软件学习记录:(10) 雷赛运动控制卡
(一)定长运动控制
-
需求分析:
-
设置XYZ某一个轴运动定长位移
-
设置轴归零。
-
-
功能设计:
定长位移流程:1.检测板卡是否上线。2.设置轴运动
-
具体实现:
(1)轴定长运动
调用方式:
if (JOGMotionCheck()) { CommonMotion(XAxis, 1); }
先进行板卡是否在线的检测
private bool JOGMotionCheck() { if (!IsCardExit) { AddLog(1, "板卡不存在,无法进行定长运动"); return false; } if (AutoMode) { AddLog(1, "自动模式下,无法进行定长运动"); return false; } return true; }
传入轴号与数值(正方向为1,负方向为-1),这里的运动使用的是S形速度曲线运动模式
private void CommonMotion(ushort axis, int direction)
{
//获取设置的参数值
double MinVel = Convert.ToDouble(num_MinVel.Value);
double MaxVel = Convert.ToDouble(num_MaxVel.Value);
double Tac = Convert.ToDouble(num_Tac.Value);
double STac = Convert.ToDouble(num_STac.Value);
short Distance = Convert.ToInt16(num_Dist.Value);
Dmc2410.d2410_set_st_profile(axis, MinVel, MaxVel, Tac, Tac, STac, STac);
Dmc2410.d2410_s_pmove(axis, Distance * direction, 0);
}
(2)轴归零运动
- 先高速反向到限位。
- 再高速正向到达零点附近
- 最后反向低速找零点
private bool HomeProcess()
{
//第一步:运动轴朝负方向运动,使用速度控制或定长运动(要使用较长的位移距离,保证能到达负限位)
//Z轴脉冲清零
Dmc2410.d2410_set_position(ZAxis, 0);
Dmc2410.d2410_set_st_profile(ZAxis, objConfig.VelMin, objConfig.VelMax, objConfig.Tac, objConfig.Tac, objConfig.STac, objConfig.STac);
Dmc2410.d2410_s_vmove(ZAxis, 0);
while (Dmc2410.d2410_check_done(ZAxis) == 0)
{
long position = Dmc2410.d2410_get_position(ZAxis);
if (position < -1 * this.pCurveMonitor.MaxZAxis)
{
//当位置超限时,停止轴运动
Dmc2410.d2410_decel_stop(ZAxis, 0.1);
AddLog(2, "Z轴异常,请检查!");
return false;
}
}
//第二步:再朝正方向运动一定距离,保证刚好通过原点感应器
Dmc2410.d2410_set_position(ZAxis, 0);
Dmc2410.d2410_set_st_profile(ZAxis, objConfig.VelMin, objConfig.VelMax, objConfig.Tac, objConfig.Tac, objConfig.STac, objConfig.STac);
Dmc2410.d2410_s_pmove(ZAxis, objConfig.ZAxisPosition, 0);
while (Dmc2410.d2410_check_done(ZAxis) == 0)
{
long position = Dmc2410.d2410_get_position(ZAxis);
if (position > this.pCurveMonitor.MaxZAxis)
{
//当位置超限时,停止轴运动
Dmc2410.d2410_decel_stop(ZAxis, 0.1);
AddLog(2, "Z轴异常,请检查!");
return false;
}
}
//第三步:再朝负方向低速找原点
Dmc2410.d2410_set_HOME_pin_logic(ZAxis, 0, 1);
Dmc2410.d2410_config_home_mode(ZAxis, 0, 0);
Dmc2410.d2410_home_move(ZAxis, 2, 0);
while (Dmc2410.d2410_check_done(ZAxis) == 0)
{
long position = Dmc2410.d2410_get_position(ZAxis);
if (position < -1 * this.pCurveMonitor.MaxZAxis)
{
//当位置超限时,停止轴运动
Dmc2410.d2410_decel_stop(ZAxis, 0.1);
AddLog(2, "Z轴异常,请检查!");
return false;
}
}
Dmc2410.d2410_set_position(ZAxis, 0);
#endregion
#region 复位XY轴
//第一步:运动轴朝负方向运动,使用速度控制或定长运动(要使用较长的位移距离,保证能到达负限位)
Dmc2410.d2410_set_position(XAxis, 0);
Dmc2410.d2410_set_position(YAxis, 0);
Dmc2410.d2410_set_st_profile(XAxis, objConfig.VelMin, objConfig.VelMax, objConfig.Tac, objConfig.Tac, objConfig.STac, objConfig.STac);
Dmc2410.d2410_set_st_profile(YAxis, objConfig.VelMin, objConfig.VelMax, objConfig.Tac, objConfig.Tac, objConfig.STac, objConfig.STac);
Dmc2410.d2410_s_vmove(XAxis, 0);
Dmc2410.d2410_s_vmove(YAxis, 0);
while (Dmc2410.d2410_check_done(XAxis) == 0 || Dmc2410.d2410_check_done(YAxis) == 0)
{
long positionX = Dmc2410.d2410_get_position(XAxis);
long positionY = Dmc2410.d2410_get_position(YAxis);
if (positionX < -1 * this.pCurveMonitor.MaxXAxis)
{
//当位置超限时,停止轴运动
Dmc2410.d2410_decel_stop(XAxis, 0.1);
AddLog(2, "X轴异常,请检查!");
return false;
}
if (positionY < -1 * this.pCurveMonitor.MaxYAxis)
{
//当位置超限时,停止轴运动
Dmc2410.d2410_decel_stop(YAxis, 0.1);
AddLog(2, "Y轴异常,请检查!");
return false;
}
}
//第二步:再朝正方向运动一定距离,保证刚好通过原点感应器
Dmc2410.d2410_set_position(XAxis, 0);
Dmc2410.d2410_set_position(YAxis, 0);
Dmc2410.d2410_set_st_profile(XAxis, objConfig.VelMin, objConfig.VelMax, objConfig.Tac, objConfig.Tac, objConfig.STac, objConfig.STac);
Dmc2410.d2410_set_st_profile(YAxis, objConfig.VelMin, objConfig.VelMax, objConfig.Tac, objConfig.Tac, objConfig.STac, objConfig.STac);
Dmc2410.d2410_s_pmove(XAxis, objConfig.XAxisPosition, 0);
Dmc2410.d2410_s_pmove(YAxis, objConfig.YAxisPosition, 0);
while (Dmc2410.d2410_check_done(XAxis) == 0 || Dmc2410.d2410_check_done(YAxis) == 0)
{
long positionX = Dmc2410.d2410_get_position(XAxis);
long positionY = Dmc2410.d2410_get_position(XAxis);
if (positionX > this.pCurveMonitor.MaxXAxis)
{
//当位置超限时,停止轴运动
Dmc2410.d2410_decel_stop(XAxis, 0.1);
AddLog(2, "X轴异常,请检查!");
return false;
}
if (positionY > this.pCurveMonitor.MaxYAxis)
{
//当位置超限时,停止轴运动
Dmc2410.d2410_decel_stop(YAxis, 0.1);
AddLog(2, "Y轴异常,请检查!");
return false;
}
}
//第三步:再朝负方向低速找原点
Dmc2410.d2410_set_HOME_pin_logic(XAxis, 0, 1);
Dmc2410.d2410_set_HOME_pin_logic(YAxis, 0, 1);
Dmc2410.d2410_config_home_mode(XAxis, 0, 0);
Dmc2410.d2410_config_home_mode(YAxis, 0, 0);
Dmc2410.d2410_home_move(XAxis, 2, 0);
Dmc2410.d2410_home_move(YAxis, 2, 0);
while (Dmc2410.d2410_check_done(XAxis) == 0 || Dmc2410.d2410_check_done(YAxis) == 0)
{
long positionX = Dmc2410.d2410_get_position(XAxis);
long positionY = Dmc2410.d2410_get_position(YAxis);
if (positionX < -1 * this.pCurveMonitor.MaxXAxis)
{
//当位置超限时,停止轴运动
Dmc2410.d2410_decel_stop(XAxis, 0.1);
AddLog(2, "X轴异常,请检查!");
return false;
}
if (positionY < -1 * this.pCurveMonitor.MaxYAxis)
{
//当位置超限时,停止轴运动
Dmc2410.d2410_decel_stop(YAxis, 0.1);
AddLog(2, "Y轴异常,请检查!");
return false;
}
}
Dmc2410.d2410_set_position(XAxis, 0);
Dmc2410.d2410_set_position(YAxis, 0);
return true;
(二)流程工艺
-
需求分析:
工艺流程:
- 系统归零
- 前往取料口
- 检测料是否到达
- 取料口z轴下降
- 吸取物体
- 取料口z轴上升
- 前往加工位
- 加工位检测
- 加工位z轴下降
- 放下物体
- 加工位z轴上升
- 加工为等待
- 加工位z轴下降
- 吸取物体
- 加工位z轴上升
- 前往出料口
- 检测出料口是否有料
- 出料口z轴下降
- 放下物体
- 取料口z轴上升
- 根据生产情况:下一轮或者系统归零
按照上述流程
-
功能设计:
使用枚举对象枚举上述工艺,工艺名称后面带有数值,即工艺的顺序。
然后调用一个循环体,每次执行一个步骤,都会加一个步骤号。
public enum RunStep { //等待运行 RunReady, //前往取料口 MoveToReclaimer, //取料口判断料是否存在 ReclaimerWait, //取料口Z轴下降 ReclaimerDown, }
如果希望进行紧急停止,那么也只能在当前步骤执行完以后才能停止。
执行与控制不分开,后续想要更改,很容易出现问题
而且,目前的写法接收没有设备返回信息的最大等待时间的强停保护功能,如果机器故障,撞杆了,真没法第一时间停止。
如果复杂的动作,总不能编写100多个case,这个简单点的还行,如果要现场调试,简直就是噩梦。
教程上的东西稍微有点瑕疵,如果未来有空会考虑重构,以前做过类似的软件,目前没有精力重构这个教程的项目了,先搁着吧。
重构思路:
创建四个类:
流程单元{最基本的运动单元,负责运动的描述}
流程解释器{读取xml配置文件,创建流程单元}
流程树{存储执行工艺,是由一系列的流程单元组成}
流程执行器{执行流程树中存储的流程单元,同时具有一定的控制,急停,最长运动延时,工艺报警,日志输出等必备能力}
- 流程解释器通过读取xml文件,可以配置创建流程单元的运动信息,并且插入到流程树中
- 流程执行器,执行流程树中的动作。
-
具体实现:
这个文件里面的信息详细见博客页置顶的百度云链接,不再进行一一描述了。