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.

977 lines
25 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 "Card.h"
#include "axis.h"
#include "gts.h"
#include "motor.h"
#include "log.h"
#include "config.h"
#define SAME_PULSE_OFFSET 10
#define AHEAD_BUFF 100 //前瞻缓冲区
CCard::CCard(ushort cardIndex)
{
_bOpened = false;
_cardIndex = cardIndex;
for(ushort i = 0; i < MAXAXIS; i++)
{
_pAxis[i] = new CAxis(cardIndex, i);
}
memset(_crd, 0, sizeof(_crd));
for(ushort i = 0; i < MAXCRD; i++)
{
_crd[i].crd = i + 1; //crd 只能是1和2
_crd[i].pCrdData = new CrdData[AHEAD_BUFF];
memset(_crd[i].pCrdData, 0, sizeof(CrdData) * AHEAD_BUFF);
}
}
CCard::~CCard()
{
for (ushort i = 0; i < MAXAXIS; i++)
{
delete _pAxis[i];
}
}
int CCard::Open()
{
int ret = 0;
char buff[64] = {0};
RETURN_CHK_NOPRT(!_bOpened, 0);
/*_bOpened = true;
return 0;*/
ret = GT_Open(_cardIndex);
if (ret)
{
LOG_ERR("GT_Open return error:%d", ret);
return ret;
}
cstr p = get_sys_cfg("control", "path");
if (!p) p = "data";
sprintf(buff, "%s\\card_%d.cfg", p, _cardIndex);
ret = GT_LoadConfig(_cardIndex, buff);
if (ret)
{
LOG_ERR("GT_LoadConfig return error:%d", ret);
GT_Close(_cardIndex);
return ret;
}
for (ushort i = 0; i < MAXAXIS; i++)
{
ret = _pAxis[i]->Init();
if (ret)
{//fail
CloseAllAxis();
GT_Close(_cardIndex);
return ret;
}
}
ret = GT_HomeInit(_cardIndex);
if (ret)
{
LOG_ERR("GT_HomeInit return error:%d", ret);
CloseAllAxis();
GT_Close(_cardIndex);
return ret;
}
_bOpened = true;
return RETURN_OK;
}
int CCard::Close()
{
RETURN_CHK_NOPRT(_bOpened, 0);
CloseAllAxis();
GT_Close(_cardIndex);
_bOpened = false;
return 0;
}
int CCard::Reset()
{//重置
Close();
return Open();
}
void CCard::CloseAllAxis()
{
for(ushort i = 0; i < MAXAXIS; i++)
{
_pAxis[i]->Off();
}
}
int CCard::AxisReset(ushort axisIndex)
{
RETURN_CHK_NOPRT(_bOpened, ERR_NO_INIT);
RETURN_CHK_NOPRT(axisIndex < MAXAXIS, ERR_INPUT_PARAM);
return _pAxis[axisIndex]->Reset();
}
int CCard::AxisZeroPos(ushort axisIndex)
{
RETURN_CHK_NOPRT(_bOpened, ERR_NO_INIT);
RETURN_CHK_NOPRT(axisIndex < MAXAXIS, ERR_INPUT_PARAM);
return _pAxis[axisIndex]->SetZeroPos();
}
int CCard::AxisIsMoving(ushort axisIndex)
{
RETURN_CHK_NOPRT(_bOpened, 0);
RETURN_CHK_NOPRT(axisIndex < MAXAXIS, 0);
return _pAxis[axisIndex]->IsMoving();
}
int CCard::AxisStop(ushort axisIndex, int stopType)
{
RETURN_CHK_NOPRT(_bOpened, ERR_NO_INIT);
RETURN_CHK_NOPRT(axisIndex < MAXAXIS, ERR_INPUT_PARAM);
return _pAxis[axisIndex]->Stop(stopType);
}
int CCard::AxisSetSpeed(ushort axisIndex, double vel)
{
RETURN_CHK_NOPRT(_bOpened, ERR_NO_INIT);
RETURN_CHK_NOPRT(axisIndex < MAXAXIS, ERR_INPUT_PARAM);
return _pAxis[axisIndex]->SetSpeed(vel, TRUE);
}
int CCard::AxisSetPos(ushort axisIndex, long pos)
{
RETURN_CHK_NOPRT(_bOpened, ERR_NO_INIT);
RETURN_CHK_NOPRT(axisIndex < MAXAXIS, ERR_INPUT_PARAM);
return _pAxis[axisIndex]->SetPos(pos);
}
int CCard::AxisGetPos(ushort axisIndex, EMPosType postype, double* pval)
{
RETURN_CHK_NOPRT(_bOpened, ERR_NO_INIT);
RETURN_CHK_NOPRT(pval && axisIndex < MAXAXIS, ERR_INPUT_PARAM);
*pval = _pAxis[axisIndex]->GetCurPos(postype);
return 0;
}
int CCard::AxisMoveJog(ushort axisIndex, int dir, double vel, double acc, double dec)
{
RETURN_CHK_NOPRT(_bOpened, ERR_NO_INIT);
RETURN_CHK_NOPRT(axisIndex < MAXAXIS, ERR_INPUT_PARAM);
return _pAxis[axisIndex]->MoveJog(dir, vel, acc, dec);
}
int CCard::AxisMovePos(ushort axisIndex, long pos, double vel, double acc, double dec)
{
RETURN_CHK_NOPRT(_bOpened, ERR_NO_INIT);
RETURN_CHK_NOPRT(axisIndex < MAXAXIS, ERR_INPUT_PARAM);
return _pAxis[axisIndex]->MovePos(pos, vel, acc, dec);
}
int CCard::AxisHome(ushort axisIndex, ushort homeType, long pos, long offset, double vel)
{
RETURN_CHK_NOPRT(_bOpened, ERR_NO_INIT);
RETURN_CHK_NOPRT(axisIndex < MAXAXIS, ERR_INPUT_PARAM);
return _pAxis[axisIndex]->Home(homeType, pos, offset, vel);
}
int CCard::AxisMoveOffset(ushort axisIndex, long offset, double vel, double acc, double dec)
{
RETURN_CHK_NOPRT(_bOpened, ERR_NO_INIT);
RETURN_CHK_NOPRT(axisIndex < MAXAXIS, ERR_INPUT_PARAM);
return _pAxis[axisIndex]->MoveOffset(offset, vel, acc, dec);
}
int CCard::ComparePos(ushort axisCnt, short time, long *pBuf1, short count1, long *pBuf2, short count2)
{
RETURN_CHK_NOPRT(_bOpened, ERR_NO_INIT);
short ret = GT_CompareData(_cardIndex, axisCnt, 1, 0, 0, time, pBuf1, 1, NULL, 0); //脉冲输出
if(ret)
{
LOG_ERR("GT_CompareData return error:%d", ret);
}
return ret;
}
int CCard::CreateCrd(ushort *pAxisIndex, ushort nsize, int& crd)
{
int ret = 0;
RETURN_CHK_NOPRT(_bOpened, ERR_NO_INIT);
RETURN_CHK_NOPRT(pAxisIndex && nsize < MAXAXIS, ERR_INPUT_PARAM);
crd = GetExistCrd(); //获取空闲坐标系
RETURN_CHK_NOPRT(crd >= 0, ERR_SET_CRD);
_crd[crd].axisCnt = nsize;
for(ushort i = 0; i < nsize; i++)
{//赋值轴
_crd[crd].axisIndex[i] = pAxisIndex[i];
}
RETURN_CHK_NOPRT(!SetCrd(_crd[crd]), ERR_SET_CRD);
_crd[crd].buse = true; //标识使用中
return 0;
}
int CCard::CloseCrd(int index)
{
int ret = 0;
RETURN_CHK_NOPRT(_bOpened, ERR_NO_INIT);
RETURN_CHK_NOPRT(index >= 0 && index < MAXCRD, 0);
RETURN_CHK_NOPRT(_crd[index].buse, 0);
ret = GT_CrdClear(_cardIndex, _crd[index].crd, 0);
if (ret)
{
LOG_ERR("GT_CrdClear return %d.", ret);
}
_crd[index].buse = false; //标识不在使用中
return ret;
}
int CCard::AddLinePos(int index, double *ppos, double vel, double acc, double endvel)
{
int ret = ERR_INPUT_PARAM;
RETURN_CHK_NOPRT(_bOpened, ERR_NO_INIT);
RETURN_CHK_NOPRT(ppos, ERR_INPUT_PARAM);
RETURN_CHK_NOPRT(index >= 0 && index < MAXCRD, ERR_INPUT_PARAM);
RETURN_CHK_NOPRT(_crd[index].buse, ERR_NO_INIT);
switch (_crd[index].axisCnt)
{
case 2:
ret = GT_LnXY(_cardIndex, _crd[index].crd, double_to_int(ppos[0]),
double_to_int(ppos[1]), vel, acc, endvel);
break;
case 3:
ret = GT_LnXYZ(_cardIndex, _crd[index].crd, double_to_int(ppos[0]),
double_to_int(ppos[1]), double_to_int(ppos[2]), vel, acc, endvel);
break;
case 4:
ret = GT_LnXYZA(_cardIndex, _crd[index].crd, double_to_int(ppos[0]),
double_to_int(ppos[1]), double_to_int(ppos[2]), double_to_int(ppos[3]), vel, acc, endvel);
break;
default:
break;
}
if (ret)
{
LOG_ERR("AddArcPos return %d", ret);
}
return ret;
}
int CCard::AddArcPos(int index, double *ppos1, double *ppos2, double *ppos3, double vel, double acc, double endvel)
{
int rtn = 0;
long realPos1[4];
long realPos2[4];
long realPos3[4];
int arcType = 0;
short arcDir = 0; //默认圆弧运动方向 0 顺时针 1逆时针
double x, y, r;
RETURN_CHK_NOPRT(_bOpened, ERR_NO_INIT);
RETURN_CHK_NOPRT(ppos1 && ppos2 && ppos3, ERR_INPUT_PARAM);
RETURN_CHK_NOPRT(index >= 0 && index < MAXCRD, ERR_INPUT_PARAM);
RETURN_CHK_NOPRT(_crd[index].buse, ERR_NO_INIT);
for(int i = 0; i < _crd[index].axisCnt; i++)
{
realPos1[i] = double_to_int(ppos1[i]);
realPos2[i] = double_to_int(ppos2[i]);
realPos3[i] = double_to_int(ppos3[i]);
}
//计算圆弧运动类型,并按类型处理位置数据
rtn = CalcArcType(realPos1, realPos2, realPos3, _crd[index].axisCnt, arcType);
RETURN_CHK_NOPRT(!rtn, rtn);
if (!IsSamePos(realPos1, realPos3, _crd[index].axisCnt))
{//不是整圆,不能在一条线
RETURN_CHK_NOPRT(!IsSameLine(realPos1, realPos2, realPos3), ERR_INPUT_PARAM);
//计算圆弧运动方向 0 顺时针 1逆时针
arcDir = CalcDir(realPos1, realPos2, realPos3) ? 0 : 1;
}
//计算圆心坐标
CalcCenter(realPos1, realPos2, realPos3, x, y, r);
switch (arcType)
{
case EM_ARC_XY:
rtn = GT_ArcXYC(_cardIndex, _crd[index].crd, realPos3[0], realPos3[1],
x-realPos3[0], y-realPos3[1], arcDir, vel, acc, endvel);
break;
case EM_ARC_YZ:
rtn = GT_ArcYZC(_cardIndex, _crd[index].crd, realPos3[0], realPos3[1],
x-realPos3[0], y-realPos3[1], arcDir, vel, acc, endvel);
break;
case EM_ARC_ZX:
rtn = GT_ArcZXC(_cardIndex, _crd[index].crd, realPos3[0], realPos3[1],
x-realPos3[0], y-realPos3[1], arcDir, vel, acc, endvel);
break;
default:
rtn = ERR_INPUT_PARAM;
break;
}
if (rtn)
{
LOG_ERR("AddArcPos return %d", rtn);
}
return rtn;
}
int CCard::CrdStartMove(int index)
{
int rtn = 0;
RETURN_CHK_NOPRT(_bOpened, ERR_NO_INIT);
RETURN_CHK_NOPRT(index >= 0 && index < MAXCRD, ERR_INPUT_PARAM);
RETURN_CHK_NOPRT(_crd[index].buse, ERR_NO_INIT);
//将前瞻缓冲区压入运动缓冲区
rtn = GT_CrdData(_cardIndex, _crd[index].crd, NULL);
if (rtn)
{
LOG_ERR("GT_CrdData return %d", rtn);
return rtn;
}
//启动插补运动
rtn = GT_CrdStart(_cardIndex, _crd[index].crd, 0);
if (rtn)
{
LOG_ERR("GT_CrdStart return %d", rtn);
}
return rtn;
}
int CCard::CrdStatus(int index, int *progress)
{
int ret = 0;
long res = 0;
short run = 0;
RETURN_CHK_NOPRT(_bOpened, 0);
RETURN_CHK_NOPRT(index >= 0 && index < MAXCRD, 0);
RETURN_CHK_NOPRT(_crd[index].buse, 0);
ret = GT_CrdStatus(_cardIndex, _crd[index].crd, &run, &res);
if (ret)
{
LOG_ERR("GT_CrdStatus return %d.", ret);
}
if (progress) *progress = (int)res; //已完成插补段数
return run; //1标识运动中 0标识运动完成
}
int CCard::GetExistCrd()
{
for(int i = 0; i < MAXCRD; i++)
{
if (!_crd[i].buse)
{//没有坐标系数据
return i;
}
}
return -1;
}
int CCard::SetCrd(TCrd& crd)
{
short rtn = 0;
TCrdPrm crdPrm;
memset(&crdPrm, 0, sizeof(TCrdPrm));
crdPrm.dimension = crd.axisCnt;
crdPrm.evenTime = 50;
crdPrm.setOriginFlag = 1;
for(int i = 0; i < crd.axisCnt; i++)
{
crdPrm.profile[crd.axisIndex[i]] = i + 1; //profile表示卡上所有轴数组下标为每个轴索引 i + 1 表示坐标系轴 从1开始
/*crdPrm.profile[i] = i + 1;*/
crdPrm.originPos[i] = /*pAxisParam->homeOffset*/0;
}
crdPrm.synVelMax = 10000;
crdPrm.synAccMax = 10000;
rtn = GT_SetCrdPrm(_cardIndex, crd.crd, &crdPrm);
if (rtn)
{
LOG_ERR("GT_SetCrdPrm return %d", rtn);
return rtn;
}
rtn = GT_CrdClear(_cardIndex, crd.crd, 0); //清空FIFO0
//rtn = GT_CrdClear(_cardIndex, crd.crd, 1); //清空FIFO1
if (rtn)
{
LOG_ERR("GT_CrdClear return %d", rtn);
return rtn;
}
rtn = GT_InitLookAhead(_cardIndex, crd.crd, 0, 5, 10000, AHEAD_BUFF, crd.pCrdData);
if (rtn)
{
LOG_ERR("GT_InitLookAhead return %d", rtn);
}
return rtn;
}
bool CCard::IsSamePos(long* pos1, long* pos2, int axisCnt)
{
for(int i = 0; i < axisCnt; i++)
{
if (abs(pos1[i] - pos2[i]) >= SAME_PULSE_OFFSET)
{//差距在可允许范围内
return false;
}
}
return true;
}
bool CCard::IsSameLine(long* pos1, long* pos2,long* pos3)
{
if ((pos2[0] - pos1[0])*(pos3[1] - pos2[1]) == (pos2[1] - pos1[1])*(pos3[0] - pos2[0]))
{
return true;
}
return false;
}
int CCard::CalcArcType(long* pos1, long* pos2, long* pos3, int axisCnt, int &arcType)
{
int i = 0;
//1-2 2-3不能重合
RETURN_CHK_NOPRT(!IsSamePos(pos1, pos2, axisCnt), ERR_INPUT_PARAM);
RETURN_CHK_NOPRT(!IsSamePos(pos2, pos3, axisCnt), ERR_INPUT_PARAM);
for(i = 0; i < axisCnt; i++)
{
if (abs(pos1[i] - pos2[i]) < SAME_PULSE_OFFSET &&
abs(pos1[i] - pos3[i]) < SAME_PULSE_OFFSET &&
abs(pos2[i] - pos3[i]) < SAME_PULSE_OFFSET)
{//差距在可允许范围内
break;
}
}
RETURN_CHK_NOPRT(i <= 2, ERR_INPUT_PARAM); //圆弧插补只能前面3个轴之间任意两轴
switch (i)
{
case 0:
arcType = EM_ARC_YZ; //把数据前移
pos1[0] = pos1[1];
pos1[1] = pos1[2];
pos2[0] = pos2[1];
pos2[1] = pos2[2];
pos3[0] = pos3[1];
pos3[1] = pos3[2];
break;
case 1:
arcType = EM_ARC_ZX; //把数据换一下顺序,否则参数不好传递
pos1[1] = pos1[0];
pos1[0] = pos1[2];
pos2[1] = pos2[0];
pos2[0] = pos2[2];
pos3[1] = pos3[0];
pos3[0] = pos3[2];
break;
case 2:
arcType = EM_ARC_XY;
break;
default:
break;
}
return 0;
}
void CCard::CalcCenter(long* pos1, long* pos2, long* pos3, double &x, double &y, double&r)
{
double a,b,c,d,e,f;
double x1,x2,x3,y1,y2,y3;
x1 = pos1[0];
x2 = pos2[0];
x3 = pos3[0];
y1 = pos1[1];
y2 = pos2[1];
y3 = pos3[1];
a = 2 * (x2 - x1);
b = 2 * (y2 - y1);
c = x2 * x2 + y2 * y2 - x1 * x1 - y1 * y1;
d = 2 * (x3 - x2);
e = 2 * (y3 - y2);
f = x3 * x3 + y3 * y3 - x2 * x2 - y2 * y2;
x = (b * f - e * c) / (b * d - e * a);
y = (d * c - a * f) / (b * d - e * a);
r = sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1));
}
bool CCard::CalcDir(long *pos1, long* pos2, long* pos3)
{
//a b c 顺序3个点网上参考答案
//(b.x - a.x) * (c.y - b.y) - (b.y - a.y) * (c.x - b.x)
long rtn = (pos2[0] - pos1[0]) * (pos3[1] - pos2[1]) - (pos2[1] - pos1[1]) * (pos3[0] - pos2[0]);
//大于0 顺时针, 小于0 逆时针
return rtn > 0 ? true : false;
}
short CCard::TransfIOType(short di_type)
{
int dioType[] = {
MC_GPI,
MC_GPO,
MC_LIMIT_POSITIVE,
MC_LIMIT_NEGATIVE,
MC_ALARM,
MC_HOME,
MC_ENABLE,
MC_CLEAR
};
return dioType[di_type];
}
const int g_diotype[] = {
MC_GPI,
MC_GPO,
MC_LIMIT_POSITIVE,
MC_LIMIT_NEGATIVE,
MC_ALARM,
MC_HOME,
MC_ENABLE,
MC_CLEAR
};
int CCard::ReadIn(EIOType di_type, long& val)
{
int ret = -1;
RETURN_CHK_NOPRT(_bOpened, ERR_NO_INIT);
ret = GT_GetDi(_cardIndex, g_diotype[di_type], &val);
if (ret)
{
LOG_ERR("GT_GetDi return error:%d", ret);
}
return ret;
}
int CCard::ReadOut(EIOType do_type, long& val)
{
int ret = -1;
RETURN_CHK_NOPRT(_bOpened, ERR_NO_INIT);
ret = GT_GetDo(_cardIndex, g_diotype[do_type], &val);
if (ret)
{
LOG_ERR("GT_GetDo return error:%d", ret);
}
return ret;
}
int CCard::ReadBit(ushort in_index, EIOType di_type)
{
long val = 0;
RETURN_CHK_NOPRT(in_index < MAXIO, 0);
if (IOT_COMOUT == di_type || IOT_SEVON == di_type || IOT_CLEARALARM == di_type)
{
return ReadOutBit(in_index, di_type);
}
if (ReadIn(di_type, val))
{//读取错误
return 0;
}
return 0x01 & (val>>in_index);
}
int CCard::ReadOutBit(ushort out_index, EIOType do_type)
{
long val = 0;
RETURN_CHK_NOPRT(out_index < MAXIO, 0);
if (ReadOut(do_type, val))
{//读取错误
return 0;
}
return 0x01 & (val>>out_index);
}
int CCard::WriteOutBit(ushort out_index, ushort val, EIOType do_type)
{
int ret = ERR_INPUT_PARAM;
RETURN_CHK_NOPRT(_bOpened, ERR_NO_INIT);
if (IOT_SEVON == do_type)
{//伺服使能
RETURN_CHK_NOPRT(out_index < MAXAXIS, ERR_INPUT_PARAM);
return val ? _pAxis[out_index]->On() : _pAxis[out_index]->Off();
}
else if (IOT_COMOUT == do_type || IOT_CLEARALARM == do_type)
{//输出
RETURN_CHK_NOPRT(out_index < MAXIO, ERR_INPUT_PARAM);
ret = GT_SetDoBit(_cardIndex, g_diotype[do_type], out_index + 1, val);
if (ret)
{
LOG_ERR("GT_SetDoBit return error:%d", ret);
}
}
return ret;
}
int CCard::ReadADC(ushort index, double* pval)
{
int ret = 0;
RETURN_CHK_NOPRT(_bOpened, ERR_NO_INIT);
RETURN_CHK_NOPRT(pval && index < MAXAD, ERR_INPUT_PARAM);
ret = GT_GetAdc(_cardIndex, index + 1, pval);
if (ret)
{
LOG_ERR("GT_GetAdc return error:%d", ret);
}
return ret;
}
int CCard::WriteADC(ushort index, double val)
{
int ret = 0;
short rtn = 0;
RETURN_CHK_NOPRT(_bOpened, ERR_NO_INIT);
RETURN_CHK_NOPRT(index < MAXAD, ERR_INPUT_PARAM);
rtn = (short)double_to_int(val);
ret = GT_SetDac(_cardIndex, index + 1, &rtn);
if (ret)
{
LOG_ERR("GT_SetDac return error:%d", ret);
}
return ret;
}
#define RESET "reset" //重置卡
#define PAUSE "pause" //暂停运动
#define CONTINUE "continue" //继续运动
#define BACKLASH "backlash" //反向间隙补偿
#define ARRIVE "arrive" //设置到位信号
#define SETAD "writeda" //设置电压值
int CCard::SendCustomCommand(const char* msg, char* res/* = 0*/)
{
char* ptmp = NULL;
char buff[256] = {0};
char* pnext = buff;
RETURN_CHK_NOPRT(msg, ERR_INPUT_PARAM);
RETURN_CHK_NOPRT(_bOpened, ERR_NO_INIT);
strcpy(buff, msg); //拷贝指令
ptmp = sys_strtok(NULL, ", ", &pnext);
RETURN_CHK_NOPRT(ptmp, ERR_INPUT_PARAM);
if (0 == sys_stricmp(RESET, ptmp))
{//reset
RETURN_CHK_NOPRT(!pnext || 0 == *pnext, ERR_INPUT_PARAM); //结束
return Reset();
}
else if (0 == sys_stricmp(PAUSE, ptmp))
{//pause
RETURN_CHK_NOPRT(!pnext || 0 == *pnext, ERR_INPUT_PARAM); //结束
return 0;
}
else if (0 == sys_stricmp(CONTINUE, ptmp))
{//continue
RETURN_CHK_NOPRT(!pnext || 0 == *pnext, ERR_INPUT_PARAM); //结束
return 0;
}
else if (0 == sys_stricmp(BACKLASH, ptmp))
{//负向间隙补偿
return SetBacklash(pnext);
}
else if (0 == sys_stricmp(ARRIVE, ptmp))
{//到位信号
return SetArrive(pnext);
}
else if (0 == sys_stricmp(SETAD, ptmp))
{
return SetAD(pnext);
}
return ERR_INPUT_PARAM;
}
int CCard::RecvCustomCommand(const char* msg, char* res/* = 0*/, int timeout/* = 0*/)
{
return ERR_INPUT_PARAM;
}
int CCard::ParseCompare(char* param)
{
char *ptm = NULL;
char *pNextToken = param;
short chn,mode,style,encx,ency,count;
long pbuffx[MAX_BUF_LEN], pbuffy[MAX_BUF_LEN];
ptm = sys_strtok(NULL,",",&pNextToken);
RETURN_CHK_NOPRT(ptm,ERR_INPUT_PARAM);
chn = atoi(ptm);
ptm = sys_strtok(NULL,",",&pNextToken);
RETURN_CHK_NOPRT(ptm,ERR_INPUT_PARAM);
mode = atoi(ptm);
ptm = sys_strtok(NULL,",",&pNextToken);
RETURN_CHK_NOPRT(ptm,ERR_INPUT_PARAM);
style = atoi(ptm);
if(0 == style)
{
ptm = sys_strtok(NULL,",",&pNextToken);
RETURN_CHK_NOPRT(ptm,ERR_INPUT_PARAM);
encx = atoi(ptm);
ptm = sys_strtok(NULL,",",&pNextToken);
RETURN_CHK_NOPRT(ptm,ERR_INPUT_PARAM);
ency = atoi(ptm);
return SetComparePrm(chn, mode, encx, ency);
}
ptm = sys_strtok(NULL,",",&pNextToken);
RETURN_CHK_NOPRT(ptm,ERR_INPUT_PARAM);
count = atoi(ptm);
for(int i = 0;i< count;i++)
{
ptm = sys_strtok(NULL,",",&pNextToken);
RETURN_CHK_NOPRT(ptm,ERR_INPUT_PARAM);
pbuffx[i] = atoi(ptm);
ptm = sys_strtok(NULL,",",&pNextToken);
RETURN_CHK_NOPRT(ptm,ERR_INPUT_PARAM);
pbuffy[i] = atoi(ptm);
}
return StartCompare(chn, mode, count, pbuffx, pbuffy);
}
int CCard::SetComparePrm(short chn, short mode, short encx, short ency) //ency 为比较轴
{
int ret;
T2DComparePrm prm;
// ret = GT_2DCompareStop(cardIndex,chn);
// if(ret)
// {
// LOG_ERR("GT_CompareData return error:%d",ret);
// return ERR_MOTOR_API;
// }
ret = GT_2DCompareClear(_cardIndex, chn); //清空二维位置比较输出数据
if(ret)
{
LOG_ERR("GT_CompareData return error:%d",ret);
return ret;
}
ret = GT_2DCompareMode(_cardIndex, chn, mode); //设置位置比较输出模式 0:1D 1:2D
if(ret)
{
LOG_ERR("GT_CompareData return error:%d",ret);
return ret;
}
prm.encx=encx; //2关联比较轴x
prm.ency=ency; //1关联比较轴y 一维时只能比较Y轴,此时此处关联X轴号
prm.maxerr=150; //最大允许误差(单位:pulse)
prm.outputType=0; //输出类型: 0脉冲;1电平
prm.source=1; //比较源:0规划,1编码器
prm.startLevel=0; //初始电平是否反转0复位电平1反转
prm.threshold=10; //最优算法阈值
prm.time=200; //脉冲方式脉冲时间(单位us)
ret = GT_2DCompareSetPrm(_cardIndex,chn, //通道号 0 HSIO0 通道号 1 HSIO1
&prm);
if(ret)
{
LOG_ERR("GT_CompareData return error:%d",ret);
}
return ret;
}
int CCard::StartCompare(short chn, short mode, int count, long *px, long *py)
{
short ret = 1;
T2DCompareData databuf[MAX_BUF_LEN];
short pStatus,pFifo,pFifoCount,pBufCount;
long pCount;
double pValue;
for(int i=0;i<count;i++)
{
if(0 == mode)
{
ret = GT_GetEncPos(1,1,&pValue);
py[i]=py[i]-(long)pValue;
databuf[i].px = 0; //第一比较点(10000,10000)
}
else
{
ret = GT_GetEncPos(1,1,&pValue);
px[i]=px[i]-(long)pValue;
ret = GT_GetEncPos(1,2,&pValue);
py[i]=py[i]-(long)pValue;
databuf[i].px = px[i]; //第一比较点(10000,10000)
}
databuf[i].py = py[i];
}
ret = GT_2DCompareStatus(_cardIndex,chn,&pStatus, //读取位置比较状态这里主要获取空闲fifo
&pCount,&pFifo,&pFifoCount,&pBufCount);
if(ret)
{
LOG_ERR("GT_CompareData return error:%d",ret);
return ret;
}
ret=GT_2DCompareData(_cardIndex,chn, // 通道号 0 HSIO0 通道号 1 HSIO1
count, //位置比较数据个数
databuf, // 数据
pFifo); //空闲FIFO
//commandhandler("GT_2DCompareData", sRtn);
if(ret)
{
LOG_ERR("GT_CompareData return error:%d",ret);
return ret;
}
ret=GT_2DCompareStart(_cardIndex,chn); //启动位置比较
if(ret)
{
LOG_ERR("GT_CompareData return error:%d",ret);
return ret;
}
return 0;
}
int CCard::ParseGearMove(char* param)
{
char *pTmp = NULL;
char *pNextToken = param;
ushort masterAxis = 0;
ushort slaveAxis = 0;
int iGearType = 0;
double ratio = 0;
long masterSlope = 0;
int rtn = 0;
pTmp = sys_strtok(NULL, ",", &pNextToken);
RETURN_CHK_NOPRT(pTmp, ERR_INPUT_PARAM);
masterAxis = atoi(pTmp);
pTmp = sys_strtok(NULL, ",", &pNextToken);
RETURN_CHK_NOPRT(pTmp, ERR_INPUT_PARAM);
slaveAxis = atoi(pTmp);
pTmp = sys_strtok(NULL, ",", &pNextToken);
RETURN_CHK_NOPRT(pTmp, ERR_INPUT_PARAM);
iGearType = atoi(pTmp);
pTmp = sys_strtok(NULL, ",", &pNextToken);
RETURN_CHK_NOPRT(pTmp, ERR_INPUT_PARAM);
ratio = atof(pTmp);
pTmp = sys_strtok(NULL, ",", &pNextToken);
RETURN_CHK_NOPRT(pTmp, ERR_INPUT_PARAM);
masterSlope = atoi(pTmp);
RETURN_CHK_NOPRT(masterAxis < MAXAXIS && slaveAxis < MAXAXIS, ERR_INPUT_PARAM);
return _pAxis[slaveAxis]->GearMove(_pAxis[masterAxis], iGearType, ratio, masterSlope);
}
//backlash,axis,offset;
int CCard::SetBacklash(char* param)
{
int ret = 0;
short axis = 0;
char* ptmp = NULL;
long compValue = 0;
ptmp = sys_strtok(NULL, ", ", &param);
RETURN_CHK_NOPRT(EMSTR_INT == get_str_type(ptmp), ERR_INPUT_PARAM);
axis = (short)atoi(ptmp);
RETURN_CHK_NOPRT(axis < MAXAXIS, ERR_INPUT_PARAM);
RETURN_CHK_NOPRT(EMSTR_INT == get_str_type(param), ERR_INPUT_PARAM);
compValue = atoi(param);
ret = GT_SetBacklash(_cardIndex, axis, compValue, (double)compValue * 0.175, 0);
if (ret)
{
LOG_ERR("GT_SetBacklash return error:%d", ret);
}
return ret;
}
//arrive,axis,1;
int CCard::SetArrive(char* param)
{
int flag = 0;
char* ptmp = NULL;
ushort axisIndex = 0;
ptmp = sys_strtok(NULL, ", ", &param);
RETURN_CHK_NOPRT(EMSTR_INT == get_str_type(ptmp), ERR_INPUT_PARAM);
axisIndex = (ushort)atoi(ptmp);
RETURN_CHK_NOPRT(axisIndex < MAXAXIS, ERR_INPUT_PARAM);
RETURN_CHK_NOPRT(EMSTR_INT == get_str_type(param), ERR_INPUT_PARAM);
flag = atoi(param);
RETURN_CHK_NOPRT(flag <= 1 && flag >= 0, ERR_INPUT_PARAM);
LOG_INF1("arrive(%d,%d) = 0", axisIndex, flag);
_pAxis[axisIndex]->SetArrive(flag ? true : false);
return 0;
}
//writeda,adindex,val
int CCard::SetAD(char* param)
{
short val = 0;
char* ptmp = NULL;
ushort adIndex = 0;
ptmp = sys_strtok(NULL, ", ", &param);
if (EMSTR_INT != get_str_type(ptmp) ||
EMSTR_INT != get_str_type(param))
{
LOG_ERR("input param error. adindex/val param type.");
return ERR_INPUT_PARAM;
}
adIndex = (ushort)atoi(ptmp);
val = (short)atoi(param);
return WriteADC(adIndex, val);
}