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/MotionCard_PCI1245.cpp

1221 lines
43 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 "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_HomeMode");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_HomeMode);
pPropertie->SetType(_PROP_TYPE_INT);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("Home方式");
Description = _T("调用板卡提供的Home函数时的方式索引(0~15).");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_HomeMode, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = _T("m_bCheckActCoord");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_bCheckActCoord);
pPropertie->SetType(_PROP_TYPE_BOOL);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("检测光栅尺");
Description = _T("是否检测光栅尺的坐标");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_bCheckActCoord, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = _T("m_MaxActCoordErr");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_MaxActCoordErr);
pPropertie->SetType(_PROP_TYPE_DOUBLE);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("光栅尺误差脉冲");
Description = _T("允许最大光栅尺误差脉冲个数");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_MaxActCoordErr, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = _T("m_bAutoCloseSevon");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_bAutoCloseSevon);
pPropertie->SetType(_PROP_TYPE_BOOL);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("退出时关闭sevon");
Description = _T("软件退出时自动关闭所有轴的sevon");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_bAutoCloseSevon, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = _T("m_bArcCut");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_bArcCut);
pPropertie->SetType(_PROP_TYPE_BOOL);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("圆弧插补");
Description = _T("是否使用平台圆弧插补");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_bArcCut, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = _T("m_bGroupAisxRev");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_bGroupAisxRev);
pPropertie->SetType(_PROP_TYPE_BOOL);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("插补轴调换");
Description = _T("如果插补轴运动反向,调换轴顺序");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_bGroupAisxRev, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = _T("m_CheckDelay");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_CheckDelay);
pPropertie->SetType(_PROP_TYPE_INT);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("检测延时");
Description = _T("检测电机运动的延时ms");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_CheckDelay, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = _T("m_MotorXAsixIdx");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_MotorXAsixIdx);
pPropertie->SetType(_PROP_TYPE_INT);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("X 轴编号");
Description = _T("X 轴对应的轴编号");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_MotorXAsixIdx, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = _T("m_MotorX2AsixIdx");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_MotorX2AsixIdx);
pPropertie->SetType(_PROP_TYPE_INT);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("X 2轴编号");
Description = _T("X 2轴对应的轴编号");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_MotorX2AsixIdx, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = _T("m_MotorYAsixIdx");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_MotorYAsixIdx);
pPropertie->SetType(_PROP_TYPE_INT);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("Y 轴编号");
Description = _T("Y 轴对应的轴编号");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_MotorYAsixIdx, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = _T("m_MotorZAsixIdx");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&m_MotorZAsixIdx);
pPropertie->SetType(_PROP_TYPE_INT);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("Z 轴编号");
Description = _T("Z 轴对应的轴编号");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_MotorZAsixIdx, Description);
pGroup->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
if(gAuthorityMgr->CheckAuthority(_FACTORY))
{
CMFCPropertyGridProperty* pGroup1;
pGroup1 = CreatSpeedGridProperty(m_OrgSpeedMotorZ,_T("Z 轴原点速度"),_T("m_OrgSpeedMotorZ"));
pGroup->AddSubItem(pGroup1);
pGroup1 = CreatSpeedGridProperty(m_MoveSpeedMotorZ,_T("Z 轴移动速度"),_T("m_MoveSpeedMotorZ"));
pGroup->AddSubItem(pGroup1);
pGroup1 = CreatSpeedGridProperty(m_OrgSpeedMotorXY,_T("XY 轴原点速度"),_T("m_OrgSpeedMotorXY"));
pGroup->AddSubItem(pGroup1);
pGroup1 = CreatSpeedGridProperty(m_MoveSpeedMotorX,_T("X 轴空移速度"),_T("m_MoveSpeedMotorX"));
pGroup->AddSubItem(pGroup1);
pGroup1 = CreatSpeedGridProperty(m_WorkSpeedMotorX,_T("X 轴工作速度"),_T("m_WorkSpeedMotorX"));
pGroup->AddSubItem(pGroup1);
pGroup1 = CreatSpeedGridProperty(m_MoveSpeedMotorY,_T("Y 轴空移速度"),_T("m_MoveSpeedMotorY"));
pGroup->AddSubItem(pGroup1);
pGroup1 = CreatSpeedGridProperty(m_WorkSpeedMotorY,_T("Y 轴工作速度"),_T("m_WorkSpeedMotorY"));
pGroup->AddSubItem(pGroup1);
}
if(gAuthorityMgr->CheckAuthority(_FACTORY))
{
PropertyName = "下料机保护信号";
CMFCPropertyGridProperty* pGroup1 = new CMFCPropertyGridProperty(PropertyName);
{
//添加属性变量映射
Name = "m_AsixNum";//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&(m_InPortUnload.m_AsixNum));
pPropertie->SetType(_PROP_TYPE_INT);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("轴编号");
Description = _T("用于控制的轴编号(0~3)");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName,(_variant_t)(m_InPortUnload.m_AsixNum), Description);
pGroup1->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = "m_PortNum";//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&(m_InPortUnload.m_PortNum));
pPropertie->SetType(_PROP_TYPE_INT);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("端口号");
Description = _T("用于控制的端口号(0~3)");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName,(_variant_t)m_InPortUnload.m_PortNum, Description);
pGroup1->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = "m_bRev";//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&(m_InPortUnload.m_bRev));
pPropertie->SetType(_PROP_TYPE_BOOL);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("是否反向");
Description = _T("端口控制是否反向");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName,(_variant_t)m_InPortUnload.m_bRev, Description);
pGroup1->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
pGroup->AddSubItem(pGroup1);
}
}
//-------------------------------------------------------------------------------//
return pGroup;
}
CMFCPropertyGridProperty* MotionCard_PCI1245::CreatSpeedGridProperty(PCI1245_SpeedParam &SpeedParam,CString SpeedName,CString ValName)
{
CString PropertyName;//属性名称
CString Description;//描述
CString Path = _T("MotionCard_PCI1245");//存储路径
CString Name;
CMFCPropertyGridProperty* pGroup1 = new CMFCPropertyGridProperty(SpeedName);
{
{
//添加属性变量映射
Name = ValName+_T("_Acc");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&SpeedParam.m_Acc);
pPropertie->SetType(_PROP_TYPE_DOUBLE);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("加速度");
Description = _T("静止到运行速度的加速度(mm/s2)");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)SpeedParam.m_Acc, Description);
pGroup1->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = ValName+_T("_Dec");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&SpeedParam.m_Dec);
pPropertie->SetType(_PROP_TYPE_DOUBLE);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("减速度");
Description = _T("运行速度到静止的减速度(mm/s2)");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)SpeedParam.m_Dec, Description);
pGroup1->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = ValName+_T("_VelLow");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&SpeedParam.m_VelLow);
pPropertie->SetType(_PROP_TYPE_DOUBLE);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("起动速度");
Description = _T("起动速度(mm/s)");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)SpeedParam.m_VelLow, Description);
pGroup1->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
{
//添加属性变量映射
Name = ValName+_T("_VelHigh");//变量名字
CPropertie *pPropertie = new CPropertie;
pPropertie->SetpVal((void*)&SpeedParam.m_VelHigh);
pPropertie->SetType(_PROP_TYPE_DOUBLE);
pPropertie->SetpModule(this);
pPropertie->SetPath(Path);
pPropertie->SetName(Name);
pPropertie->WriteRead(true);//读取保存的属性
//添加属性显示
PropertyName = _T("运行速度");
Description = _T("运行速度(mm/s)");
CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)SpeedParam.m_VelHigh, Description);
pGroup1->AddSubItem(p1);
gDevicePropertieMgr.Insert(p1, pPropertie);
}
}
return pGroup1;
}
void MotionCard_PCI1245::ExportPar(ofstream *pFile)
{
}
#if 1
void MotionCard_PCI1245::Ini()
{
if(!m_bUsed)
return;
CCommPortMgr Comm;
if(!Comm.Open(1,9600))//如果无法操作串口的话说明在笔记本上运行
return;
Comm.Close();
//设置轴的编号-------------------------------------------
CMotor &MotorX = *(CMotor::GetMotor(MOTOR_X));
CMotor &MotorX2 = *(CMotor::GetMotor(MOTOR_X2));
CMotor &MotorY = *(CMotor::GetMotor(MOTOR_Y));
CMotor &MotorZ = *(CMotor::GetMotor(MOTOR_Z));
MotorX.SetAsixIdx(m_MotorXAsixIdx);
MotorX2.SetAsixIdx(m_MotorX2AsixIdx);
MotorY.SetAsixIdx(m_MotorYAsixIdx);
MotorZ.SetAsixIdx(m_MotorZAsixIdx);
//初始化卡
if(!InitCard())
return;
//打开卡并读取支持的轴
if(!OpenCard())
return;
//检查轴的编号是否合法
if(!CheckRange(m_MotorXAsixIdx,0,MAX_ASIX_IDX)
|| !CheckRange(m_MotorX2AsixIdx,0,MAX_ASIX_IDX)
|| !CheckRange(m_MotorYAsixIdx,0,MAX_ASIX_IDX)
|| !CheckRange(m_MotorZAsixIdx,0,MAX_ASIX_IDX)
)
{
gLogMgr->WriteDebugLog("[Error]---->invalid Asix Idx");
return;
}
//读取运动控制卡的参数文件.cfg
LoadConfigFile();
//将绑定XY 轴为一个组(支持线性插补运动)
AddAsixToGroup(m_GpHand,m_MotorXAsixIdx);
AddAsixToGroup(m_GpHand,m_MotorYAsixIdx);
SetCurGpIdx(0);
//自动SvOn
SetSvOn(true);
//启动读取轴状态的线程
AfxBeginThread(CheckAsixStateThread,this);
}
void MotionCard_PCI1245::OnExitApp()
{
if(m_bAutoCloseSevon)
SetSvOn(false);
}
void MotionCard_PCI1245::SetSvOn(bool bOn)
{
gLogMgr->WriteDebugLog("Fuc---->Motion Asix SetSvOn");
for(int k=0;k<=MAX_ASIX_IDX;k++)
{
Acm_AxSetSvOn(m_Axishand[k],bOn);
Sleep(100);
}
}
//初始化运动控制卡
bool MotionCard_PCI1245::InitCard()
{
U32 Result;
ULONG i=0;
ULONG deviceNumber=0;//卡的数量
CString strTemp;
Result = Acm_GetAvailableDevs(m_avaDevs,MAX_DEVICES,&deviceNumber);
if (Result!=SUCCESS || deviceNumber<=0)
{
gLogMgr->WriteDebugLog("[Error]---->Acm_GetAvailableDevs");
return false;
}
m_dwDevNum=m_avaDevs[0].dwDeviceNum;//当前的设备号
gLogMgr->WriteDebugLog("Fuc---->InitMotionCard 1245L Success");
m_bInited = true;//是否被正常初始化
return true;
}
//打开卡
bool MotionCard_PCI1245::OpenCard()
{
U32 Result;
ULONG i=0;
CString strTemp;
CString strString;
ULONG AxisPerDev=0;
ULONG AxisNumber=0;
//打开设备m_dwDevNum ,获得设备句柄m_Devhand
Result = Acm_DevOpen(m_dwDevNum, &m_Devhand);
if (Result != SUCCESS)
{
strString.Format("Open Device Failed With Error Code:%x",Result);
gLogMgr->WriteDebugLog(strString);
return false;
}
//获得设备轴的数量
Result = Acm_GetU32Property(m_Devhand,FT_DevAxesCount,&AxisPerDev);
if (Result!=SUCCESS)
{
strString.Format("Get Device Axes Number Failed With Error Code: %x",Result);
gLogMgr->WriteDebugLog(strString);
return false;
}
m_ulAxisCount=AxisPerDev;
//if you device is fixed,for example: PCI-1245 m_ulAxisCount =4
for(AxisNumber=0;AxisNumber<m_ulAxisCount;AxisNumber++)
{
//打开轴,并获得轴的句柄m_Axishand
Result =Acm_AxOpen(m_Devhand, (USHORT)AxisNumber, &m_Axishand[AxisNumber]);
if(Result != SUCCESS)
{
strString.Format("Open Axis Failed With Error Code: %x",Result);
gLogMgr->WriteDebugLog(strString);
return false;
}
//设置轴的初始坐标为0
Acm_AxSetCmdPosition(m_Axishand[AxisNumber],0);
}
m_bInit = TRUE; //是否打开成功
gLogMgr->WriteDebugLog("Fuc---->OpenCard 1245L Success");
return true;
}
//使用运动控制卡的时候有些功能不能使用
bool MotionCard_PCI1245::CheckFucCanUsed()
{
if(m_bUsed)
{
CMsgBox MsgBox;
MsgBox.Show(_T("使用运动控制卡时不能使用"));
return false;
}
return true;
}
//读取运动控制卡的参数文件.cfg
void MotionCard_PCI1245::LoadConfigFile()
{
CString strTemp;
CFileMgr FileMgr;
FileMgr.GetFullFilePath(strTemp,CFG_FILE_PATH);//获取完整路径
//Set all configurations for the device according to the loaded file
U32 Result;
Result=Acm_DevLoadConfig(m_Devhand,strTemp.GetBuffer(strTemp.GetLength()));
if(Result != SUCCESS)
{
strTemp.Format("Load Config Failed With Error Code: %x",Result);
gLogMgr->WriteDebugLog(strTemp);
return;
}
gLogMgr->WriteDebugLog("Fuc---->LoadConfigFile 1245 Success");
}
#endif
#if 1//组运动
//添加轴到组
bool MotionCard_PCI1245::AddAsixToGroup(HAND &GpHand,UINT index)
{
U32 Result;
CString strTemp;
Result = Acm_GpAddAxis(&GpHand,m_Axishand[index]);
if (Result!=SUCCESS)
{
strTemp.Format("Add Axis To Group Failed With Error Code: %x",Result);
gLogMgr->WriteDebugLog(strTemp);
return false;
}
CString LogStr;
LogStr.Format(_T("AddAsixToGroup [Asix index] = [%d]"),index);
gLogMgr->WriteDebugLog(LogStr);
return true;
}
//设置当前的组编号
void MotionCard_PCI1245::SetCurGpIdx(int idx)
{
CString LogStr;
LogStr.Format(_T("SetCurGpIdx [index] = [%d]"),idx);
gLogMgr->WriteDebugLog(LogStr);
m_CurGpIdx = idx;
gPlatformXY->SetCoord(GetPlatformXYCoord());
}
void MotionCard_PCI1245::ResetAllAsixCoord()
{
gLogMgr->WriteDebugLog("ResetAllAsixCoord");
Acm_AxSetCmdPosition(m_Axishand[m_MotorXAsixIdx],0);
Acm_AxSetCmdPosition(m_Axishand[m_MotorX2AsixIdx],0);
Acm_AxSetCmdPosition(m_Axishand[m_MotorYAsixIdx],0);
Acm_AxSetCmdPosition(m_Axishand[m_MotorZAsixIdx],0);
//同时设置光栅尺的坐标
Acm_AxSetActualPosition(m_Axishand[m_MotorXAsixIdx],0);
Acm_AxSetActualPosition(m_Axishand[m_MotorX2AsixIdx],0);
Acm_AxSetActualPosition(m_Axishand[m_MotorYAsixIdx],0);
//通知观察者平台坐标变化了
gPlatformXY->NotifyObservers();
}
//从运动控制卡读取平台当前的坐标
Dbxy MotionCard_PCI1245::GetPlatformXYCoord()
{
if (gLogMgr->IsDebuging())
{
return gLogMgr->LastTargetCoord;
}
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("***[Move To]===>Coord x : %f,Coord y : %f", Coord.x,Coord.y);
if (gLogMgr->IsDebuging())
{
gLogMgr->LastTargetCoord = Coord;
}
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 = m_HomeMode%16;
//U32 HomeMode = 6;//找原点的模式(如果在原点上,先反向移出原点再找)
U32 DirMode = (Motor.GetFindOriginDir())?1:0;//找原点方向
Acm_AxHome(m_Axishand[AsixIdx],HomeMode,DirMode);
//等待找原点完成
int TotalTimes = 0;
while(1)
{
TotalTimes++;
if((TotalTimes*m_CheckDelay)>30000)//防止死循环
{
CString str;
str.Format("轴%d寻找原点超时.", AsixIdx);
AfxMessageBox(str);
return false;
}
Sleep(m_CheckDelay);
//Get the Group's current state
U16 GpState;
Acm_AxGetState(m_Axishand[AsixIdx],&GpState);
if(GpState== STA_AX_HOMING)//STA_AxReady轴已准备就绪等待新的命令
{
break;
}
}
Sleep(100); //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 = abs(CmdCoord)-abs(ActualCoord);
if(fabs(ActPluseErrCnt)>m_MaxActCoordErr)
{
return false;
}
return true;
}
#endif