#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;AxisNumberWriteDebugLog(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