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.
TwoLaserHead-PushJig/LaiPuLaser/PlatformXY.cpp

1087 lines
38 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "StdAfx.h"
#include "PlatformXY.h"
#include "LogMgr.h"
#include "PciPortMgr.h"
#include "Propertie.h"
#include "PropertieMgr.h"
#include "AuthorityMgr.h"
#include "GlobalDrawMgr.h"
#include "DrawSimpleShape.h"
#include "ExceptionMsg.h"
#include "ObjComponentMgr.h"
#include "DeviceState.h"
#include "WorkCmdMovePlatformXY.h"
#include "MsgBox.h"
#include "WorkCmdInvoker.h"
#include "MotionCard_PCI1245.h"
#include "WorkCmdSetMotorSpeed.h"
#include "WorkCmdWaitMotorStop.h"
#include "WorkCmdMoveMotor.h"
#include "Program_SZ_XL.h"
//电机速度校准文件
#define MOTOR_SPEED_FILE_X _T("\\Parameter\\PlatformXY\\MotorSpeedX.txt")
#define MOTOR_SPEED_FILE_Y _T("\\Parameter\\PlatformXY\\MotorSpeedY.txt")
CPlatformXY *gPlatformXY = NULL;
CPlatformXY::CPlatformXY(CMotor &MotorX,CMotor &MotorY)
:m_MotorX(MotorX),m_MotorY(MotorY)
{
m_bBresenhamAlgorithm = false;//是否使用直线算法来移动
m_bUsed = false;//是否使用平台
m_MaxDisL = 0;//左边最大行程
m_MaxDisR = 0;//右边最大行程
m_MaxDisU = 0;//上边最大行程
m_MaxDisD = 0;//下边最大行程
m_MoveDelay = 200;//平台移动延时us
m_MoveOrder = 0;
m_bSpeedCtrl = false;//是否使用平台运动速度控制(mm/s)
m_WorkSpeed = 40;//加工速度(mm/s)
m_MoveSpeed = 40;//空移速度(mm/s)
m_MoveNeedDeviceIni = true;//是否需要设备初始化后才能手动移动
m_XY_Angle = 0;//XY 轴的夹角(360 度角)
m_bMoveToRealCoord = false;//是否移动到实际的坐标位置,应对平台有安装角度的情况
m_bUseMoveRange = true;//是否使用范围限制
m_MaxMoveDis = 10;//一次最大的移动距离
m_bUseManualMoveDis = true;//是否使用手调整量
m_MaxManualMoveDis =5;//最大的手动移动量(在这个正负范围之内)
m_InitMotorX = true;//是否初始化X 轴
m_InitMotorY = true;//是否初始化Y 轴
m_bLockManualMoveDis = false;//锁定手动微调值
m_UserMaxMoveDis = 5;//操作员一次最大的移动距离mm
}
CPlatformXY::~CPlatformXY(void)
{
}
#if 1
CMFCPropertyGridProperty *CPlatformXY::CreatGridProperty()
{
CString PropertyName;//属性名称
CString Description;//描述
CString Path = _T("PlatformXY");//存储路径
CString Name;
//-------------------------------------------------------------------------------//
PropertyName = _T("平台");
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_MoveNeedDeviceIni");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_MoveNeedDeviceIni);
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_MoveNeedDeviceIni, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = _T("m_InitMotorX");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_InitMotorX);
pPropertie->SetType(_PROP_TYPE_BOOL);
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_InitMotorX, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = _T("m_InitMotorY");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_InitMotorY);
pPropertie->SetType(_PROP_TYPE_BOOL);
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_InitMotorY, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
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* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_MoveDelay, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = _T("m_bBresenhamAlgorithm");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_bBresenhamAlgorithm);
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_bBresenhamAlgorithm, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = _T("m_ProductPoint_x");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_ProductPoint.x);
pPropertie->SetType(_PROP_TYPE_DOUBLE);
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_ProductPoint.x, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = _T("m_ProductPoint_y");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_ProductPoint.y);
pPropertie->SetType(_PROP_TYPE_DOUBLE);
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_ProductPoint.y, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = _T("m_bMoveToRealCoord");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_bMoveToRealCoord);
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_bMoveToRealCoord, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = _T("m_XY_Angle");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_XY_Angle);
pPropertie->SetType(_PROP_TYPE_DOUBLE);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("XY 轴夹角");
Description = _T("电机XY 轴的夹角(360 度角)");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_XY_Angle, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = _T("m_bUseManualMoveDis");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_bUseManualMoveDis);
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_bUseManualMoveDis, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = _T("m_MaxManualMoveDis");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_MaxManualMoveDis);
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_MaxManualMoveDis, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
}
{
CMFCPropertyGridProperty* pGroup1 = new CMFCPropertyGridProperty(_T("平台范围"));
if(gAuthorityMgr->CheckAuthority(_FACTORY))
{
//添加属性变量映射
Name = _T("m_MaxMoveDis");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_MaxMoveDis);
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_MaxMoveDis, Description);
pGroup1->AddSubItem(p);
gDevicePropertieMgr.Insert(p, pPropertie);
}
if(gAuthorityMgr->CheckAuthority(_FACTORY))
{
//添加属性变量映射
Name = _T("m_UserMaxMoveDis");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_UserMaxMoveDis);
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_UserMaxMoveDis, Description);
pGroup1->AddSubItem(p);
gDevicePropertieMgr.Insert(p, pPropertie);
}
if(gAuthorityMgr->CheckAuthority(_FACTORY))
{
//添加属性变量映射
Name = _T("m_bUseMoveRange");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_bUseMoveRange);
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_bUseMoveRange, Description);
pGroup1->AddSubItem(p);
gDevicePropertieMgr.Insert(p, pPropertie);
}
if(gAuthorityMgr->CheckAuthority(_FACTORY))
{
//添加属性变量映射
Name = _T("m_MaxDisL");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_MaxDisL);
pPropertie->SetType(_PROP_TYPE_DOUBLE);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("左边最大行程");
Description = _T("从原点位置开始X 轴左边最大行程");
CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_MaxDisL, Description);
pGroup1->AddSubItem(p);
gDevicePropertieMgr.Insert(p, pPropertie);
}
if(gAuthorityMgr->CheckAuthority(_FACTORY))
{
//添加属性变量映射
Name = _T("m_MaxDisR");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_MaxDisR);
pPropertie->SetType(_PROP_TYPE_DOUBLE);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("右边最大行程");
Description = _T("从原点位置开始X 轴右边最大行程");
CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_MaxDisR, Description);
pGroup1->AddSubItem(p);
gDevicePropertieMgr.Insert(p, pPropertie);
}
if(gAuthorityMgr->CheckAuthority(_FACTORY))
{
//添加属性变量映射
Name = _T("m_MaxDisU");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_MaxDisU);
pPropertie->SetType(_PROP_TYPE_DOUBLE);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("上边最大行程");
Description = _T("从原点位置开始Y 轴上边最大行程");
CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_MaxDisU, Description);
pGroup1->AddSubItem(p);
gDevicePropertieMgr.Insert(p, pPropertie);
}
if(gAuthorityMgr->CheckAuthority(_FACTORY))
{
//添加属性变量映射
Name = _T("m_MaxDisD");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_MaxDisD);
pPropertie->SetType(_PROP_TYPE_DOUBLE);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("下边最大行程");
Description = _T("从原点位置开始Y 轴下边最大行程");
CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_MaxDisD, Description);
pGroup1->AddSubItem(p);
gDevicePropertieMgr.Insert(p, pPropertie);
}
pGroup->AddSubItem(pGroup1);
}
{
CMFCPropertyGridProperty* pGroup1 = new CMFCPropertyGridProperty(_T("运动速度"));
if(gAuthorityMgr->CheckAuthority(_FACTORY))
{
//添加属性变量映射
Name = _T("m_bSpeedCtrl");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_bSpeedCtrl);
pPropertie->SetType(_PROP_TYPE_BOOL);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("mm/s 方式");
Description = _T("是否使用平台运动速度控制(mm/s)");
CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_bSpeedCtrl, Description);
pGroup1->AddSubItem(p);
gDevicePropertieMgr.Insert(p, pPropertie);
}
if(gAuthorityMgr->CheckAuthority(_FACTORY))
{
//添加属性变量映射
Name = _T("m_WorkSpeed");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_WorkSpeed);
pPropertie->SetType(_PROP_TYPE_DOUBLE);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("加工速度");
Description = _T("加工速度(mm/s)");
CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_WorkSpeed, Description);
pGroup1->AddSubItem(p);
gDevicePropertieMgr.Insert(p, pPropertie);
}
if(gAuthorityMgr->CheckAuthority(_FACTORY))
{
//添加属性变量映射
Name = _T("m_MoveSpeed");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_MoveSpeed);
pPropertie->SetType(_PROP_TYPE_DOUBLE);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("空移速度");
Description = _T("空移速度(mm/s)");
CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_MoveSpeed, Description);
pGroup1->AddSubItem(p);
gDevicePropertieMgr.Insert(p, pPropertie);
}
pGroup->AddSubItem(pGroup1);
}
//-------------------------------------------------------------------------------//
return pGroup;
}
void CPlatformXY::ExportPar(ofstream *pFile)
{
(*pFile)<<"[模块] [CPlatformXY]------------------------------------------------"<<endl;
(*pFile)<<"[取料点X][m_ProductPoint.x] = "<<m_ProductPoint.x<<endl;
(*pFile)<<"[取料点Y][m_ProductPoint.y] = "<<m_ProductPoint.y<<endl;
}
//获取平台范围
DbRect CPlatformXY::GetRect()
{
return DbRect(m_MaxDisL*(-1),m_MaxDisR,m_MaxDisU,m_MaxDisD*(-1));
}
void CPlatformXY::Draw(CDC* pDC)
{
if(gDraw->IsShowPlatformPos())
{
DrawRect(pDC,gDraw->GetSelObjectPen(),GetRect(),false);
}
}
#endif
#if 1
void CPlatformXY::WriteWorkFileExt(vector<CLab> &LabVec)
{
//读取也要按照这个顺序
LabVec.push_back(CLab(LAB_NULL,m_WorkSpeed));//加工速度
LabVec.push_back(CLab(LAB_NULL,m_MoveSpeed));//空移速度
}
void CPlatformXY::ReadWorkFile(CLabVecRang &LabVecRang)
{
int idx = LabVecRang.GetStart()+1;
m_WorkSpeed = LabVecRang.GetDouble(idx++);
m_MoveSpeed = LabVecRang.GetDouble(idx++);
AdjustPlatformSpeed();
}
#endif
Dbxy CPlatformXY::GetCoord()
{
return gMotionCard_PCI1245->GetPlatformXYCoord();
}
//校准平台的运动速度
void CPlatformXY::AdjustPlatformSpeed()
{
}
//计算脉冲个数,结果保存到PulseCntX 和PulseCntY 并且保存当前坐标
//为了避免累计误差,脉冲个数应该用脉冲坐标来计算
//MovePt 和TargetPt 都是相对于平台原点的坐标
void CPlatformXY::CalPulseCntAndSaveCoord(Dbxy MovePt,Dbxy TargetPt,double &PulseCntX,double &PulseCntY,bool bSaveCoord)
{
Dbxy Coord = GetCoord();
double OnePulseDisX = m_MotorX.GetOnePulseDis();
double OnePulseDisY = m_MotorY.GetOnePulseDis();
//计算发送脉冲个数,有正负的区分
double CntX = (TargetPt.x - (MovePt.x+Coord.x))/OnePulseDisX;
double CntY = (TargetPt.y - (MovePt.y+Coord.y))/OnePulseDisY;
PulseCntX = (abs(CntX));//向下取整
PulseCntY = (abs(CntY));
//保存当前坐标------------------------------------------------------------------------
/*注意是应该加上实际的移动距离,
TargetPt 只是目的坐标但是不一定能准确的移动到TargetPt 的位置上*/
double ValX = abs(CntX);
if(CntX>=1)//floor函数对负数不起作用
{
Coord.x += (floor(ValX)*OnePulseDisX);
}
else if(CntX<=-1)
{
Coord.x -= (floor(ValX)*OnePulseDisX);
}
double ValY = abs(CntY);
if(CntY>=1)//floor函数对负数不起作用
{
Coord.y += (floor(ValY)*OnePulseDisY);
}
else if(CntY<=-1)
{
Coord.y -= (floor(ValY)*OnePulseDisY);
}
//检查新坐标的安全性------------------------------------------
if(m_bUseMoveRange && IsPointInRect(Coord,GetRect())==false)
{
CString str = _T("电机不能移动到安全范围外!");
CExceptionMsg Msg;
Msg.SetMsg(str);
throw Msg;
}
//设置新的坐标
if(bSaveCoord)//因为平台补偿的是否不需要记录坐标值
{
SetCoord(Coord);
}
}
//记录坐标(通过脉冲个数移动平台时)
void CPlatformXY::SaveCoord(int PulseCntX,int PulseCntY)
{
Dbxy Coord = GetCoord();
double OnePulseDisX = m_MotorX.GetOnePulseDis();
double OnePulseDisY = m_MotorY.GetOnePulseDis();
Coord.x += (PulseCntX*OnePulseDisX);
Coord.y += (PulseCntY*OnePulseDisY);
SetCoord(Coord);
}
//平台移动的Bresenham 算法(移动距离长的轴每次动一个脉冲,短的轴每次是否发送脉冲根据斜率来确定)
//MotorX 代表发送脉冲多的轴
//只管发脉冲,不管方向
bool CPlatformXY::MoveBresenhamAlgorithm(bool bWork,CMotor &MotorX,double PulseCntX,CMotor &MotorY,double PulseCntY)
{
double error = 2*PulseCntY - PulseCntX;
bool bSendY = false;
int TallyY = 0;//统计Y 的个数(只有Y 可能有误差)
for(double i=0;i<PulseCntX;i++)
{
if(MotorX.MoveOnePluse(MotorX.GetDelay(bWork))==false)
{
return false;//撞到限位
}
if(bSendY)
{
if(MotorY.MoveOnePluse(MotorY.GetDelay(bWork))==false)
{
return false;//撞到限位
}
bSendY = false;
TallyY++;
}
if(error>=0)
{
bSendY = true;
error = error - 2*PulseCntX;
}
error = error +2*PulseCntY;
}
//x 发送数量肯定是准的
//Y 的数量由于计算误差可能会少一个
if(TallyY<PulseCntY)
{
CString str = "[Bresenham 算法脉冲补偿]";
gLogMgr->WriteDebugLog(str);
if(MotorY.MoveOnePluse(MotorY.GetDelay(bWork))==false)
{
return false;//撞到限位
}
}
return true;
}
//移动指定的距离(dis 的单位是毫米)
bool CPlatformXY::MoveDistance(double dis,DIRECTION dir,bool bSaveCoord)
{
//获取当前坐标
Dbxy MovePt = GetCoord();
Dbxy TargetPt;
switch(dir)
{
case _DIR_L:
MovePt.x -= dis;
break;
case _DIR_R:
MovePt.x += dis;
break;
case _DIR_U:
MovePt.y += dis;
break;
case _DIR_D:
MovePt.y -= dis;
break;
default:
return true;
break;
}
return Move(false,TargetPt,MovePt,bSaveCoord);
}
//移动指定的脉冲个数(不记录坐标)
bool CPlatformXY::MovePulseCnt(int Cnt,DIRECTION dir)
{
if(Cnt<=0)
return true;
//设置方向
SetMoveDir(dir);
int PulseCntX = 0;
int PulseCntY = 0;
switch(dir)
{
case _DIR_L:
PulseCntX = Cnt*(-1);
break;
case _DIR_R:
PulseCntX = Cnt;
break;
case _DIR_U:
PulseCntY = Cnt;
break;
case _DIR_D:
PulseCntY = Cnt*(-1);
break;
default:
break;
}
if(PulseCntX<0)
{
PulseCntX *= -1;
}
if(PulseCntY<0)
{
PulseCntY *= -1;
}
//平台移动
m_MotorX.MoveByPluse((double)PulseCntX,false);
m_MotorY.MoveByPluse((double)PulseCntY,false);
return true;
}
void CPlatformXY::SetMoveDir(DIRECTION dir)
{
switch(dir)
{
case _DIR_L:
m_MotorX.SetDir(false);
break;
case _DIR_R:
m_MotorX.SetDir(true);
break;
case _DIR_U:
m_MotorY.SetDir(true);
break;
case _DIR_D:
m_MotorY.SetDir(false);
break;
default:
return;
break;
}
}
//根据移动点来设置移动的方向
void CPlatformXY::SetMoveDir(Dbxy MovePt,Dbxy TargetPt)
{
Dbxy Coord = GetCoord();
bool bDirX = false;//负向
bool bDirY = false;//负向
if((TargetPt.x - (MovePt.x+Coord.x))>0)
{
bDirX = true;
}
if((TargetPt.y - (MovePt.y+Coord.y))>0)
{
bDirY = true;
}
if(!gLogMgr->IsDebuging())//调试状态
{
m_MotorX.SetDir(bDirX);
m_MotorY.SetDir(bDirY);
}
}
//理论坐标系的坐标pt 转换为平台的实际坐标
Dbxy CPlatformXY::TheoryCoor2RealCoord(Dbxy pt)
{
double Angle = _360ToAngle(m_XY_Angle);
Dbxy CenterPt(0,0);//相对于平台的坐标原点
Dbxy RealPt = RotatoPt(pt,Angle,CenterPt);
return RealPt;
}
//移动MovePt 点到TargetPt 点(bSaveCoord 表示是否要记录移动的坐标(默认是要记录的))
//MovePt 和TargetPt都是相对于平台原点的坐标值
//bWork 表示工作或者空移
bool CPlatformXY::Move(bool bWork,Dbxy MovePt,Dbxy TargetPt,bool bSaveCoord)
{
if(!m_bUsed)
return true;
//移动前
OnPlatformMoveStart();
//按实际位置移动
if(m_bMoveToRealCoord)
{
//MovePt 和TargetPt 都是理论坐标系的坐标
//当平台有角度时平台移动的位置会有偏移
//理论坐标系的坐标pt 转换为平台的实际坐标
MovePt = TheoryCoor2RealCoord(MovePt);
TargetPt = TheoryCoor2RealCoord(TargetPt);
}
//使用研华运动控制卡控制平台
if(gMotionCard_PCI1245->IsbUsed())
{
Dbxy Coord = GetTargetCoord(MovePt,TargetPt);//平台的目标坐标点
//检查坐标的安全性(抛出异常)
CheckCoordRange(Coord);
Coord = gMotionCard_PCI1245->MovePlatformXY(Coord);
#if 0
//设置新的坐标
if(bSaveCoord)//因为平台补偿的是否不需要记录坐标值
{
m_Coord = Coord;
//通知观察者平台坐标变化了
NotifyObservers();
}
#endif
}
OnPlatformMoveEnd();
return true;
}
//设置当前位置为平台的坐标原点
void CPlatformXY::SetCurPosOrigin()
{
Dbxy pt(0,0);
gMotionCard_PCI1245->SetCurGpIdx(0);
SetCoord(pt);
//切换组再设置一次
gMotionCard_PCI1245->SetCurGpIdx(1);
SetCoord(pt);
CString str1 = _T("[func][SetCurPosOrigin] [设置当前位置为工作原点]");
gLogMgr->WriteDebugLog(str1);
}
Dbxy CPlatformXY::GetTargetCoord(Dbxy MovePt,Dbxy TargetPt)
{
Dbxy Coord;//平台的目标坐标点
Coord.x = TargetPt.x - MovePt.x;
#ifdef __CUSTOM_SW_XL__
Coord.y = MovePt.y -TargetPt.y;
#else
Coord.y = TargetPt.y - MovePt.y;
#endif
return Coord;
}
//检查坐标的安全性(抛出异常)
void CPlatformXY::CheckCoordRange(Dbxy Coord)
{
//检查新坐标的安全性------------------------------------------
if(m_bUseMoveRange && IsPointInRect(Coord,GetRect())==false)
{
CString str = _T("电机不能移动到安全范围外!");
CExceptionMsg Msg;
Msg.SetMsg(str);
throw Msg;
}
}
//设置新的坐标
void CPlatformXY::SetCoord(Dbxy pt)
{
m_Coord = pt;
gMotionCard_PCI1245->SetCoord(pt);
//通知观察者平台坐标变化了
NotifyObservers();
}
//移动到指定坐标
void CPlatformXY::MoveToPt(Dbxy MovePt,Dbxy TargetPt)
{
gLogMgr->WriteDebugLog("MovePt.x","",MovePt.x);
gLogMgr->WriteDebugLog("MovePt.y","",MovePt.y);
Move(false,MovePt,TargetPt);
}
//手动步进移动平台
void CPlatformXY::ManualMovePlatForm(bool bMoveByDis,double MoveDis,DIRECTION MoveDir)
{
//自动运行中禁止移动
if(gProgram_SZ_XL->IsbAutoWorking())
return;
//非厂家权限限制移动距离
if(gAuthorityMgr->CheckAuthority(_FACTORY,false)==false)
{
if(fabs(MoveDis)>m_UserMaxMoveDis)
{
CString s;
s.Format("一次只能移动%.3f",m_UserMaxMoveDis);
CMsgBox MsgBox;
MsgBox.Show(s);
return;
}
}
CDeviceState &DeviceState = CDeviceState::GetInstance();
bool IniState = DeviceState.IsDeviceIni();
DeviceState.SetIniState(true);//强制初始化成功
//需要初始化后才能移动平台
if(IsMoveNeedDeviceIni())
{
if(DeviceState.IsDeviceIni()==false)
{
CMsgBox MsgBox;
MsgBox.Show("设备未初始化!");
return;
}
}
if(bMoveByDis)
{
double Max = m_MaxMoveDis;//一次最大移动距离
if(MoveDis>Max)
{
CMsgBox MsgBox;
CString str;
str.Format(_T("每次最多只能移动%f (mm)"),Max);
MsgBox.Show(str);
return;
}
}
CWorkCmdContainer CmdContainer;
//设置电机速度
{
CWorkCmdSetMotorSpeed *pCmd = new CWorkCmdSetMotorSpeed();
pCmd->SetbSetMotorX();
pCmd->SetbSetMotorX2();
pCmd->SetbSetMotorY();
pCmd->SetSpeedType(_SpeedType_Move);
CmdContainer.AddCmd(pCmd);
}
//移动
{
CMotor *pMotor = CMotor::GetMotor(MOTOR_Y);
if(MoveDir == _DIR_L ||MoveDir == _DIR_R )
{
if(gMotionCard_PCI1245->GetCurGpIdx()==0)
pMotor = CMotor::GetMotor(MOTOR_X);
else
pMotor = CMotor::GetMotor(MOTOR_X2);
}
if(MoveDir == _DIR_L || MoveDir == _DIR_D)
MoveDis *= (-1);
CWorkCmdMoveMotor *pCmd = new CWorkCmdMoveMotor(*pMotor,MoveDis);
pCmd->SetMoveFlg(true);//按距离移动
CmdContainer.AddCmd(pCmd);
}
//等待移动结束
{
CWorkCmdWaitMotorStop *pCmd = new CWorkCmdWaitMotorStop();
if(MoveDir == _DIR_L ||MoveDir == _DIR_R )
{
if(gMotionCard_PCI1245->GetCurGpIdx()==0)
pCmd->SetbWaitMotorX();
else
pCmd->SetbWaitMotorX2();
}
else
{
pCmd->SetbWaitMotorY();
}
CmdContainer.AddCmd(pCmd);
}
CWorkCmdInvoker WorkInvoker;//工作调度者
WorkInvoker.Excute(CmdContainer);
//通知观察者平台坐标变化了
NotifyObservers();
DeviceState.SetIniState(IniState);//恢复初始化状态
}
//平台是否在取料点上
bool CPlatformXY::IsAtProductPoint()
{
return (m_ProductPoint==m_Coord);
}
//设置当前点为取料点
void CPlatformXY::SetCurPosAsProductPt()
{
CMsgBox MsgBox;
if(MsgBox.ConfirmOkCancel("设置当前点为取料点?"))
{
m_ProductPoint = m_Coord;
gLogMgr->WriteDebugLog("Fuc---->SetCurPosAsProductPt");
}
}
//移动到取料点
void CPlatformXY::MoveToWorkPt()
{
CDeviceState &DeviceState = CDeviceState::GetInstance();
if(!DeviceState.CheckInitState())
return;
vector<CString> CmdVec;
CmdVec.push_back(_T("CmdName[CMD_PLATFORM_MOVE] Par1[TO_WORK_PT]"));
CWorkCmdInvoker Invoker;
Invoker.ExcuteCmd(CmdVec);
}
void CPlatformXY::MoveToOriginPt()
{
CDeviceState &DeviceState = CDeviceState::GetInstance();
if(!DeviceState.CheckInitState())
return;
vector<CString> CmdVec;
CmdVec.push_back(_T("CmdName[CMD_PLATFORM_MOVE] Par1[TO_ORIGIN]"));
CWorkCmdInvoker Invoker;
Invoker.ExcuteCmd(CmdVec);
}
//初始化平台(bConfirm 表示是否弹出提示)
void CPlatformXY::IniPlat(bool bConfirm)
{
if(bConfirm)
{
CMsgBox MsgBox;
if(MsgBox.ConfirmOkCancel(_T("初始化平台?"))==false)
return;
}
OnPlatformMoveStart();
vector<CString> CmdVec;
if(m_InitMotorX)
{
CmdVec.push_back(_T("CmdName[CMD_MOTOR_TO_MACHINE_ORIGIN] Par1[X]"));
}
if(m_InitMotorY)
{
CmdVec.push_back(_T("CmdName[CMD_MOTOR_TO_MACHINE_ORIGIN] Par1[Y]"));
CmdVec.push_back(_T("CmdName[CMD_MOTOR_TO_OFFSET_POS] Par1[Y]"));
}
if(m_InitMotorX)
{
CmdVec.push_back(_T("CmdName[CMD_MOTOR_TO_OFFSET_POS] Par1[X]"));
}
CmdVec.push_back(_T("CmdName[CMD_DEVICE_PAR_RESET]"));
CWorkCmdInvoker Invoker;
Invoker.ExcuteCmd(CmdVec);
OnPlatformMoveEnd();
}
//移动平台之前的操作(主要是要停掉占cpu 的工作)
void CPlatformXY::OnPlatformMoveStart()
{
}
void CPlatformXY::OnPlatformMoveEnd()
{
}
#if 1
//重置手动微调量
void CPlatformXY::ResetManualMoveDis()
{
m_ManualMoveDis.x = m_ManualMoveDis.y = 0;
}
//记录手动移动量
void CPlatformXY::SaveManualMoveDis(double MoveDis,DIRECTION MoveDir)
{
if(m_bLockManualMoveDis)//锁定状态
return;
switch(MoveDir)
{
case _DIR_L:
m_ManualMoveDis.x -= MoveDis;
break;
case _DIR_R:
m_ManualMoveDis.x += MoveDis;
break;
case _DIR_U:
m_ManualMoveDis.y += MoveDis;
break;
case _DIR_D:
m_ManualMoveDis.y -= MoveDis;
break;
default:
return;
break;
}
//保证在限定范围之内
if(m_ManualMoveDis.x>m_MaxManualMoveDis)
m_ManualMoveDis.x = m_MaxManualMoveDis;
else if(m_ManualMoveDis.x < m_MaxManualMoveDis*(-1))
m_ManualMoveDis.x = m_MaxManualMoveDis*(-1);
if(m_ManualMoveDis.y>m_MaxManualMoveDis)
m_ManualMoveDis.y = m_MaxManualMoveDis;
else if(m_ManualMoveDis.y < m_MaxManualMoveDis*(-1))
m_ManualMoveDis.y = m_MaxManualMoveDis*(-1);
}
#endif
//获取XY 轴一个像素移动的距离
Dbxy CPlatformXY::GetMotorXYOnePulseDis()
{
Dbxy MotorXYOnePulseDis;
MotorXYOnePulseDis.x = m_MotorX.GetOnePulseDis();
MotorXYOnePulseDis.y = m_MotorY.GetOnePulseDis();
return MotorXYOnePulseDis;
}