You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

640 lines
15 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "CGugaoDriver.h"
#include <windows.h>
#include "gts.h"
#include "gtgl500.h"
#include <thread>
CGugaoDriver::CGugaoDriver()
{
}
CGugaoDriver::~CGugaoDriver()
{
}
bool CGugaoDriver::OpenCard(std::vector<int>& axisIdVec)
{
short status = -1;
short sRtn = -1;
sRtn = GTN_Open(CHANNEL_PCIE, 1); // 打开运动控制器第一个参数打开运动控制器方式第二个参数默认1暂无意义
if (sRtn)
{
Logger::GetInstance()->WriteLog(0, "GTN_Open is error");
return false;
}
sRtn = GTN_Reset(CORE_NUM); //复位核1,参数:内核编号
if (sRtn)
{
Logger::GetInstance()->WriteLog(0, "GTN_Reset is error");
return false;
}
//初始化总线
sRtn = GTN_TerminateEcatComm(CORE_NUM); //结束EtherCAT通讯。
if (sRtn)
{
Logger::GetInstance()->WriteLog(0, "GTN_TerminateEcatComm is error");
return false;
}
sRtn = GTN_InitEcatComm(CORE_NUM); //EtherCAT初始化。
if (sRtn)
{
Logger::GetInstance()->WriteLog(0, "GTN_InitEcatComm is error");
return false;
}
short sCnt = 0;
do
{
sRtn = GTN_IsEcatReady(1, &status); //查询EtherCAT通讯状态。 0通讯未完全建立1通讯完全建立。
Sleep(500);
sCnt++;
} while ((status != 1 || sRtn != 0) && (sCnt < 20)); //通讯在0.5s*20仍未准备好
sRtn = GTN_StartEcatComm(CORE_NUM); //启动EtherCAT通讯。成功调用这条指令后才可以调用其他运动指令。
if (sRtn)
{
Logger::GetInstance()->WriteLog(0, "GTN_StartEcatComm is error");
return false;
}
// 配置运动控制器
char szFilePath[MAX_PATH + 1] = { 0 };
GetModuleFileNameA(NULL, szFilePath, MAX_PATH);
(strrchr(szFilePath, '\\'))[1] = 0; //删除文件名,只获得路径
sprintf(szFilePath, "%sgtn_core1.cfg", szFilePath);
//下载配置信息到运动控制器,调用该指令后需再调用GTN_ClrSts才能使该指令生
sRtn = GTN_LoadConfig(CORE_NUM, szFilePath); //第一个参数:内核,第二个参数:文件路径
if (sRtn)
{
Logger::GetInstance()->WriteLog(0, "GTN_LoadConfig error");
return false;
}
for (auto& iter : axisIdVec)
{
//第一个参数内核编号第二个参数轴编号第三个参数默认为1暂无实际意义
sRtn = GTN_ClrSts(CORE_NUM, iter, 10); //清除驱动器报警标志、跟随误差越限标志、限位触发标志。
if (sRtn)
{
Logger::GetInstance()->WriteLog(0, "GTN_ClrSts is error");
return false;
}
}
for (auto& iter : axisIdVec)
{
//第一个参数内核编号第二个参数轴编号第三个参数默认为1
sRtn = GTN_ZeroPos(CORE_NUM, iter, 1); //清零规划位置和实际位置,并进行零漂补偿。
}
//驱动器使能
for (auto& iter : axisIdVec)
{
sRtn = GTN_AxisOn(CORE_NUM, iter); //打开驱动器使能, 第一个参数:内核编号,第二个参数:轴编号
if (sRtn)
{
Logger::GetInstance()->WriteLog(0, "GTN_AxisOn is error");
return false;
}
Sleep(50);
}
sRtn = GT_GLinkInit(0); //扩展模块初始化,第一个参数目前默认为0
if (sRtn)
{
Logger::GetInstance()->WriteLog(0, "GT_GLinkInit is error");
return false;
}
m_open = true;
return true;
}
bool CGugaoDriver::CloseCard(std::vector<int>& axisIdVec)
{
//驱动器使能
short sRet;
for (auto& iter : axisIdVec)
{
sRet = GTN_AxisOff(CORE_NUM, iter); //关闭驱动器使能。第一个参数:内核,第二个参数:轴号
if (sRet)
{
Logger::GetInstance()->WriteLog(0, "GTN_AxisOff is error");
return false;
}
Sleep(50);
}
sRet = GTN_Close(); //关闭运动控制器
if (sRet)
{
Logger::GetInstance()->WriteLog(0, "GTN_Close is error");
return false;
}
m_open = false;
return true;
}
int CGugaoDriver::AbsMove(int iAxisId,
int pulseTo1mm,
double dPos,
double dAcc,
double dDec,
double dMoveSpeed,
bool bWaitFinished)
{
if (!m_open)
return 1;
//执行安全回调
if (m_onAxisMoveSafeFunc != nullptr)
{
if (!m_onAxisMoveSafeFunc(iAxisId, dPos))
{
return 1;
}
}
//换算成脉冲
double targetPulse = pulseTo1mm * dPos;
unsigned short uirvMode;
//读取 EtheCAT 轴的操作模式,第一个参数:内核,第二个参数轴号,第三个参数私服操作模式
short sRet = GTN_GetEcatAxisMode(CORE_NUM, iAxisId, &uirvMode);
if (!sRet && uirvMode != CYCLIC_SYNC_POSITION)
{
//设置轴的操作模式
sRet = GTN_SetEcatAxisMode(CORE_NUM, iAxisId, CYCLIC_SYNC_POSITION);
}
long lAxisStatus;
sRet = GTN_GetSts(CORE_NUM, iAxisId, &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(CORE_NUM, iAxisId); //切换为点位运动
if (sRet)
Logger::GetInstance()->WriteLog(0, "function: Home -> GTN_SetHomingMode is error");
// 读取点位运动参数
TTrapPrm trap;
sRet = GTN_GetTrapPrm(CORE_NUM, iAxisId, &trap);
if (sRet)
{
Logger::GetInstance()->WriteLog(0, "SetPointMotionParam中的GTN_GetTrapPrm失败");
return false;
}
trap.acc = dAcc;
trap.dec = dDec;
trap.velStart = dMoveSpeed;
trap.smoothTime = 50;
sRet = GTN_SetTrapPrm(CORE_NUM, iAxisId, &trap); // 设置点位运动参数
if (sRet)
{
Logger::GetInstance()->WriteLog(0, "GTN_SetTrapPrm is error");
return 1;
}
sRet = GTN_SetVel(CORE_NUM, iAxisId, dMoveSpeed); //设置目标速度
if (sRet)
{
Logger::GetInstance()->WriteLog(0, "GTN_SetVel is error");
return 1;
}
// 设置AXIS轴的目标位置
sRet = GTN_SetPos(CORE_NUM, (short)iAxisId, (long)targetPulse);
Sleep(100);
if (sRet)
{
Logger::GetInstance()->WriteLog(0, "GTN_SetPos is error");
return 1;
}
// 启动AXIS轴的运动当 bit 位为 1 时表示启动对应的轴。
short sRtn = GTN_Update(CORE_NUM, 1 << (iAxisId - 1));
Sleep(100);
if (sRtn)
{
Logger::GetInstance()->WriteLog(0, "GTN_Update is error");
return 1;
}
if (bWaitFinished)
{
long lAxisSts = 0;
while (true)
{
// 读取AXIS轴的状态
sRtn = GTN_GetSts(CORE_NUM, iAxisId, &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, "电机使能标志");
}
if (lAxisSts & (1 << 10))
{
continue;
}
else
{
double prefPos;
// 读取AXIS轴的规划位置
short sRtn = GTN_GetPrfPos(CORE_NUM, iAxisId, &prefPos);
if (sRtn)
{
Logger::GetInstance()->WriteLog(0, "function:GetCurPos, GTN_GetPrfPos is error");
return 1;
}
long pulsePos = (long)prefPos;
if (pulsePos == (long)targetPulse) {
return 0;
}
else
{
Logger::GetInstance()->WriteLog(0, "GetPos != setPos");
continue;
}
}
}
Sleep(25);
}
return 0;
}
int CGugaoDriver::WriteIO(short sSlaveNo, short sIoIndex, unsigned char ucValue)
{
if (m_onSetIoSafeFunc != nullptr)
{
if (!m_onSetIoSafeFunc(sIoIndex, ucValue)) {
return 1;
}
}
//设置数字量输出sSlaveNo模块号sIoIndexIO号ucValue数值
short rtn = GT_SetGLinkDoBit(sSlaveNo, sIoIndex, ucValue);
if (rtn != 0) {
Logger::GetInstance()->WriteLog(0, "function:writeIO, GT_SetGLinkDoBit is error");
return 1;
}
return 0;
}
int CGugaoDriver::WriteAO(short sSlaveNo, short sIoIndex, short sValue)
{
//设置模拟量sSlaveNo模块号sIoIndexIO号ucValue数值
short rtn = GT_SetGLinkAo(sSlaveNo, sIoIndex, &sValue, 1);
if (rtn != 0) {
Logger::GetInstance()->WriteLog(0, "function:writeAO, GT_SetGLinkAo is error");
return 1;
}
return 0;
}
short CGugaoDriver::ReadDo(short sSlaveNo, short sIoIndex)
{
//读取模拟量输出数值, sSlaveNo模块号sIoIndexIO号
short outval = 0;
short rtn = GT_GetGLinkAo(sSlaveNo, sIoIndex, &outval, 1);
if (rtn != 0) {
Logger::GetInstance()->WriteLog(0, "function:ReadDo, GT_GetGLinkAo is error");
return outval;
}
return outval;
}
unsigned char CGugaoDriver::ReadDi(short sSlaveNo, short sIoIndex)
{
unsigned char bit = 0;
short sRet = GT_GetGLinkDiBit(sSlaveNo, sIoIndex, &bit);
if (sRet != 0) {
Logger::GetInstance()->WriteLog(0, "function:ReadIO, GT_GetGLinkDiBit is error");
return bit;
}
return bit;
}
double CGugaoDriver::GetCurPos(int iAxisId, int pulseTo1mm)
{
if (!m_open)
{
Logger::GetInstance()->WriteLog(0, "function:GetCurPos, device is not open");
return 0;
}
double pos;
// 读取AXIS轴的规划位置
short sRtn = GTN_GetPrfPos(CORE_NUM, iAxisId, &pos);
if (sRtn)
{
Logger::GetInstance()->WriteLog(0, "function:GetCurPos, GTN_GetPrfPos is error");
return 0;
}
if (pulseTo1mm > 0)
{
pos /= (double)pulseTo1mm;
}
return pos;
}
void CGugaoDriver::stopMove(int iAxisId)
{
}
int CGugaoDriver::home(int iAxisId, double dSearchSpeed, double iIndexSpeed, double sSearchAcc, short sModule)
{
if (!m_open)
return 1;
if (m_onAxisPrevHomeFunc != nullptr)
{
if (!m_onAxisPrevHomeFunc(iAxisId)) {
return 1;
}
}
// 必须处于伺服使能状态, 切换到回零模式数字6代表回零模式
short sRtn = GTN_SetHomingMode(CORE_NUM, iAxisId, 6);
if (sRtn)
{
Logger::GetInstance()->WriteLog(0, "function: Home -> GTN_SetHomingMode is error");
sRtn = GTN_SetHomingMode(CORE_NUM, iAxisId, 8);// 切换到位置控制模式
if (sRtn)
Logger::GetInstance()->WriteLog(0, "function: Home -> GTN_SetHomingMode is error");
return 1;
}
//设置回零参数
sRtn = GTN_SetEcatHomingPrm(CORE_NUM, iAxisId,
sModule,//回零模式
dSearchSpeed, //搜索开关速度,单位: 驱动器设置的用户速度单位
iIndexSpeed, //搜索 index 标识速度,单位: 驱动器设置的用户速度单位
sSearchAcc, //搜索加速度
0, //原点偏移量
0 //探针功能
);
if (sRtn)
{
Logger::GetInstance()->WriteLog(0, "function: Home -> GTN_GetEcatHomingStatus is error");
return 1;
}
// 启动回零
sRtn = GTN_StartEcatHoming(CORE_NUM, iAxisId);
if (sRtn)
{
Logger::GetInstance()->WriteLog(0, "function: Home -> GTN_GetEcatHomingStatus is error");
return 1;
}
unsigned short sHomeSts; // 回零状态
while (true)
{
sRtn = GTN_GetEcatHomingStatus(CORE_NUM, iAxisId, &sHomeSts); //读回零状态
if (sRtn)
{
Logger::GetInstance()->WriteLog(0, "function: Home -> GTN_GetEcatHomingStatus is error");
return 1;
}
if (sHomeSts == 3) //3代表回零完成和回零成功完成
{
double encPos;
if (GTN_GetEncPos(CORE_NUM, iAxisId, &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(CORE_NUM, iAxisId, &prfPos) == 0) {
//回零后规划位置
std::string str = "Plan location after returning to zero: " + std::to_string(encPos);
Logger::GetInstance()->WriteLog(0, str);
}
sRtn = GTN_ClrSts(CORE_NUM, iAxisId);
if (sRtn)
Logger::GetInstance()->WriteLog(0, "function:Home, GTN_ClrSts is error");
sRtn = GTN_ZeroPos(CORE_NUM, iAxisId);//清零规划位置和实际位置,并进行零漂补偿。
if (sRtn)
Logger::GetInstance()->WriteLog(0, "function:Home, GTN_ZeroPos is error");
if (GTN_GetEncPos(CORE_NUM, iAxisId, &encPos) == 0) {
//回零后编码器位置
std::string str = "Encoder position after clear(GTN_ZeroPos): " + std::to_string(encPos);
Logger::GetInstance()->WriteLog(0, str);
}
if (GTN_GetPrfPos(CORE_NUM, iAxisId, &prfPos) == 0) {
//回零后规划位置
std::string str = "Plan location after clear(GTN_ZeroPos): " + std::to_string(encPos);
Logger::GetInstance()->WriteLog(0, str);
}
if (GTN_SetHomingMode(CORE_NUM, iAxisId, 8))// 切换到位置控制模式,8代表位置控制模式
Logger::GetInstance()->WriteLog(0, "function: Home -> GTN_SetHomingMode is error");
break;
}
Sleep(200);
}
if (m_AxisAfterHomeFunc != nullptr)
{
if (!m_AxisAfterHomeFunc(iAxisId))
{
return 1;
}
}
return 0;
}
bool CGugaoDriver::IsHome(int iAxisId)
{
if (!m_open)
{
return false;
}
unsigned short sHomeSts; // 回零状态
short sRtn = GTN_GetEcatHomingStatus(CORE_NUM, iAxisId, &sHomeSts); //读回零状态
if (sHomeSts == 3) //3代表回零完成和回零成功完成
{
return true;
}
return false;
}
bool CGugaoDriver::IsHoming(int iAxisId)
{
if (!m_open)
{
return false;
}
unsigned short sHomeSts; // 回零状态
short sRtn = GTN_GetEcatHomingStatus(CORE_NUM, iAxisId, &sHomeSts); //读回零状态
if (sHomeSts == 0) //0代表正在回零
{
return true;
}
return false;
}
bool CGugaoDriver::IsMoveing(int iAxisId)
{
if (!m_open)
{
return false;
}
long lAxisStatus = 0;
// 读取AXIS轴的状态
short sRtn = GTN_GetSts(CORE_NUM, iAxisId, &lAxisStatus);
if (lAxisStatus & 0x400) //0x400正好在运动标志位
{
return true;
}
return false;
}
bool CGugaoDriver::IsMoveEnd(int iAxisId)
{
if (!m_open)
{
return false;
}
long lAxisStatus = 0;
// 读取AXIS轴的状态
short sRtn = GTN_GetSts(CORE_NUM, iAxisId, &lAxisStatus);
if (!(lAxisStatus & 0x400))//0x400正好在运动标志位,反向
{
return true;
}
return false;
}
bool CGugaoDriver::IsAxisEnable(int iAxisId)
{
if (!m_open)
{
return false;
}
long lAxisStatus = 0;
// 读取AXIS轴的状态
short sRtn = GTN_GetSts(CORE_NUM, iAxisId, &lAxisStatus);
if (lAxisStatus & 0x200)//0x200私服使能
{
return true;
}
return false;
}
bool CGugaoDriver::IsAxisError(int iAxisId)
{
if (!m_open)
{
return false;
}
long lAxisStatus = 0;
// 读取AXIS轴的状态
short sRtn = GTN_GetSts(CORE_NUM, iAxisId, &lAxisStatus);
if (lAxisStatus & 0x2) // 0x2私服报警标志
{
return true;
}
else
{
return false;
}
}
bool CGugaoDriver::GetAxisErrorCode(int iAxisId)
{
return false;
}
bool CGugaoDriver::IsAxisPaslimit(int iAxisId)
{
if (!m_open)
{
return false;
}
long lAxisStatus = 0;
// 读取AXIS轴的状态
short sRtn = GTN_GetSts(CORE_NUM, iAxisId, &lAxisStatus);
// 正向限位触发
if (lAxisStatus & 0x20)
{
return true;
}
return false;
}
bool CGugaoDriver::isAxisNagLimit(int iAxisId)
{
long lAxisStatus = 0;
// 读取AXIS轴的状态
short sRtn = GTN_GetSts(CORE_NUM, iAxisId, &lAxisStatus);
if (lAxisStatus & 0x40)
{
return true;
}
return false;
}