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.

1189 lines
42 KiB
C++

#include "StdAfx.h"
#include "MotionCard_PCI1245.h"
#include "Propertie.h"
#include "PropertieMgr.h"
#include "AuthorityMgr.h"
#include "LogMgr.h"
#include "Motor.h"
#include "PlatformXY.h"
#include "MsgBox.h"
#include "FileMgr.h"
#include "SinglechipCardMgr.h"
#include "PciCh365Mgr.h"
#include "CommPortMgr.h"
#include "FileMgr.h"
#include "WorkTime.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#include "general.h"
#pragma comment( lib, "Version.lib" )
#pragma comment( lib, "ADVMOT.lib" )
#define MAX_ASIX_IDX 3 //运动控制卡最大支持的轴编号
#define CFG_FILE_PATH _T("\\Parameter\\MotionCard_PCI1245\\PCI_1245.cfg")
//检查轴状态的线程
UINT CheckAsixStateThread(LPVOID pParam)
{
MotionCard_PCI1245 *p = (MotionCard_PCI1245 *)pParam;
p->CheckAsixState();
return 0;
}
MotionCard_PCI1245 *gMotionCard_PCI1245 = new MotionCard_PCI1245;
MotionCard_PCI1245::MotionCard_PCI1245(void)
{
m_bUsed = false;//是否使用
m_bArcCut = false;//圆弧插补
m_Devhand = 0;
memset(m_Axishand,0,sizeof(m_Axishand));
for (int i=0;i<32;i++)
{
m_End[i]=0;
}
m_ulAxisCount=0;
m_bServoOn =FALSE;
m_bInit=FALSE;
m_CurGpIdx = 0;//当前使用的组编号
m_GpHand=0;
AxCount=0;
m_EndNum =0;
m_MotorXAsixIdx = 1;//X轴对应的轴编号
m_MotorX2AsixIdx = 3;//X 2轴对应的轴编号
m_MotorYAsixIdx = 0;//Y轴对应的轴编号
m_MotorZAsixIdx = 2;//Z轴对应的轴编号
m_bGroupAisxRev = false;//插补轴调换
m_CheckDelay = 20;//等待电机运动时检测延时ms
m_bInited = false;//是否被正常初始化
m_bMotorXMoveStop = true;//轴是否运动停止
m_bMotorX2MoveStop = true;//
m_bMotorYMoveStop = true;//
m_bMotorZMoveStop = true;//
m_bAutoCloseSevon = false;//关闭程序时自动关闭sevon
m_bCheckActCoord = true;//是否检测实际光栅尺的坐标
m_MaxActCoordErr = 10;//允许最大光栅尺误差脉冲个数
m_XYFindOriginByLimit = true;//XY轴通过找极限来找原点(汕尾信利6台机)
}
MotionCard_PCI1245::~MotionCard_PCI1245(void)
{
}
CMFCPropertyGridProperty *MotionCard_PCI1245::CreatGridProperty()
{
CString PropertyName;//属性名称
CString Description;//描述
CString Path = _T("MotionCard_PCI1245");//存储路径
CString Name;
//-------------------------------------------------------------------------------//
PropertyName = _T("PCI 1245L 运动控制卡");
CMFCPropertyGridProperty* pGroup = new CMFCPropertyGridProperty(PropertyName);
//-------------------------------------------------------------------------------//
if(gAuthorityMgr->CheckAuthority(_FACTORY))
{
{
//添加属性变量映射
Name = _T("m_bUsed");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_bUsed);
pPropertie->SetType(_PROP_TYPE_BOOL);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("是否使用");
Description = _T("是否使用运动控制卡控制电机");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_bUsed, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = _T("m_XYFindOriginByLimit");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_XYFindOriginByLimit);
pPropertie->SetType(_PROP_TYPE_BOOL);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("极限原点");
Description = _T("是否XY轴通过找极限来找原点");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_XYFindOriginByLimit, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = _T("m_bCheckActCoord");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_bCheckActCoord);
pPropertie->SetType(_PROP_TYPE_BOOL);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("检测光栅尺");
Description = _T("是否检测光栅尺的坐标");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_bCheckActCoord, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = _T("m_MaxActCoordErr");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_MaxActCoordErr);
pPropertie->SetType(_PROP_TYPE_DOUBLE);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("光栅尺误差脉冲");
Description = _T("允许最大光栅尺误差脉冲个数");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_MaxActCoordErr, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = _T("m_bAutoCloseSevon");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_bAutoCloseSevon);
pPropertie->SetType(_PROP_TYPE_BOOL);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("退出时关闭sevon");
Description = _T("软件退出时自动关闭所有轴的sevon");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_bAutoCloseSevon, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = _T("m_bArcCut");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_bArcCut);
pPropertie->SetType(_PROP_TYPE_BOOL);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("圆弧插补");
Description = _T("是否使用平台圆弧插补");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_bArcCut, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = _T("m_bGroupAisxRev");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_bGroupAisxRev);
pPropertie->SetType(_PROP_TYPE_BOOL);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("插补轴调换");
Description = _T("如果插补轴运动反向,调换轴顺序");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_bGroupAisxRev, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = _T("m_CheckDelay");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_CheckDelay);
pPropertie->SetType(_PROP_TYPE_INT);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("检测延时");
Description = _T("检测电机运动的延时ms");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_CheckDelay, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = _T("m_MotorXAsixIdx");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_MotorXAsixIdx);
pPropertie->SetType(_PROP_TYPE_INT);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("X 轴编号");
Description = _T("X 轴对应的轴编号");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_MotorXAsixIdx, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = _T("m_MotorX2AsixIdx");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_MotorX2AsixIdx);
pPropertie->SetType(_PROP_TYPE_INT);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("X 2轴编号");
Description = _T("X 2轴对应的轴编号");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_MotorX2AsixIdx, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = _T("m_MotorYAsixIdx");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_MotorYAsixIdx);
pPropertie->SetType(_PROP_TYPE_INT);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("Y 轴编号");
Description = _T("Y 轴对应的轴编号");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_MotorYAsixIdx, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = _T("m_MotorZAsixIdx");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_MotorZAsixIdx);
pPropertie->SetType(_PROP_TYPE_INT);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("Z 轴编号");
Description = _T("Z 轴对应的轴编号");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_MotorZAsixIdx, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
if(gAuthorityMgr->CheckAuthority(_FACTORY))
{
CMFCPropertyGridProperty* pGroup1;
pGroup1 = CreatSpeedGridProperty(m_OrgSpeedMotorZ,_T("Z 轴原点速度"),_T("m_OrgSpeedMotorZ"));
pGroup->AddSubItem(pGroup1);
pGroup1 = CreatSpeedGridProperty(m_MoveSpeedMotorZ,_T("Z 轴移动速度"),_T("m_MoveSpeedMotorZ"));
pGroup->AddSubItem(pGroup1);
pGroup1 = CreatSpeedGridProperty(m_OrgSpeedMotorXY,_T("XY 轴原点速度"),_T("m_OrgSpeedMotorXY"));
pGroup->AddSubItem(pGroup1);
pGroup1 = CreatSpeedGridProperty(m_MoveSpeedMotorX,_T("X 轴空移速度"),_T("m_MoveSpeedMotorX"));
pGroup->AddSubItem(pGroup1);
pGroup1 = CreatSpeedGridProperty(m_WorkSpeedMotorX,_T("X 轴工作速度"),_T("m_WorkSpeedMotorX"));
pGroup->AddSubItem(pGroup1);
pGroup1 = CreatSpeedGridProperty(m_MoveSpeedMotorY,_T("Y 轴空移速度"),_T("m_MoveSpeedMotorY"));
pGroup->AddSubItem(pGroup1);
pGroup1 = CreatSpeedGridProperty(m_WorkSpeedMotorY,_T("Y 轴工作速度"),_T("m_WorkSpeedMotorY"));
pGroup->AddSubItem(pGroup1);
}
if(gAuthorityMgr->CheckAuthority(_FACTORY))
{
PropertyName = "下料机保护信号";
CMFCPropertyGridProperty* pGroup1 = new CMFCPropertyGridProperty(PropertyName);
{
//添加属性变量映射
Name = "m_AsixNum";//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&(m_InPortUnload.m_AsixNum));
pPropertie->SetType(_PROP_TYPE_INT);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("轴编号");
Description = _T("用于控制的轴编号(0~3)");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName,(_variant_t)(m_InPortUnload.m_AsixNum), Description);
pGroup1->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = "m_PortNum";//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&(m_InPortUnload.m_PortNum));
pPropertie->SetType(_PROP_TYPE_INT);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("端口号");
Description = _T("用于控制的端口号(0~3)");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName,(_variant_t)m_InPortUnload.m_PortNum, Description);
pGroup1->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = "m_bRev";//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&(m_InPortUnload.m_bRev));
pPropertie->SetType(_PROP_TYPE_BOOL);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("是否反向");
Description = _T("端口控制是否反向");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName,(_variant_t)m_InPortUnload.m_bRev, Description);
pGroup1->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
pGroup->AddSubItem(pGroup1);
}
}
//-------------------------------------------------------------------------------//
return pGroup;
}
CMFCPropertyGridProperty* MotionCard_PCI1245::CreatSpeedGridProperty(PCI1245_SpeedParam &SpeedParam,CString SpeedName,CString ValName)
{
CString PropertyName;//属性名称
CString Description;//描述
CString Path = _T("MotionCard_PCI1245");//存储路径
CString Name;
CMFCPropertyGridProperty* pGroup1 = new CMFCPropertyGridProperty(SpeedName);
{
{
//添加属性变量映射
Name = ValName+_T("_Acc");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&SpeedParam.m_Acc);
pPropertie->SetType(_PROP_TYPE_DOUBLE);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("加速度");
Description = _T("静止到运行速度的加速度(mm/s2)");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)SpeedParam.m_Acc, Description);
pGroup1->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = ValName+_T("_Dec");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&SpeedParam.m_Dec);
pPropertie->SetType(_PROP_TYPE_DOUBLE);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("减速度");
Description = _T("运行速度到静止的减速度(mm/s2)");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)SpeedParam.m_Dec, Description);
pGroup1->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = ValName+_T("_VelLow");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&SpeedParam.m_VelLow);
pPropertie->SetType(_PROP_TYPE_DOUBLE);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("起动速度");
Description = _T("起动速度(mm/s)");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)SpeedParam.m_VelLow, Description);
pGroup1->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = ValName+_T("_VelHigh");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&SpeedParam.m_VelHigh);
pPropertie->SetType(_PROP_TYPE_DOUBLE);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("运行速度");
Description = _T("运行速度(mm/s)");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)SpeedParam.m_VelHigh, Description);
pGroup1->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
}
return pGroup1;
}
void MotionCard_PCI1245::ExportPar(ofstream *pFile)
{
}
#if 1
void MotionCard_PCI1245::Ini()
{
/* if(!m_bUsed)
return;
CCommPortMgr Comm;
if(!Comm.Open(1,9600))//如果无法操作串口的话说明在笔记本上运行
return;
Comm.Close();
//设置轴的编号-------------------------------------------
CMotor &MotorX = *(CMotor::GetMotor(MOTOR_X));
CMotor &MotorX2 = *(CMotor::GetMotor(MOTOR_X2));
CMotor &MotorY = *(CMotor::GetMotor(MOTOR_Y));
CMotor &MotorZ = *(CMotor::GetMotor(MOTOR_Z));
MotorX.SetAsixIdx(m_MotorXAsixIdx);
MotorX2.SetAsixIdx(m_MotorX2AsixIdx);
MotorY.SetAsixIdx(m_MotorYAsixIdx);
MotorZ.SetAsixIdx(m_MotorZAsixIdx);
//初始化卡
if(!InitCard())
return;
//打开卡并读取支持的轴
if(!OpenCard())
return;
//检查轴的编号是否合法
if(!CheckRange(m_MotorXAsixIdx,0,MAX_ASIX_IDX)
|| !CheckRange(m_MotorX2AsixIdx,0,MAX_ASIX_IDX)
|| !CheckRange(m_MotorYAsixIdx,0,MAX_ASIX_IDX)
|| !CheckRange(m_MotorZAsixIdx,0,MAX_ASIX_IDX)
)
{
gLogMgr->WriteDebugLog("[Error]---->invalid Asix Idx");
return;
}
//读取运动控制卡的参数文件.cfg
LoadConfigFile();
//将绑定XY 轴为一个组(支持线性插补运动)
AddAsixToGroup(m_GpHand,m_MotorXAsixIdx);
AddAsixToGroup(m_GpHand,m_MotorYAsixIdx);
SetCurGpIdx(0);
//自动SvOn
SetSvOn(true);
//启动读取轴状态的线程
AfxBeginThread(CheckAsixStateThread,this);*/
}
void MotionCard_PCI1245::OnExitApp()
{
/*if(m_bAutoCloseSevon)
SetSvOn(false);*/
}
void MotionCard_PCI1245::SetSvOn(bool bOn)
{
gLogMgr->WriteDebugLog("Fuc---->Motion Asix SetSvOn");
for(int k=0;k<=MAX_ASIX_IDX;k++)
{
Acm_AxSetSvOn(m_Axishand[k],bOn);
Sleep(100);
}
}
//初始化运动控制卡
bool MotionCard_PCI1245::InitCard()
{
U32 Result;
ULONG i=0;
ULONG deviceNumber=0;//卡的数量
CString strTemp;
Result = Acm_GetAvailableDevs(m_avaDevs,MAX_DEVICES,&deviceNumber);
if (Result!=SUCCESS || deviceNumber<=0)
{
gLogMgr->WriteDebugLog("[Error]---->Acm_GetAvailableDevs");
return false;
}
m_dwDevNum=m_avaDevs[0].dwDeviceNum;//当前的设备号
gLogMgr->WriteDebugLog("Fuc---->InitMotionCard 1245L Success");
m_bInited = true;//是否被正常初始化
return true;
}
//打开卡
bool MotionCard_PCI1245::OpenCard()
{
U32 Result;
ULONG i=0;
CString strTemp;
CString strString;
ULONG AxisPerDev=0;
ULONG AxisNumber=0;
//打开设备m_dwDevNum ,获得设备句柄m_Devhand
Result = Acm_DevOpen(m_dwDevNum, &m_Devhand);
if (Result != SUCCESS)
{
strString.Format("Open Device Failed With Error Code:%x",Result);
gLogMgr->WriteDebugLog(strString);
return false;
}
//获得设备轴的数量
Result = Acm_GetU32Property(m_Devhand,FT_DevAxesCount,&AxisPerDev);
if (Result!=SUCCESS)
{
strString.Format("Get Device Axes Number Failed With Error Code: %x",Result);
gLogMgr->WriteDebugLog(strString);
return false;
}
m_ulAxisCount=AxisPerDev;
//if you device is fixed,for example: PCI-1245 m_ulAxisCount =4
for(AxisNumber=0;AxisNumber<m_ulAxisCount;AxisNumber++)
{
//打开轴,并获得轴的句柄m_Axishand
Result =Acm_AxOpen(m_Devhand, (USHORT)AxisNumber, &m_Axishand[AxisNumber]);
if(Result != SUCCESS)
{
strString.Format("Open Axis Failed With Error Code: %x",Result);
gLogMgr->WriteDebugLog(strString);
return false;
}
//设置轴的初始坐标为0
Acm_AxSetCmdPosition(m_Axishand[AxisNumber],0);
}
m_bInit = TRUE; //是否打开成功
gLogMgr->WriteDebugLog("Fuc---->OpenCard 1245L Success");
return true;
}
//使用运动控制卡的时候有些功能不能使用
bool MotionCard_PCI1245::CheckFucCanUsed()
{
if(m_bUsed)
{
CMsgBox MsgBox;
MsgBox.Show(_T("使用运动控制卡时不能使用"));
return false;
}
return true;
}
//读取运动控制卡的参数文件.cfg
void MotionCard_PCI1245::LoadConfigFile()
{
CString strTemp;
CFileMgr FileMgr;
FileMgr.GetFullFilePath(strTemp,CFG_FILE_PATH);//获取完整路径
//Set all configurations for the device according to the loaded file
U32 Result;
Result=Acm_DevLoadConfig(m_Devhand,strTemp.GetBuffer(strTemp.GetLength()));
if(Result != SUCCESS)
{
strTemp.Format("Load Config Failed With Error Code: %x",Result);
gLogMgr->WriteDebugLog(strTemp);
return;
}
gLogMgr->WriteDebugLog("Fuc---->LoadConfigFile 1245 Success");
}
#endif
#if 1//组运动
//添加轴到组
bool MotionCard_PCI1245::AddAsixToGroup(HAND &GpHand,UINT index)
{
U32 Result;
CString strTemp;
Result = Acm_GpAddAxis(&GpHand,m_Axishand[index]);
if (Result!=SUCCESS)
{
strTemp.Format("Add Axis To Group Failed With Error Code: %x",Result);
gLogMgr->WriteDebugLog(strTemp);
return false;
}
CString LogStr;
LogStr.Format(_T("AddAsixToGroup [Asix index] = [%d]"),index);
gLogMgr->WriteDebugLog(LogStr);
return true;
}
//设置当前的组编号
void MotionCard_PCI1245::SetCurGpIdx(int idx)
{
CString LogStr;
LogStr.Format(_T("SetCurGpIdx [index] = [%d]"),idx);
gLogMgr->WriteDebugLog(LogStr);
m_CurGpIdx = idx;
gPlatformXY->SetCoord(GetPlatformXYCoord());
}
void MotionCard_PCI1245::ResetAllAsixCoord()
{
gLogMgr->WriteDebugLog("ResetAllAsixCoord");
Acm_AxSetCmdPosition(m_Axishand[m_MotorXAsixIdx],0);
Acm_AxSetCmdPosition(m_Axishand[m_MotorX2AsixIdx],0);
Acm_AxSetCmdPosition(m_Axishand[m_MotorYAsixIdx],0);
Acm_AxSetCmdPosition(m_Axishand[m_MotorZAsixIdx],0);
//同时设置光栅尺的坐标
Acm_AxSetActualPosition(m_Axishand[m_MotorXAsixIdx],0);
Acm_AxSetActualPosition(m_Axishand[m_MotorX2AsixIdx],0);
Acm_AxSetActualPosition(m_Axishand[m_MotorYAsixIdx],0);
//通知观察者平台坐标变化了
gPlatformXY->NotifyObservers();
}
//从运动控制卡读取平台当前的坐标
Dbxy MotionCard_PCI1245::GetPlatformXYCoord()
{
Dbxy Coord;
Dbxy OnePulseDis = gPlatformXY->GetMotorXYOnePulseDis();
//获取控制卡返回的脉冲位置
int MotorXAsixIdx = (m_CurGpIdx==0)?m_MotorXAsixIdx:m_MotorX2AsixIdx;
Acm_AxGetCmdPosition(m_Axishand[MotorXAsixIdx],&Coord.x);
Acm_AxGetCmdPosition(m_Axishand[m_MotorYAsixIdx],&Coord.y);
//换算为mm 单位
Coord.x *= OnePulseDis.x;
Coord.y *= OnePulseDis.y;
CString LogStr;
LogStr.Format(_T("[XYCoord.x] = [%f] [XYCoord.y] = [%f]"),Coord.x,Coord.y);
gLogMgr->WriteDebugLog(LogStr);
return Coord;
}
//强制设置平台的当前坐标
void MotionCard_PCI1245::SetCoord(Dbxy coord)
{
if(!m_bUsed)
return;
//mm 转换为脉冲坐标
Dbxy OnePulseDis = gPlatformXY->GetMotorXYOnePulseDis();
coord.x= coord.x/OnePulseDis.x;
coord.y = coord.y/OnePulseDis.y;
int MotorXAsixIdx = (m_CurGpIdx==0)?m_MotorXAsixIdx:m_MotorX2AsixIdx;
Acm_AxSetCmdPosition(m_Axishand[MotorXAsixIdx],coord.x);
Acm_AxSetCmdPosition(m_Axishand[m_MotorYAsixIdx],coord.y);
gLogMgr->WriteDebugLog("Fuc---->SetCoord 1245L Success");
}
//mm 转换为脉冲单位脉冲
Dbxy MotionCard_PCI1245::MM2PulseCoord(Dbxy Coord)
{
Dbxy OnePulseDis = gPlatformXY->GetMotorXYOnePulseDis();
Dbxy PulseCoord;
PulseCoord.x = Coord.x/OnePulseDis.x;
PulseCoord.y = Coord.y/OnePulseDis.y;
return PulseCoord;
}
//等待平台移动停止
void MotionCard_PCI1245::WaitPlatfromStop()
{
//等待直到移动完成----------------------
int TotalTimes = 0;
while(1)
{
if(TotalTimes++>100000)//防止死循环
{
break;
}
Sleep(m_CheckDelay);
//Get the Group's current state
U16 GpState;
Acm_GpGetState(m_GpHand, &GpState);
if(GpState != 4)//STA_GP_MOTION 表示运行状态
{
break;
}
}
}
//直线插补移动平台XY ---------------------------------------------------
Dbxy MotionCard_PCI1245::MovePlatformXY(Dbxy Coord)
{
//单轴移动
{
Dbxy CurCoord = gPlatformXY->GetCoord();
CString MotorStr = (m_CurGpIdx==0)?(MOTOR_X):(MOTOR_X2);
CMotor &MotorX = *(CMotor::GetMotor(MotorStr));
CMotor &MotorY = *(CMotor::GetMotor(MOTOR_Y));
double eps = 0.005;//需要移动时才调用,否则容易卡死
if(!IsTwoDbEqual(Coord.y,CurCoord.y,eps))
{
MoveMotor(MotorY,Coord.y);
}
if(!IsTwoDbEqual(Coord.x,CurCoord.x,eps))
{
MoveMotor(MotorX,Coord.x);
}
}
gLogMgr->WriteDebugLog("Fuc---->MovePlatformXY 1245L");
CString strTemp;
strTemp.Format("Coord x : %f,Coord y : %f",Coord.y);
gLogMgr->WriteDebugLog(strTemp);
//从运动控制卡读取平台当前的坐标---------------
return GetPlatformXYCoord();
}
//设置平台直线插补的运动速度(bWorkSpeed 是否为工作速度)
void MotionCard_PCI1245::SetPlatformSpeed(bool bWorkSpeed)
{
}
//mm 单位转换为脉冲单位
PCI1245_SpeedParam MotionCard_PCI1245::MM2PulseParam(PCI1245_SpeedParam &SpeedParam,double OnePulseDis)
{
PCI1245_SpeedParam Param;
Param.m_Acc = SpeedParam.m_Acc/OnePulseDis;//加速度(mm/s2)
Param.m_Dec = SpeedParam.m_Dec/OnePulseDis;//减速度(mm/s2)
Param.m_VelLow = SpeedParam.m_VelLow/OnePulseDis;//最低速度(mm/s)
Param.m_VelHigh = SpeedParam.m_VelHigh/OnePulseDis;//最高速度(mm/s)
return Param;
}
void MotionCard_PCI1245::SetPlatformSpeedExt(PCI1245_SpeedParam GpParam)
{
U32 Result;
double GpVelLow;
double GpVelHigh;
double GpAcc;
double GpDec;
double GpJerk;
CString strTemp;
HAND GpHand = m_GpHand;
GpVelLow = GpParam.m_VelLow;
Result = Acm_SetF64Property(GpHand,PAR_GpVelLow,GpVelLow);
if(Result != SUCCESS)
{
strTemp.Format("Set PAR_GpVelLow Property Failed With Error Code: %x",Result);
gLogMgr->WriteDebugLog(strTemp);
return;
}
GpVelHigh = GpParam.m_VelHigh;
Result = Acm_SetF64Property(GpHand,PAR_GpVelHigh,GpVelHigh);
if(Result != SUCCESS)
{
strTemp.Format("Set PAR_GpVelHigh Property Failed With Error Code: %x",Result);
gLogMgr->WriteDebugLog(strTemp);
return;
}
GpAcc = GpParam.m_Acc;
Result = Acm_SetF64Property(GpHand,PAR_GpAcc,GpAcc);
if(Result != SUCCESS)
{
strTemp.Format("Set PAR_GpAcc Property Failed With Error Code: %x",Result);
gLogMgr->WriteDebugLog(strTemp);
return;
}
GpDec = GpParam.m_Dec;
Result = Acm_SetF64Property(GpHand,PAR_GpDec,GpDec);
if(Result != SUCCESS)
{
strTemp.Format("Set PAR_GpDec Property Failed With Error Code: %x",Result);
gLogMgr->WriteDebugLog(strTemp);
return;
}
GpJerk = 0;//加速方式
Result = Acm_SetF64Property(GpHand,PAR_GpJerk,GpJerk);
if(Result != SUCCESS)
{
strTemp.Format("Set PAR_GpJerk Property Failed With Error Code: %x",Result);
gLogMgr->WriteDebugLog(strTemp);
return;
}
}
#endif
#if 1//单轴控制
//电机找原点
bool MotionCard_PCI1245::FindOrigin(CMotor &Motor)
{
bool ret;
if(m_XYFindOriginByLimit)
{
if(Motor.Name() == MOTOR_Z)//Z 轴原点还是找
ret = FindOriginExt(Motor);
else//XY轴使用找极限的方式
ret = FindOriginByLimit(Motor);
}
else
{
ret = FindOriginExt(Motor);
}
return ret;
}
//找原点开关的方式
bool MotionCard_PCI1245::FindOriginExt(CMotor &Motor)
{
int AsixIdx = Motor.GetAsixIdx();//轴的编号
if(!CheckRange(AsixIdx,0,MAX_ASIX_IDX))
return false;
//设置轴的坐标为0
Acm_AxSetCmdPosition(m_Axishand[AsixIdx],0);
U32 HomeMode = 6;//找原点的模式(如果在原点上,先反向移出原点再找)
U32 DirMode = (Motor.GetFindOriginDir())?1:0;//找原点方向
Acm_AxHome(m_Axishand[AsixIdx],HomeMode,DirMode);
//等待找原点完成
int TotalTimes = 0;
while(1)
{
if(TotalTimes++>100000)//防止死循环
{
return false;
}
Sleep(m_CheckDelay);
//Get the Group's current state
U16 GpState;
Acm_AxGetState(m_Axishand[AsixIdx],&GpState);
if(GpState != 4)//STA_AX_HOMING
{
break;
}
}
Sleep(1000);
CString LogStr;
//设置轴的初始坐标为0
Acm_AxSetCmdPosition(m_Axishand[AsixIdx],0);
LogStr.Format("Fuc---->FindOrigin Success[Asix Idx]: %d",AsixIdx);
gLogMgr->WriteDebugLog(LogStr);
return true;
}
//通过找极限的方式来找原点
bool MotionCard_PCI1245::FindOriginByLimit(CMotor &Motor)
{
int AsixIdx = Motor.GetAsixIdx();//轴的编号
if(!CheckRange(AsixIdx,0,MAX_ASIX_IDX))
return false;
//设置轴的坐标为0
Acm_AxSetCmdPosition(m_Axishand[AsixIdx],0);
//移动电机足够大距离(直到碰到极限)
double ReverseMoveDis = Motor.GetReverseMoveDis();
if(Motor.GetFindOriginDir()==false)
ReverseMoveDis *=(-1);
MoveMotor(Motor,ReverseMoveDis);
CString LogStr;
LogStr.Format("Fuc---->FindOriginByLimit [Asix Idx]: %d",AsixIdx);
gLogMgr->WriteDebugLog(LogStr);
//设置轴的初始坐标为0
//Acm_AxSetCmdPosition(m_Axishand[AsixIdx],0);
return true;
}
//重置所有轴的错误状态
void MotionCard_PCI1245::ResetAllAsixErr()
{
CString LogStr;
LogStr.Format("Fuc---->ResetAllAsixErr");
gLogMgr->WriteDebugLog(LogStr);
for(int k=0;k<=MAX_ASIX_IDX;k++)
{
Acm_AxResetError(m_Axishand[k]);
}
}
//移动到原点偏移位置
bool MotionCard_PCI1245::MoveToOriginOffset(CMotor &Motor)
{
int AsixIdx = Motor.GetAsixIdx();//轴的编号
if(!CheckRange(AsixIdx,0,MAX_ASIX_IDX))
return false;
double OffsetDis = Motor.GetOriginOffsetDis();//反向移动距离
bool bFindOriginDir = Motor.GetFindOriginDir();//找原点的方向
OffsetDis *= bFindOriginDir?(1):(-1);
MoveMotor(Motor,OffsetDis);
//设置轴的坐标为0
Acm_AxSetCmdPosition(m_Axishand[AsixIdx],0);
Motor.SetCoord(0);
CString LogStr;
LogStr.Format("Fuc---->MoveToOriginOffset Success[Asix Idx]: %d",AsixIdx);
gLogMgr->WriteDebugLog(LogStr);
return true;
}
//单轴移动电机到坐标Coord(绝对移动方式)
bool MotionCard_PCI1245::MoveMotor(CMotor &Motor,double &Coord)
{
int AsixIdx = Motor.GetAsixIdx();//轴的编号
if(!CheckRange(AsixIdx,0,MAX_ASIX_IDX))
return false;
U32 Result;
CString strString;
//转换为脉冲坐标----------------------------------
if(Motor.IsbReverseDir())
Coord *= -1;
F64 Position = Coord/Motor.GetOnePulseDis();
strString.Format("Move Coord: %f",Coord);
gLogMgr->WriteDebugLog(strString);
strString.Format("Move Position: %d",(int)Position);
gLogMgr->WriteDebugLog(strString);
Result=Acm_AxMoveAbs(m_Axishand[AsixIdx],Position);
if(Result != SUCCESS)
{
strString.Format("Move Failed With Error Code: %x",Result);
gLogMgr->WriteDebugLog(strString);
return false;
}
return true;
}
PCI1245_SpeedParam MotionCard_PCI1245::GetMotorSpeed(CMotor &Motor,ESpeedType SpeedType)
{
PCI1245_SpeedParam MotorSpeedParam;
if(Motor.Name() == MOTOR_X || Motor.Name() == MOTOR_X2)
{
if(SpeedType==_SpeedType_Org)
MotorSpeedParam = m_OrgSpeedMotorXY;
else if(SpeedType==_SpeedType_Move)
MotorSpeedParam = m_MoveSpeedMotorX;
else if(SpeedType==_SpeedType_Work)
MotorSpeedParam = m_WorkSpeedMotorX;
}
else if(Motor.Name() == MOTOR_Y)
{
if(SpeedType==_SpeedType_Org)
MotorSpeedParam = m_OrgSpeedMotorXY;
else if(SpeedType==_SpeedType_Move)
MotorSpeedParam = m_MoveSpeedMotorY;
else if(SpeedType==_SpeedType_Work)
MotorSpeedParam = m_WorkSpeedMotorY;
}
else if(Motor.Name() == MOTOR_Z)
{
if(SpeedType==_SpeedType_Org)
MotorSpeedParam = m_OrgSpeedMotorZ;
else if(SpeedType==_SpeedType_Move)
MotorSpeedParam = m_MoveSpeedMotorZ;
}
//转换为脉冲单位
double OnePulseDis = Motor.GetOnePulseDis();
PCI1245_SpeedParam SpeedParam = MM2PulseParam(MotorSpeedParam,OnePulseDis);
return SpeedParam;
}
//设置单轴的空移速度
void MotionCard_PCI1245::SetMotorSpeed(CMotor &Motor,ESpeedType SpeedType)
{
int AsixIdx = Motor.GetAsixIdx();//轴的编号
if(!CheckRange(AsixIdx,0,MAX_ASIX_IDX))
return ;
PCI1245_SpeedParam SpeedParam = GetMotorSpeed(Motor,SpeedType);
U32 Result;
double AxVelLow;
double AxVelHigh;
double AxAcc;
double AxDec;
double AxJerk;
CString strString;
AxVelLow = SpeedParam.m_VelLow;
AxVelHigh = SpeedParam.m_VelHigh;
AxAcc = SpeedParam.m_Acc;
AxDec = SpeedParam.m_Dec;
Result = Acm_SetF64Property(m_Axishand[AsixIdx],PAR_AxVelLow,AxVelLow);
if (Result != SUCCESS)
{
strString.Format("Set low velocity failed with error code: %x",Result);
gLogMgr->WriteDebugLog(strString);
return;
}
Result = Acm_SetF64Property(m_Axishand[AsixIdx],PAR_AxVelHigh,AxVelHigh);
if (Result != SUCCESS)
{
strString.Format("Set high velocity failed with error code: %x",Result);
gLogMgr->WriteDebugLog(strString);
return;
}
Result = Acm_SetF64Property(m_Axishand[AsixIdx],PAR_AxAcc,AxAcc);
if (Result != SUCCESS)
{
strString.Format("Set acceleration failed with error code: %x",Result);
gLogMgr->WriteDebugLog(strString);
return;
}
Result = Acm_SetF64Property(m_Axishand[AsixIdx],PAR_AxDec,AxDec);
if (Result != SUCCESS)
{
strString.Format("Set deceleration failed with error code: %x",Result);
gLogMgr->WriteDebugLog(strString);
return;
}
AxJerk = 0;
Result = Acm_SetF64Property(m_Axishand[AsixIdx],PAR_AxJerk,AxJerk);
if(Result != SUCCESS)
{
strString.Format("Set the type of velocity profile failed with error code: %x",Result);
gLogMgr->WriteDebugLog(strString);
return;
}
}
//检查轴的状态
void MotionCard_PCI1245::CheckAsixState()
{
while(1)
{
Sleep(m_CheckDelay);
m_bMotorXMoveStop = CheckAsixStateExt(m_Axishand[m_MotorXAsixIdx]);
m_bMotorX2MoveStop = CheckAsixStateExt(m_Axishand[m_MotorX2AsixIdx]);
m_bMotorYMoveStop = CheckAsixStateExt(m_Axishand[m_MotorYAsixIdx]);
m_bMotorZMoveStop = CheckAsixStateExt(m_Axishand[m_MotorZAsixIdx]);
}
}
bool MotionCard_PCI1245::CheckAsixStateExt(HAND AxisHandle)
{
U16 GpState;
Acm_AxGetState(AxisHandle,&GpState);
//STA_AX_PTP_MOT 表示运行状态
if(GpState != STA_AX_HOMING && GpState != STA_AX_PTP_MOT)
{
return true;
}
return false;
}
//读取轴AsixIdx 的Port 端口的状态(返回-1:错误,0:关,1:开)
int MotionCard_PCI1245::ReadIOState(CPci1245IOPort IOPort)
{
int AsixIdx = IOPort.m_AsixNum;
int Port = IOPort.m_PortNum;
if(Port<0 || Port>7)
return -1;
if(!CheckRange(AsixIdx,0,MAX_ASIX_IDX))
return -1;
U32 Ret; // 函数返回值
U8 bitData;
Ret = Acm_AxDiGetBit(m_Axishand[AsixIdx],Port,&bitData);
if(Ret != SUCCESS)
{
CString strTemp;
strTemp.Format("ReadIOState Failed With Error Code: %x",Ret);
gLogMgr->WriteDebugLog(strTemp);
return -1;
}
if(IOPort.m_bRev)
{
if(bitData==0)
bitData = 1;
else
bitData = 0;
}
return bitData;//bitData 的值为0 或1
}
//检查下料机状态(false 表示在轨道内,不安全)
bool MotionCard_PCI1245::CheckUnloadState()
{
int Ret = ReadIOState(m_InPortUnload);
if(Ret == 1)
return false;
return true;
}
#endif
#if 1
//从运动控制卡读取轴前的坐标
double MotionCard_PCI1245::GetMotorCoord(CMotor &Motor)
{
int AsixIdx = Motor.GetAsixIdx();//轴的编号
if(!CheckRange(AsixIdx,0,MAX_ASIX_IDX))
return -1;
double Coord;
double OnePulseDis = Motor.GetOnePulseDis();
//获取控制卡返回的脉冲位置
Acm_AxGetCmdPosition(m_Axishand[AsixIdx],&Coord);
//换算为mm 单位
Coord *= OnePulseDis;
return Coord;
}
//获取电机的实际位置(光栅尺反馈值)
double MotionCard_PCI1245::GetMotorActCoord(CMotor &Motor)
{
int AsixIdx = Motor.GetAsixIdx();//轴的编号
if(!CheckRange(AsixIdx,0,MAX_ASIX_IDX))
return -1;
double Coord;
//获取控制卡返回的脉冲位置
Acm_AxGetActualPosition(m_Axishand[AsixIdx],&Coord);
return Coord;
}
//检查电机的命令坐标和光栅尺坐标是否一致
bool MotionCard_PCI1245::CheckMotorActCoord(CMotor &Motor)
{
if(!m_bCheckActCoord)
return true;
int AsixIdx = Motor.GetAsixIdx();//轴的编号
if(!CheckRange(AsixIdx,0,MAX_ASIX_IDX))
return false;
double CmdCoord;//命令坐标
Acm_AxGetCmdPosition(m_Axishand[AsixIdx],&CmdCoord);
double ActualCoord;//光栅尺坐标
//获取控制卡返回的脉冲位置
Acm_AxGetActualPosition(m_Axishand[AsixIdx],&ActualCoord);
if(Motor.IsbRevActCoordDir())
ActualCoord *=(-1);
double ActPluseErrCnt = CmdCoord-ActualCoord;
if(fabs(ActPluseErrCnt)>m_MaxActCoordErr)
{
return false;
}
return true;
}
#endif