#include "StdAfx.h" #include "Motor.h" #include "Propertie.h" #include "PropertieMgr.h" #include "PciPortMgr.h" #include "MsgBox.h" #include "LogMgr.h" #include "AuthorityMgr.h" #include "ExceptionMsg.h" #include "FileMgr.h" #include "DeviceState.h" #include "ExceptionMsg.h" #include "MotionCard_PCI1245.h" #define MIN_DELAY 5 //脉冲最小延时时间us CMotor *CMotor::gMotorX = new CMotor(MOTOR_X);//X 轴 CMotor *CMotor::gMotorX2 = new CMotor(MOTOR_X2);//X2 轴 CMotor *CMotor::gMotorY = new CMotor(MOTOR_Y);//Y 轴 CMotor *CMotor::gMotorZ = new CMotor(MOTOR_Z);//Z 轴 CMotor::CMotor(CString Name) { m_Name = Name; //参数默认值 m_OnePulseDis = 0.005;//一个脉冲的理论移动距离 m_MaxPulseCnt = 50000;//找原点时最大脉冲,目的是为了防止硬件故障造成死循环 m_OriginOffsetDis = 0;//找完原点后的反方向移动距离 m_FindOriginDir = true;//找原点的方向(true 为向正,false 为向负) m_MoveDelay = 30;//空移延时us m_WorkDelay = 30;//正常工作时脉冲延时us m_OriginPulseDelay = 50;//初始化找远点脉冲延时us m_MaxOriginOffsetDis = -1;//原点的反方向最大移动距离(mm) -- 主要是保护硬件(-1 表示未设置) m_bNeedCheckLimit = true;//电机在运行时刻是否检查限位开关 m_StartDelay = 300;//初始速度延时 m_PerChangeDelay = 1;//每次改变的延时us m_bAccelerateCtrl = false;//是否加减速控制 m_Coord = 0;//电机单轴的坐标值 m_FindOriginDelay = 0;//找到原点后的等待延时(ms) 避免伺服电机的纠正过程 m_ReverseMoveDelay= 500;//找到光电开关后反方向移动的延时us (直到关电开关为OFF ) m_bCheckFiber = false;//时候检测光纤 m_bReverseMoveFirst = false;//找原点之前是否先反向移动一段距离 m_bReverseMoveDis = 0;//找原点之前是否先反向移动的距离mm m_AsixIdx = 0;//在运动控制卡中的编号 m_bReverseDir = false;//是否反向 m_bRevActCoordDir = false;//光栅尺反向 } CMotor::~CMotor(void) { } #if 1//复写module 的函数 CMFCPropertyGridProperty *CMotor::CreatGridProperty() { CString PropertyName;//属性名称 CString Description;//描述 CString Path = _T("motor")+m_Name;//存储路径 CString Name; //-------------------------------------------------------------------------------// PropertyName = _T("电机")+m_Name; CMFCPropertyGridProperty* pGroup = new CMFCPropertyGridProperty(PropertyName); //-------------------------------------------------------------------------------// if(gAuthorityMgr->CheckAuthority(_FACTORY)) { //添加属性变量映射 Name = _T("m_OnePulseDis");//变量名字 CPropertie *pPropertie = new CPropertie; pPropertie->SetpVal((void*)&m_OnePulseDis); pPropertie->SetType(_PROP_TYPE_DOUBLE); pPropertie->SetpModule(this); pPropertie->SetPath(Path); pPropertie->SetName(Name); pPropertie->WriteRead(true);//读取保存的属性 //添加属性显示 PropertyName = _T("脉冲分辨率"); Description = _T("电机一个脉冲移动的距离"); CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_OnePulseDis, Description); pGroup->AddSubItem(p); gDevicePropertieMgr.Insert(p, pPropertie); } if(gAuthorityMgr->CheckAuthority(_FACTORY)) { //添加属性变量映射 Name = _T("m_bNeedCheckLimit");//变量名字 CPropertie *pPropertie = new CPropertie; pPropertie->SetpVal((void*)&m_bNeedCheckLimit); pPropertie->SetType(_PROP_TYPE_BOOL); pPropertie->SetpModule(this); pPropertie->SetPath(Path); pPropertie->SetName(Name); pPropertie->WriteRead(true);//读取保存的属性 //添加属性显示 PropertyName = _T("是否检测限位开关"); Description = _T("是否检测限位开关"); CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_bNeedCheckLimit, Description); pGroup->AddSubItem(p); gDevicePropertieMgr.Insert(p, pPropertie); } if(gAuthorityMgr->CheckAuthority(_FACTORY)) { //添加属性变量映射 Name = _T("m_bReverseDir");//变量名字 CPropertie *pPropertie = new CPropertie; pPropertie->SetpVal((void*)&m_bReverseDir); pPropertie->SetType(_PROP_TYPE_BOOL); pPropertie->SetpModule(this); pPropertie->SetPath(Path); pPropertie->SetName(Name); pPropertie->WriteRead(true);//读取保存的属性 //添加属性显示 PropertyName = _T("是否反向"); Description = _T("是否反向"); CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_bReverseDir, Description); pGroup->AddSubItem(p); gDevicePropertieMgr.Insert(p, pPropertie); } if(gAuthorityMgr->CheckAuthority(_FACTORY)) { //添加属性变量映射 Name = _T("m_bRevActCoordDir");//变量名字 CPropertie *pPropertie = new CPropertie; pPropertie->SetpVal((void*)&m_bRevActCoordDir); pPropertie->SetType(_PROP_TYPE_BOOL); pPropertie->SetpModule(this); pPropertie->SetPath(Path); pPropertie->SetName(Name); pPropertie->WriteRead(true);//读取保存的属性 //添加属性显示 PropertyName = _T("光栅尺反向"); Description = _T("光栅尺坐标是否反向"); CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_bRevActCoordDir, Description); pGroup->AddSubItem(p); gDevicePropertieMgr.Insert(p, pPropertie); } //-------------------------------------------------------------------------------// //速度相关 { CMFCPropertyGridProperty* pGroup1 = new CMFCPropertyGridProperty(_T("电机速度")); if(gAuthorityMgr->CheckAuthority(_FACTORY)) { //添加属性变量映射 Name = _T("m_MoveDelay");//变量名字 CPropertie *pPropertie = new CPropertie; pPropertie->SetpVal((void*)&m_MoveDelay); pPropertie->SetType(_PROP_TYPE_INT); pPropertie->SetpModule(this); pPropertie->SetPath(Path); pPropertie->SetName(Name); pPropertie->WriteRead(true);//读取保存的属性 //添加属性显示 PropertyName = _T("空移脉冲延时"); Description = _T("脉冲之间的间隔时间,单位是us(微秒),值越小电机运动越快,需要考虑宽口的发送频率的限制"); CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_MoveDelay, Description); pGroup1->AddSubItem(p); gDevicePropertieMgr.Insert(p, pPropertie); } if(gAuthorityMgr->CheckAuthority(_FACTORY)) { //添加属性变量映射 Name = _T("m_WorkDelay");//变量名字 CPropertie *pPropertie = new CPropertie; pPropertie->SetpVal((void*)&m_WorkDelay); pPropertie->SetType(_PROP_TYPE_INT); pPropertie->SetpModule(this); pPropertie->SetPath(Path); pPropertie->SetName(Name); pPropertie->WriteRead(true);//读取保存的属性 //添加属性显示 PropertyName = _T("工作脉冲延时"); Description = _T("脉冲之间的间隔时间,单位是us(微秒),值越小电机运动越快,需要考虑宽口的发送频率的限制"); CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_WorkDelay, Description); pGroup1->AddSubItem(p); gDevicePropertieMgr.Insert(p, pPropertie); } pGroup->AddSubItem(pGroup1); } { CMFCPropertyGridProperty* pGroup1 = new CMFCPropertyGridProperty(_T("找原点")); if(gAuthorityMgr->CheckAuthority(_FACTORY)) { //添加属性变量映射 Name = _T("m_bReverseMoveFirst");//变量名字 CPropertie *pPropertie = new CPropertie; pPropertie->SetpVal((void*)&m_bReverseMoveFirst); pPropertie->SetType(_PROP_TYPE_BOOL); pPropertie->SetpModule(this); pPropertie->SetPath(Path); pPropertie->SetName(Name); pPropertie->WriteRead(true);//读取保存的属性 //添加属性显示 PropertyName = _T("先反向移动"); Description = _T("找原点之前是否先反向移动一段距离"); CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_bReverseMoveFirst, Description); pGroup1->AddSubItem(p); gDevicePropertieMgr.Insert(p, pPropertie); } if(gAuthorityMgr->CheckAuthority(_FACTORY)) { //添加属性变量映射 Name = _T("m_bReverseMoveDis");//变量名字 CPropertie *pPropertie = new CPropertie; pPropertie->SetpVal((void*)&m_bReverseMoveDis); pPropertie->SetType(_PROP_TYPE_DOUBLE); pPropertie->SetpModule(this); pPropertie->SetPath(Path); pPropertie->SetName(Name); pPropertie->WriteRead(true);//读取保存的属性 //添加属性显示 PropertyName = _T("反向移动距离"); Description = _T("找原点之前先反向移动的距离mm"); CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_bReverseMoveDis, Description); pGroup1->AddSubItem(p); gDevicePropertieMgr.Insert(p, pPropertie); } if(gAuthorityMgr->CheckAuthority(_FACTORY)) { //添加属性变量映射 Name = _T("m_OriginPulseDelay");//变量名字 CPropertie *pPropertie = new CPropertie; pPropertie->SetpVal((void*)&m_OriginPulseDelay); pPropertie->SetType(_PROP_TYPE_INT); pPropertie->SetpModule(this); pPropertie->SetPath(Path); pPropertie->SetName(Name); pPropertie->WriteRead(true);//读取保存的属性 //添加属性显示 PropertyName = _T("找原点脉冲延时"); Description = _T("脉冲之间的间隔时间,单位是us(微秒),值越小电机运动越快,需要考虑宽口的发送频率的限制"); CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_OriginPulseDelay, Description); pGroup1->AddSubItem(p); gDevicePropertieMgr.Insert(p, pPropertie); } if(gAuthorityMgr->CheckAuthority(_FACTORY)) { //添加属性变量映射 Name = _T("m_FindOriginDelay");//变量名字 CPropertie *pPropertie = new CPropertie; pPropertie->SetpVal((void*)&m_FindOriginDelay); pPropertie->SetType(_PROP_TYPE_INT); pPropertie->SetpModule(this); pPropertie->SetPath(Path); pPropertie->SetName(Name); pPropertie->WriteRead(true);//读取保存的属性 //添加属性显示 PropertyName = _T("找原点等待延时"); Description = _T("找到原点后的等待延时(ms) 避免伺服电机的纠正过程"); CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_FindOriginDelay, Description); pGroup1->AddSubItem(p); gDevicePropertieMgr.Insert(p, pPropertie); } if(gAuthorityMgr->CheckAuthority(_FACTORY)) { //添加属性变量映射 Name = _T("m_ReverseMoveDelay");//变量名字 CPropertie *pPropertie = new CPropertie; pPropertie->SetpVal((void*)&m_ReverseMoveDelay); pPropertie->SetType(_PROP_TYPE_INT); pPropertie->SetpModule(this); pPropertie->SetPath(Path); pPropertie->SetName(Name); pPropertie->WriteRead(true);//读取保存的属性 //添加属性显示 PropertyName = _T("移出限位延时"); Description = _T("找到光电开关后反方向移动离开限位的延时us (直到关电开关为OFF )"); CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_ReverseMoveDelay, Description); pGroup1->AddSubItem(p); gDevicePropertieMgr.Insert(p, pPropertie); } pGroup->AddSubItem(pGroup1); } //加速度相关 { CMFCPropertyGridProperty* pGroup1 = new CMFCPropertyGridProperty(_T("加减速控制")); if(gAuthorityMgr->CheckAuthority(_FACTORY)) { //添加属性变量映射 Name = _T("m_bAccelerateCtrl");//变量名字 CPropertie *pPropertie = new CPropertie; pPropertie->SetpVal((void*)&m_bAccelerateCtrl); pPropertie->SetType(_PROP_TYPE_BOOL); pPropertie->SetpModule(this); pPropertie->SetPath(Path); pPropertie->SetName(Name); pPropertie->WriteRead(true);//读取保存的属性 //添加属性显示 PropertyName = _T("是否加减速控制"); Description = _T("电机运动时是否使用加减速控制"); CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_bAccelerateCtrl, Description); pGroup1->AddSubItem(p); gDevicePropertieMgr.Insert(p, pPropertie); } if(gAuthorityMgr->CheckAuthority(_FACTORY)) { //添加属性变量映射 Name = _T("m_StartDelay");//变量名字 CPropertie *pPropertie = new CPropertie; pPropertie->SetpVal((void*)&m_StartDelay); pPropertie->SetType(_PROP_TYPE_INT); pPropertie->SetpModule(this); pPropertie->SetPath(Path); pPropertie->SetName(Name); pPropertie->WriteRead(true);//读取保存的属性 //添加属性显示 PropertyName = _T("初始延时增量"); Description = _T("电机启动时的脉冲延时增量(us(微秒)))"); CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_StartDelay, Description); pGroup1->AddSubItem(p); gDevicePropertieMgr.Insert(p, pPropertie); } if(gAuthorityMgr->CheckAuthority(_FACTORY)) { //添加属性变量映射 Name = _T("m_PerChangeDelay");//变量名字 CPropertie *pPropertie = new CPropertie; pPropertie->SetpVal((void*)&m_PerChangeDelay); pPropertie->SetType(_PROP_TYPE_INT); pPropertie->SetpModule(this); pPropertie->SetPath(Path); pPropertie->SetName(Name); pPropertie->WriteRead(true);//读取保存的属性 //添加属性显示 PropertyName = _T("延时增量"); Description = _T("每个脉冲延时的改变量(us(微秒)))"); CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_PerChangeDelay, Description); pGroup1->AddSubItem(p); gDevicePropertieMgr.Insert(p, pPropertie); } pGroup->AddSubItem(pGroup1); } //-------------------------------------------------------------------------------// //原点相关参数 if(gAuthorityMgr->CheckAuthority(_FACTORY)) { CMFCPropertyGridProperty* pGroup1 = new CMFCPropertyGridProperty(_T("电机原点")); //-------------------------------------------------------------------------------// { //添加属性变量映射 Name = _T("m_FindOriginDir");//变量名字 CPropertie *pPropertie = new CPropertie; pPropertie->SetpVal((void*)&m_FindOriginDir); pPropertie->SetType(_PROP_TYPE_BOOL); pPropertie->SetpModule(this); pPropertie->SetPath(Path); pPropertie->SetName(Name); pPropertie->WriteRead(true);//读取保存的属性 //添加属性显示 PropertyName = _T("找原点的方向"); Description = _T("电机找原点的方向,true 代表正向,false 代表负向"); CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_FindOriginDir, Description); pGroup1->AddSubItem(p); gDevicePropertieMgr.Insert(p, pPropertie); } //-------------------------------------------------------------------------------// { //添加属性变量映射 Name = _T("m_OriginOffsetDis");//变量名字 CPropertie *pPropertie = new CPropertie; pPropertie->SetpVal((void*)&m_OriginOffsetDis); pPropertie->SetType(_PROP_TYPE_DOUBLE); pPropertie->SetpModule(this); pPropertie->SetPath(Path); pPropertie->SetName(Name); pPropertie->WriteRead(true);//读取保存的属性 //添加属性显示 PropertyName = _T("原点偏移距离"); Description = _T("找完原点后的反方向移动距离"); CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_OriginOffsetDis, Description); pGroup1->AddSubItem(p); gDevicePropertieMgr.Insert(p, pPropertie); } { //添加属性变量映射 Name = _T("m_MaxOriginOffsetDis");//变量名字 CPropertie *pPropertie = new CPropertie; pPropertie->SetpVal((void*)&m_MaxOriginOffsetDis); pPropertie->SetType(_PROP_TYPE_DOUBLE); pPropertie->SetpModule(this); pPropertie->SetPath(Path); pPropertie->SetName(Name); pPropertie->WriteRead(true);//读取保存的属性 //添加属性显示 PropertyName = _T("原点最大偏移距离"); Description = _T("找完原点后的反方向最大移动距离(用于硬件保护)"); CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_MaxOriginOffsetDis, Description); pGroup1->AddSubItem(p); gDevicePropertieMgr.Insert(p, pPropertie); } //-------------------------------------------------------------------------------// { //添加属性变量映射 Name = _T("m_MaxPulseCnt");//变量名字 CPropertie *pPropertie = new CPropertie; pPropertie->SetpVal((void*)&m_MaxPulseCnt); pPropertie->SetType(_PROP_TYPE_DOUBLE); pPropertie->SetpModule(this); pPropertie->SetPath(Path); pPropertie->SetName(Name); pPropertie->WriteRead(true);//读取保存的属性 //添加属性显示 PropertyName = _T("原点最大脉冲"); Description = _T("找原点时最大脉冲,目的是为了防止硬件故障造成死循环,当超出这个脉冲个数仍然没有找到原点时会报错"); CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_MaxPulseCnt, Description); pGroup1->AddSubItem(p); gDevicePropertieMgr.Insert(p, pPropertie); } //-------------------------------------------------------------------------------// pGroup->AddSubItem(pGroup1); } return pGroup; } void CMotor::ExportPar(ofstream *pFile) { } void CMotor::Ini() { SetCoord(0); gMotorZ->NeedCheckFiber(); //初始化的时候读取端口的值 Update(); } void CMotor::SetPciPortType(CString DirPortType,CString PulsePortType,CString LimitPortType_F,CString LimitPortType_N) { m_DirPortType = DirPortType; m_PulsePortType = PulsePortType; m_LimitPortType_F = LimitPortType_F; m_LimitPortType_N = LimitPortType_N; } //收到属性变化的处理(重新读取端口号) void CMotor::Update() { m_DirPort = gPciPortMgr->GetCtrlPort(m_DirPortType);//方向端口 m_PulsePort = gPciPortMgr->GetCtrlPort(m_PulsePortType);//脉冲端口 m_LimitPort_F = gPciPortMgr->GetCtrlPort(m_LimitPortType_F);//正限位端口 m_LimitPort_N = gPciPortMgr->GetCtrlPort(m_LimitPortType_N);//负限位端口 m_FiberPort1 = gPciPortMgr->GetCtrlPort(PCI_PORT_FIBER1);//光纤端口1 m_FiberPort2 = gPciPortMgr->GetCtrlPort(PCI_PORT_FIBER2);//光纤端口1 } #endif //是否碰到限位开关 bool CMotor::IsLimitOn() { if(m_bNeedCheckLimit == false)//不需要检查限位开关 return false; //m_CurLimitPort 是根据电机的移动方向来确定的 if(gPciCh365Mgr->ReadPortState(m_CurLimitPort) ) { return true; } return false; } //初始化找到机械原点(bSavePulseCnt 表示是否记录脉冲个数, 用来回到上电的位置) bool CMotor::FindOrigin(bool bSavePulseCnt) { //先反向移动一段距离------------------------------------ if(m_bReverseMoveFirst && !bSavePulseCnt) { SetDir(!m_FindOriginDir); double PulseCnt; double MovePulseCnt = m_bReverseMoveDis/GetOnePulseDis(); SendSerialPulses(MovePulseCnt,PulseCnt,m_OriginPulseDelay); } //查找原点---------------------------------------------------- //设置方向 SetDir(m_FindOriginDir); bool ret = false; double PulseCnt; bool bNeedCheckLimit = m_bNeedCheckLimit;//备份 m_bNeedCheckLimit = true;//找原点时必须检测限位 ret = SendSerialPulses(m_MaxPulseCnt,PulseCnt,m_OriginPulseDelay); m_bNeedCheckLimit = bNeedCheckLimit;//恢复 if(ret)//脉冲发完了还没找到原点 { CString str = m_Name + _T("电机找原点失败!"); CExceptionMsg Msg; Msg.SetMsg(str); throw Msg; return false; } //反向移动出限位------------------------------------------------------- double ReversePlusCnt = 0;//反向移动脉冲个数 //反向移动直到离开限位 if(m_FindOriginDelay>0) { Sleep(m_FindOriginDelay); //反向 SetDir(!m_FindOriginDir); //设置检查原点的限位开关 SetCurLimitPortByDir(m_FindOriginDir); ReversePlusCnt = MoveDeviateLimit(m_ReverseMoveDelay); Sleep(m_FindOriginDelay/2);//移动完了再等待一会 } gLogMgr->WriteDebugLog("反向移动脉冲","",ReversePlusCnt); PulseCnt -= ReversePlusCnt; gLogMgr->WriteDebugLog("找原点脉冲","",PulseCnt); if(bSavePulseCnt)//记录初始点到原点的距离 { m_OriginOffsetDis = PulseCnt*GetOnePulseDis(); } return true; } //移动到指定的原点偏移位置 //FocusOffset 是微调值(正值往负方向调) bool CMotor::MoveToOriginOffset(double AdjustVal) { #if 0 SetCurLimitPortByDir(m_FindOriginDir);//强制为找远点方向来检查限位 if(IsLimitOn()==false)//调用这个函数时电机需要在限位上 { gLogMgr->WriteDebugLog("限位检查失败",_LOG_ERROR); return false; } #endif double OriginOffsetDis =m_OriginOffsetDis + AdjustVal; if(m_MaxOriginOffsetDis>0 && OriginOffsetDis > m_MaxOriginOffsetDis) { gLogMgr->WriteDebugLog("偏移距离超过限制",_LOG_ERROR); return false; } SetDir(!m_FindOriginDir);//找原点的反方向 double TotalCnt = OriginOffsetDis/GetOnePulseDis(); MoveByPluse(TotalCnt,false); Ini(); return true; } //发送连续脉冲(PulseCnt 统计一共发送了多少个脉冲,也可以不统计) bool CMotor::SendSerialPulses(double TotalCnt,double &PulseCnt,unsigned int Delay) { PulseCnt = 0; while(TotalCnt>0) { //发送一个脉冲 if(MoveOnePluse(Delay)==false) { return false;//脉冲没有全部发送完成 } TotalCnt -= 1; PulseCnt += 1; } //TotalCnt 发完了还没找到限位时不要统计 PulseCnt = 0; return true; } //移动电机直到没有检测到光电开关,并返回移动的脉冲个数 double CMotor::MoveDeviateLimit(unsigned int Delay) { double PulseCnt = 0; while(IsLimitOn()) { gPciCh365Mgr->SendOnePulse(m_PulsePort,Delay); PulseCnt += 1; } return PulseCnt; } //移动一个脉冲(Delay = 0 表示没有设置) bool CMotor::MoveOnePluse(unsigned int Delay) { if(IsLimitOn())//撞到限位了 { return false; } if(Delay == 0) { Delay = m_WorkDelay; } gPciCh365Mgr->SendOnePulse(m_PulsePort,Delay); return true; } //设置方向(b 为true 表示正向) void CMotor::SetDir(bool bForward) { gPciCh365Mgr->WritePortState(m_DirPort,bForward); gPciCh365Mgr->DelayTime(1000);//改变方向后延时1ms 再发脉冲 //改变方向时也要改变检查的限位端口 //主要是防止反向移动时卡在限位上 SetCurLimitPortByDir(bForward); } //根据方向设置检查限位的端口 void CMotor::SetCurLimitPortByDir(bool bForward) { if(bForward)//正向移动检查正限位 { m_CurLimitPort = m_LimitPort_F; } else//负向移动检查负限位 { m_CurLimitPort = m_LimitPort_N; } } //获取电机 CMotor *CMotor::GetMotor(CString Name) { CMotor *p = NULL; if(Name == MOTOR_X) return gMotorX; if(Name == MOTOR_X2) return gMotorX2; if(Name == MOTOR_Y) return gMotorY; if(Name == MOTOR_Z) return gMotorZ; return NULL; } //获取最大速度延时 unsigned int CMotor::GetDelay(bool bWork) { if(bWork) return m_WorkDelay; else return m_MoveDelay; } //获取相对于机械原点的坐标值 double CMotor::GetCoord2() { return m_OriginOffsetDis-m_Coord; } #if 1 void CMotor::OnMotorLimit() { //重置初始化状态 CDeviceState &DeviceState = CDeviceState::GetInstance(); DeviceState.SetIniState(false); } //按连续脉冲来移动 void CMotor::MoveByPluse(double PulseCnt,bool bWork) { if(PulseCnt<1) return; if(PulseCnt>0 && PulseCnt<2)//一个脉冲单独处理 { if(MoveOnePluse(GetDelay(bWork))==false) { OnMotorLimit(); CString str = _T("异常,电机限位触发!"); CExceptionMsg Msg; Msg.SetMsg(str); throw Msg; } return; } if(m_bAccelerateCtrl) { MoveByPluseAccelerate(PulseCnt,bWork); } else { MoveByPluseNoAccelerate(PulseCnt,bWork); } } //加减速 void CMotor::MoveByPluseAccelerate(double PulseCnt,bool bWork) { gLogMgr->WriteDebugLog("MoveByPluseAccelerate"); unsigned int MaxDelay = GetDelay(bWork);//最大速度 double AccelerateCnt = (m_StartDelay)/m_PerChangeDelay;//加速脉冲个数 if(AccelerateCnt>(PulseCnt/2))//如果脉冲数过少,值加速到一半的位置 { AccelerateCnt = (PulseCnt/2); } unsigned int CurDelay = MaxDelay+m_StartDelay; for(double PluseIdx=1;PluseIdx<=PulseCnt;PluseIdx+=1) { if(PluseIdx<=AccelerateCnt)//加速阶段 { CurDelay -= m_PerChangeDelay; } else if(PluseIdx>=(PulseCnt-AccelerateCnt))//减速阶段 { CurDelay += m_PerChangeDelay; } if(CurDelayWriteDebugLog("MoveByPluseNoAccelerate"); unsigned int MaxDelay = GetDelay(bWork);//最大速度 for(double PluseIdx=1;PluseIdx<=PulseCnt;PluseIdx+=1) { if(MoveOnePluse(MaxDelay)==false) { OnMotorLimit(); CString str = _T("异常,电机限位触发!"); CExceptionMsg Msg; Msg.SetMsg(str); throw Msg; } } } #endif #if 1 #define MIN_CNT 2//最小移动的脉冲个数 //移动指定距离 void CMotor::MoveDis(double dis) { MoveToCoord(m_Coord+dis); } //移动到坐标值 void CMotor::MoveToCoord(double Coord) { if(gMotionCard_PCI1245->IsbUsed()) { if(gMotionCard_PCI1245->MoveMotor(*this,Coord)) { m_Coord = Coord; } } } #endif