#define CARD_DLL_API _declspec(dllexport) #include "CMotorDriver.h" #include #include "gts.h" #include "gtgl500.h" #include CMotorDriver::CMotorDriver() { m_motor = new std::vector(); } CMotorDriver::~CMotorDriver() { } int CMotorDriver::Relmove(int motorId, double pos, bool waitFinished) { double prfPos = 0.0; auto motorObj = std::find_if((*m_motor).begin(), (*m_motor).end(), [&](const MotorAttr &obj) { return obj.AxisId() == motorId; }); if (motorObj == (*m_motor).end()) { return 1; } pos *= motorObj->PulseTo1mm(); short sRtn = GTN_GetPrfPos(m_gugaoCardCore, motorId, &prfPos); // 读取AXIS轴的规划位置 if (sRtn) { Logger::GetInstance()->WriteLog(0, "GTN_GetPrfPos is error"); return 1; } prfPos += pos; prfPos = prfPos / motorObj->PulseTo1mm(); AbsMove(motorId, motorObj->PulseTo1mm(), pos, motorObj->Acc(), motorObj->Dec(), motorObj->Vel(),true); return 0; } int CMotorDriver::AbsmoveMulti(std::vector motorIdVec, std::vector posVec, bool waitFinished) { if (motorIdVec.size() != posVec.size()) { return 1; } if (!m_open) return 1; short sRtn; long mask = 0; for (unsigned int i = 0; i < motorIdVec.size(); i++) { unsigned short uirvMode; short sRet = GTN_GetEcatAxisMode(m_gugaoCardCore, motorIdVec[i], &uirvMode); if (!sRet && uirvMode != 8) { sRet = GTN_SetEcatAxisMode(m_gugaoCardCore, motorIdVec[i], 8); } long lAxisStatus; sRet = GTN_GetSts(m_gugaoCardCore, motorIdVec[i], &lAxisStatus); if (sRet) { Logger::GetInstance()->WriteLog(0, "AbsMotion中的GTN_GetSts失败"); return false; } if (!(lAxisStatus & (1 << 9)))//第9位为1时,电机使能 { Logger::GetInstance()->WriteLog(0, "轴未使能"); return false; } if (lAxisStatus & (1 << 10))//检查轴是否正在运动 { Logger::GetInstance()->WriteLog(0, "轴正在运动"); return false; } sRet = GTN_PrfTrap(m_gugaoCardCore, motorIdVec[i]); //切换为点位运动 if (sRet) Logger::GetInstance()->WriteLog(0, "function: Home -> GTN_SetHomingMode is error"); // 读取点位运动参数 TTrapPrm trap; sRet = GTN_GetTrapPrm(m_gugaoCardCore, motorIdVec[i], &trap); if (sRet) { Logger::GetInstance()->WriteLog(0, "SetPointMotionParam中的GTN_GetTrapPrm失败"); return false; } auto motorObj = QueryMotor(motorIdVec[i]); if (motorObj.AxisId() > -1) { double resAcc = motorObj.Acc(); double resDec = motorObj.Dec(); double velStart = motorObj.Vel(); TTrapPrm trap; trap.acc = motorObj.Acc(); trap.dec = motorObj.Dec(); trap.velStart = motorObj.Vel(); trap.smoothTime = 50; sRet = GTN_SetTrapPrm(m_gugaoCardCore, motorIdVec[i], &trap); // 设置点位运动参数 if (sRet) { Logger::GetInstance()->WriteLog(0, "GTN_SetTrapPrm is error"); return 1; } sRet = GTN_SetVel(m_gugaoCardCore, motorIdVec[i], motorObj.Vel()); if (sRet) { Logger::GetInstance()->WriteLog(0, "GTN_SetVel is error"); return 1; } } sRtn = GTN_SetPos(m_gugaoCardCore, motorIdVec[i], (long)posVec[i]); // 设置AXIS轴的目标位置 Sleep(100); if (sRtn) { Logger::GetInstance()->WriteLog(0, "function: AbsmoveMulti -> GTN_SetPos is error"); return 1; } mask |= 1 << (motorIdVec[i] - 1); } sRtn = GTN_Update(m_gugaoCardCore, mask); Sleep(100); if (sRtn) { Logger::GetInstance()->WriteLog(0, "function: AbsmoveMulti -> GTN_Update is error"); return 1; } if (waitFinished) { for (unsigned int i = 0; i < motorIdVec.size(); i++) { long lAxisSts; do { // 读取AXIS轴的状态 sRtn = GTN_GetSts(m_gugaoCardCore, motorIdVec[i], &lAxisSts); if (sRtn) { Logger::GetInstance()->WriteLog(0, "function: AbsmoveMulti -> GTN_GetSts is error"); return 1; } } while (lAxisSts & (1 << 10)); // 等待AXIS轴规划停止 } } return 0; } int CMotorDriver::RelmoveMulti(std::vector motorIdVec, std::vector posVec, bool waitFinished) { return 0; } int CMotorDriver::Home(int motorId, bool waitFinished) { if (!m_open) return 1; // 必须处于伺服使能状态, 切换到回零模式 short sRtn = GTN_SetHomingMode(m_gugaoCardCore, motorId, 6); if (sRtn) { Logger::GetInstance()->WriteLog(0, "function: Home -> GTN_SetHomingMode is error"); sRtn = GTN_SetHomingMode(m_gugaoCardCore, motorId, 8);// 切换到位置控制模式 if (sRtn) Logger::GetInstance()->WriteLog(0, "function: Home -> GTN_SetHomingMode is error"); return 1; } double searchSpeed = 0.0; double indexSpeed = 0.0; double searchAcc = 0.0; short module = 1; auto motorObj = QueryMotor(motorId); if (motorObj.AxisId() > -1) { searchSpeed = motorObj.ReturnHomeStartVel(); indexSpeed = motorObj.ReturnHomeEndVel(); searchAcc = motorObj.ReturnAcc(); for (auto & iter : (*m_motor)) { if (iter.AxisId() == motorId) { module = iter.ReturnHomeMode(); break; } } } //设置回零参数 sRtn = GTN_SetEcatHomingPrm(m_gugaoCardCore, motorId, module,//回零模式 searchSpeed, //搜索开关速度,单位: 驱动器设置的用户速度单位 indexSpeed, //搜索 index 标识速度,单位: 驱动器设置的用户速度单位 searchAcc, //搜索加速度 0, //原点偏移量 0 //探针功能 ); if (sRtn) { Logger::GetInstance()->WriteLog(0, "function: Home -> GTN_GetEcatHomingStatus is error"); return 1; } // 启动回零 sRtn = GTN_StartEcatHoming(m_gugaoCardCore, motorId); if (sRtn) { Logger::GetInstance()->WriteLog(0, "function: Home -> GTN_GetEcatHomingStatus is error"); return 1; } unsigned short sHomeSts; // 回零状态 while (true) { sRtn = GTN_GetEcatHomingStatus(m_gugaoCardCore, motorId, &sHomeSts); //读回零状态 if (sRtn) { Logger::GetInstance()->WriteLog(0, "function: Home -> GTN_GetEcatHomingStatus is error"); return 1; } if (sHomeSts == 3) { //@TODO下面这一行最开始有临界区保护 auto& motorObj = QueryMotor(motorId); if (motorObj.AxisId() >= 0) { motorObj.IsHomed(true); } double encPos; if (GTN_GetEncPos(m_gugaoCardCore, motorId, &encPos) == 0) { //回零后编码器位置 std::string str = "Encoder position after returning to zero: " + std::to_string(encPos); Logger::GetInstance()->WriteLog(0, str); } double prfPos; if (GTN_GetPrfPos(m_gugaoCardCore, motorId, &prfPos) == 0) { //回零后规划位置 std::string str = "Plan location after returning to zero: " + std::to_string(encPos); Logger::GetInstance()->WriteLog(0, str); } sRtn = GTN_ClrSts(m_gugaoCardCore, motorId); if (sRtn) Logger::GetInstance()->WriteLog(0, "function:Home, GTN_ClrSts is error"); sRtn = GTN_ZeroPos(m_gugaoCardCore, motorId);//清零规划位置和实际位置,并进行零漂补偿。 if (sRtn) Logger::GetInstance()->WriteLog(0, "function:Home, GTN_ZeroPos is error"); if (GTN_GetEncPos(m_gugaoCardCore, motorId, &encPos) == 0) { //回零后编码器位置 std::string str = "Encoder position after clear(GTN_ZeroPos): " + std::to_string(encPos); Logger::GetInstance()->WriteLog(0, str); } if (GTN_GetPrfPos(m_gugaoCardCore, motorId, &prfPos) == 0) { //回零后规划位置 std::string str = "Plan location after clear(GTN_ZeroPos): " + std::to_string(encPos); Logger::GetInstance()->WriteLog(0, str); } if (GTN_SetHomingMode(m_gugaoCardCore, motorId, 8))// 切换到位置控制模式 Logger::GetInstance()->WriteLog(0, "function: Home -> GTN_SetHomingMode is error"); return 0; } } return 0; } #if 0 int CMotorDriver::allAxisHome(std::vector allAxisId, bool waitFinished) { //std::vector vThread; //for (auto motorId : allAxisId) //{ // auto motorObj = QueryMotor(motorId); // std::thread thrWork = std::thread([this, motorObj]() // { // Home(motorObj.AxisId(), true); // }); // vThread.push_back(std::move(thrWork)); //} //for (std::thread& t : vThread) //{ // if (t.joinable()) // { // t.join(); // } //} //return 0; if (!m_open) return 1; for (auto motorId : allAxisId) { short sRtn = GTN_ClrSts(m_gugaoCardCore, motorId); if (sRtn) Logger::GetInstance()->WriteLog(0, "function:Home, GTN_ClrSts is error"); } for (auto motorId : allAxisId) { short sRtn = GTN_SetHomingMode(m_gugaoCardCore, motorId, 6); if (sRtn) { Logger::GetInstance()->WriteLog(0, "function: Home -> GTN_SetHomingMode is error"); sRtn = GTN_SetHomingMode(m_gugaoCardCore, motorId, 8); if (sRtn) Logger::GetInstance()->WriteLog(0, "function: Home -> GTN_SetHomingMode is error"); return 1; } } for (auto motorId : allAxisId) { double searchSpeed = 0.0; double indexSpeed = 0.0; double searchAcc = 0.0; short module = 1; auto motorObj = QueryMotor(motorId); if (motorObj.AxisId() > 0 && motorObj.AxisId() <= 3) { motorObj.IsHomed(false); searchSpeed = motorObj.ReturnHomeStartVel(); indexSpeed = motorObj.ReturnHomeEndVel(); searchAcc = motorObj.ReturnAcc(); if (motorId == AXIS_X || motorId == AXIS_Y) { module = 1; } else if (motorId == AXIS_Z) { module = 27; } } short sRtn = GTN_SetEcatHomingPrm(m_gugaoCardCore, motorId, module, searchSpeed, indexSpeed, searchAcc, 0, 0 ); if (sRtn) { Logger::GetInstance()->WriteLog(0, "function: Home -> GTN_GetEcatHomingStatus is error"); return 1; } } Sleep(20); for (auto motorId : allAxisId) { short sRtn = GTN_StartEcatHoming(m_gugaoCardCore, motorId); if (sRtn) { Logger::GetInstance()->WriteLog(0, "function: Home -> GTN_GetEcatHomingStatus is error"); return 1; } } int judgeFlag = 0; while (waitFinished) { for (auto motorId : allAxisId) { unsigned short sHomeSts; short sRtn = GTN_GetEcatHomingStatus(m_gugaoCardCore, motorId, &sHomeSts); if (sRtn) { Logger::GetInstance()->WriteLog(0, "function: Home -> GTN_GetEcatHomingStatus is error"); return 1; } auto& motorObj = QueryMotor(motorId); if (motorObj.AxisId() < 0) { Logger::GetInstance()->WriteLog(0, "Axis is not exist"); return 1; } if (sHomeSts == 3 && motorObj.IsHomed() == false) { judgeFlag++; motorObj.IsHomed(true); } } if (judgeFlag == allAxisId.size()) { for (auto motorId : allAxisId) { short sRtn = GTN_SetHomingMode(m_gugaoCardCore, motorId, 8); if (GTN_SetHomingMode(m_gugaoCardCore, motorId, 8)) Logger::GetInstance()->WriteLog(0, "function: Home -> GTN_SetHomingMode is error"); Sleep(10); sRtn = GTN_ClrSts(m_gugaoCardCore, motorId); } for (auto motorId : allAxisId) { short sRtn = GTN_ClrSts(m_gugaoCardCore, motorId); if (sRtn) Logger::GetInstance()->WriteLog(0, "function:Home, GTN_ClrSts is error"); sRtn = GTN_ClrSts(m_gugaoCardCore, 1, 3); sRtn = GTN_ClrSts(m_gugaoCardCore, 1, 3); sRtn = GTN_ClrSts(m_gugaoCardCore, 1, 3); long diPos = 0; double lrPrfPos = 0; sRtn = GTN_GetPos(m_gugaoCardCore, motorId, &diPos); sRtn = GTN_GetPrfPos(m_gugaoCardCore, motorId, &lrPrfPos, 1); Sleep(50); long lAxisSts = 0; sRtn = GTN_GetSts(m_gugaoCardCore, motorId, &lAxisSts); if (sRtn) { Logger::GetInstance()->WriteLog(0, "GTN_GetSts is error"); return 1; } } return 0; } Sleep(20); } return 1; } #else int CMotorDriver::allAxisHome(std::vector allAxisId, bool waitFinished) { if (!m_open) return 1; short sRtn = 0; //short motorId = 1; //清除所有告警 for (auto motorId : allAxisId) { short sRtn = GTN_ClrSts(m_gugaoCardCore, motorId); if (sRtn) Logger::GetInstance()->WriteLog(0, "function:Home, GTN_ClrSts is error"); } // 必须处于伺服使能状态, 切换到回零模式 for (auto motorId : allAxisId) { short sRtn = GTN_SetHomingMode(m_gugaoCardCore, motorId, 6); if (sRtn) { Logger::GetInstance()->WriteLog(0, "function: Home -> GTN_SetHomingMode is error"); sRtn = GTN_SetHomingMode(m_gugaoCardCore, motorId, 8);// 切换到位置控制模式 if (sRtn) Logger::GetInstance()->WriteLog(0, "function: Home -> GTN_SetHomingMode is error"); return 1; } } //设置回零参数 for (auto motorId : allAxisId) { double searchSpeed = 0.0; double indexSpeed = 0.0; double searchAcc = 0.0; short module = 1; auto motorObj = QueryMotor(motorId); if (motorObj.AxisId() > 0 && motorObj.AxisId() <= 5) { searchSpeed = motorObj.ReturnHomeStartVel(); indexSpeed = motorObj.ReturnHomeEndVel(); searchAcc = motorObj.ReturnAcc(); for (auto & iter : (*m_motor)) { if (iter.AxisId() == motorId) { module = iter.ReturnHomeMode(); break; } } } //设置回零参数 sRtn = GTN_SetEcatHomingPrm(m_gugaoCardCore, motorObj.AxisId(), module,//回零模式 searchSpeed, //搜索开关速度,单位: 驱动器设置的用户速度单位 indexSpeed, //搜索 index 标识速度,单位: 驱动器设置的用户速度单位 searchAcc, //搜索加速度 0, //原点偏移量 0 //探针功能 ); if (sRtn) { Logger::GetInstance()->WriteLog(0, "function: Home -> GTN_GetEcatHomingStatus is error"); return 1; } } //double searchSpeed = 10000; //double indexSpeed = 5000; //double searchAcc = 2000; //short module = 1; ////设置回零参数 //sRtn = GTN_SetEcatHomingPrm(m_gugaoCardCore, 1, // module,//回零模式 // searchSpeed, //搜索开关速度,单位: 驱动器设置的用户速度单位 // indexSpeed, //搜索 index 标识速度,单位: 驱动器设置的用户速度单位 // searchAcc, //搜索加速度 // 0, //原点偏移量 // 0 //探针功能 //); //if (sRtn) //{ // Logger::GetInstance()->WriteLog(0, "function: Home -> GTN_GetEcatHomingStatus is error"); // return 1; //} ////设置回零参数 //sRtn = GTN_SetEcatHomingPrm(m_gugaoCardCore, 2, // module,//回零模式 // searchSpeed, //搜索开关速度,单位: 驱动器设置的用户速度单位 // indexSpeed, //搜索 index 标识速度,单位: 驱动器设置的用户速度单位 // searchAcc, //搜索加速度 // 0, //原点偏移量 // 0 //探针功能 //); //if (sRtn) //{ // Logger::GetInstance()->WriteLog(0, "function: Home -> GTN_GetEcatHomingStatus is error"); // return 1; //} ////设置回零参数 //sRtn = GTN_SetEcatHomingPrm(m_gugaoCardCore, 3, // 27,//回零模式 // 5000, //搜索开关速度,单位: 驱动器设置的用户速度单位 // 2000, //搜索 index 标识速度,单位: 驱动器设置的用户速度单位 // 1000, //搜索加速度 // 0, //原点偏移量 // 0 //探针功能 //); //if (sRtn) //{ // Logger::GetInstance()->WriteLog(0, "function: Home -> GTN_GetEcatHomingStatus is error"); // return 1; //} //下回零指令 // 启动回零 Sleep(20); for (auto motorId : allAxisId) { sRtn = GTN_StartEcatHoming(m_gugaoCardCore, motorId); if (sRtn) { Logger::GetInstance()->WriteLog(0, "function: Home -> GTN_GetEcatHomingStatus is error"); return 1; } } //判断等待回原 int judgeFlag = 0; unsigned short* sHomeSts = new unsigned short[allAxisId.size()]; // 回零状态 while (waitFinished) { if (judgeFlag == 0) { for (auto motorId : allAxisId) { short sRtn = GTN_GetEcatHomingStatus(m_gugaoCardCore, motorId, &sHomeSts[motorId - 1]); //读回零状态 if (sRtn) { Logger::GetInstance()->WriteLog(0, "function: Home -> GTN_GetEcatHomingStatus is error"); return 1; } } bool allEnd = true; for (size_t i = 0; i < allAxisId.size(); i++) { if (sHomeSts[i] != 3) { allEnd = false; } } if (allEnd/*sHomeSts[0] == 3 && sHomeSts[1] == 3 && sHomeSts[2] == 3*/) { for (short motorId = 1; motorId <= 3; motorId++) { sRtn = GTN_SetHomingMode(m_gugaoCardCore, motorId, 8); if (GTN_SetHomingMode(m_gugaoCardCore, motorId, 8))// 切换到位置控制模式 Logger::GetInstance()->WriteLog(0, "function: Home -> GTN_SetHomingMode is error"); Sleep(10); sRtn = GTN_ClrSts(m_gugaoCardCore, motorId); judgeFlag = 1; } } } //判断所有轴是否回原 if (judgeFlag == 1) { //清除所有告警 for (auto motorId : allAxisId) { short sRtn = GTN_ClrSts(m_gugaoCardCore, motorId); if (sRtn) Logger::GetInstance()->WriteLog(0, "function:Home, GTN_ClrSts is error"); // 读取AXIS轴的状态 sRtn = GTN_ClrSts(m_gugaoCardCore, 1, 3); sRtn = GTN_ClrSts(m_gugaoCardCore, 1, 3); sRtn = GTN_ClrSts(m_gugaoCardCore, 1, 3); long diPos = 0; double lrPrfPos = 0; sRtn = GTN_GetPos(m_gugaoCardCore, motorId, &diPos); sRtn = GTN_GetPrfPos(m_gugaoCardCore, motorId, &lrPrfPos, 1); Sleep(50); long lAxisSts = 0; sRtn = GTN_GetSts(m_gugaoCardCore, motorId, &lAxisSts); if (sRtn) { Logger::GetInstance()->WriteLog(0, "GTN_GetSts is error"); return 1; } if (lAxisSts & (1 << 1)) { Logger::GetInstance()->WriteLog(0, "Driver alarm flag"); } else if (lAxisSts & (1 << 4)) { Logger::GetInstance()->WriteLog(0, "跟随误差越限标志"); } else if (lAxisSts & (1 << 5)) { Logger::GetInstance()->WriteLog(0, "正限位触发标志"); } else if (lAxisSts & (1 << 6)) { Logger::GetInstance()->WriteLog(0, "负限位触发标志"); } else if (lAxisSts & (1 << 7)) { Logger::GetInstance()->WriteLog(0, "IO平滑停止触发标志"); } else if (lAxisSts & (1 << 8)) { Logger::GetInstance()->WriteLog(0, "IO急停触发标志"); } else if (lAxisSts & (1 << 9)) { Logger::GetInstance()->WriteLog(0, "电机使能标志"); } } return 0; } Sleep(2); } return 1; } #endif void CMotorDriver::ResetAxisErr(std::vector axisId) { for (auto& iter : axisId) { short sRtn = GTN_ClrSts(m_gugaoCardCore, iter); //清除驱动器报警标志、跟随误差越限标志、限位触发标志。 if (sRtn) { Logger::GetInstance()->WriteLog(0, "GTN_ClrSts is error"); return; } } } int CMotorDriver::AddMotor(const MotorAttr & motor) { m_motor->push_back(motor); return 0; } int CMotorDriver::DeleteMotor(int motorId) { return 0; } int CMotorDriver::ModifyMotor(const MotorAttr & motor) { return 0; } MotorAttr CMotorDriver::QueryMotor(int motorId) { for (auto& iter : (*m_motor)) { if (iter.AxisId() == motorId) { return iter; } } MotorAttr obj; obj.AxisId(-1); return obj; } void CMotorDriver::ClearAllAxis() { m_motor->clear(); } double CMotorDriver::GetCurPos(int motorId) { if (!m_open) { Logger::GetInstance()->WriteLog(0, "function:GetCurPos, device is not open"); return 0; } double pos; // 读取AXIS轴的规划位置 short sRtn = GTN_GetPrfPos(m_gugaoCardCore, motorId, &pos); if (sRtn) { Logger::GetInstance()->WriteLog(0, "function:GetCurPos, GTN_GetPrfPos is error"); return 0; } for (auto & iter : (*m_motor)) { if (iter.AxisId() == motorId && iter.PulseTo1mm() > 0) { pos /= iter.PulseTo1mm(); break; } } return pos; }