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.

770 lines
28 KiB
C++

#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(CurDelay<MaxDelay)//避免大于最大速度
{
CurDelay = MaxDelay;
}
if(MoveOnePluse(CurDelay)==false)
{
OnMotorLimit();
CString str = _T("异常,电机限位触发!");
CExceptionMsg Msg;
Msg.SetMsg(str);
throw Msg;
}
}
}
//匀速
void CMotor::MoveByPluseNoAccelerate(double PulseCnt,bool bWork)
{
gLogMgr->WriteDebugLog("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