今天继续推进《将“运动控制功能块”移植到OOP中》的学习,反复学习了6,7,8三个示例。三个示例本身很简单,通过状态机实现轴多轴的时序配合,通过itfAxis和itfCommand接口实现功能调用。但是在状态机中,对于运动控制相关的Method并没有循环调用,只在状态转移时调用一次,这是如何实现真正的运动控制过程控制的还很迷糊。为了一探究竟,我突然萌生了一共奇特的想法:我计划在接下来的几天把经典的Codesys的PLCopen库重新在西门子的1500上实现,且采用AX的面向对象的设计思想。让自动化行业最具有代表性的2个平台在AX的作用下融合在一起,想想都刺激!
下面是今天学习的一些笔记,供日后参阅。
6、仓库示例
6.1 应用说明
该应用的目的是自动从货架的储藏柜中取出货物。货物存放在托盘中,可以用叉子系统取出。
图4:仓储实例概述
仓库的任务是用三个轴移动叉子来放置或取走托盘:
- X 轴沿地面移动;
- Y 轴移动到所需高度;
- Z 轴将叉子移动到货架上,取走托盘。
顺序是将X轴和Y轴移动到所需位置。两个轴到达该位置后,Z轴立即移动到托盘下方的货架上,在本例中是移动1000毫米。然后,Y轴将托盘再提升100毫米,将托盘从货架上抬起,这样托盘就可以从货架上移出,并移动到所需位置进行交付。
这个示例可以用不同的方法实现。一种直接的方法是使用PLCopen第1部分功能块。另外,也可以在支持PLCopen第4部分(协调运动)的控制器中定义XYZ组,这样可以简化和优化运动
6.2 第一个编程示例(使用第1部分中的FB)
只需使用第1部分中的功能块,就可以通过以下方式实现。
图5: 仓储示例的第一个程序
6.3 时序图
下图显示了从仓储系统提取托盘的顺序。
图6:仓储示例的时间图
6.4 OOP实现
本示例用于展示ST语言的OO编程。对于PLC程序员来说,编程非常简单,后台使用的是标准PLCopen运动控制库第1部分(v2)。通常,这些FB是以循环方式调用的,这与OOP理念不太相符。如果不需要反馈(完成、错误…),那么不循环调用FB,也是可以的。通过GetCommandStatus方法,可以调用底层FB(如 MC_MoveAbsolute),并通过GetCommandStatus(通过内部调用MC_MoveAbsolute和其他实例)返回运动的状态信息(完成、错误等)。在此基础上,可以开始下一条指令。当然,这些方法的实现取决于具体的供应商。
程序使用了状态机,不同的状态反映了整个轨迹的不同阶段。通过使用变量lastCommandX、lastCommandY和lastCommandZ,程序变得非常透明(见图7:上部为变量声明部分,下部为以CASE指令形式实现的状态机)。由此产生的时序图如图8所示。
PROGRAM WarehosingExample
VAR
AxisX:itfAxis;
AxisY:itfAxis;
AxisZ:itfAxis;
stateOOP:INT;
lastCommandX:itfCommand;
lastCommandY:itfCommand;
lastCommandZ:itfCommnad;
stepOn:BOOL:= FALSE;
targetPosX:REAL:= 400;
targetPosY:REAL:= 600;
END_VAR
CASE stateOOP OF
0:;
10: //init
AxisX.Power(Enable := TRUE,EnablePositive := TRUE,EnableNegative := TRUE);
AxisY.Power(Enable := TRUE,EnablePositive := TRUE,EnableNegative := TRUE);
AxisZ.Power(Enable := TRUE,EnablePositive := TRUE,EnableNegative := TRUE);
IF stepOn THEN
stateOOP := stateOOP + 10;
END_IF
20: // start movement in XY
lastCommnadX := AxisX.MoveAbsolute(Positio