最近一段时间集中研究OPCUA 在机器人控制应用中应用的可能性。这个话题自然离不开运动控制。
笔者对运动控制不是十分了解。于是恶补EtherCAT 驱动,PLCopen 运动控制的知识,下面是自己的读书笔记和实现OPCUA /IEC61499 运动控制器的实现方案设想。
为什么要研究OPCUA /IEC61499 的运动控制?PLCopen 对运动控制实现了标准化功能块库的工作,使PLC 能够实现运动控制器的功能。不过,IEC 61131 4 定义了一个集中式自动化系统。缺乏分布式控制的概念,每个控制都需要单独考虑。另一方面,每个厂商的PLC 运动控制功能块库或多或少地有些差别,使用的运动控制总线也不相同。OPCUA /IEC61499模型能够弥补这方面的不足。
PLCopen 功能块库
早期的运动控制是使用运动控制器实现的,PLCopen 提供了运动控制的功能块库,从而使PLC 能够成为“运动控制器”。
PLCopen 提供了运动控制功能块库。PLC 厂商提供符合PLCopen 规范的运动控制功能块库,用户可以使用标准的功能块实现运动控制应用。
结构数据类型
AXIS_REF
几乎所有的运动控制功能块都使用AXIS_REF 数据类型,用于描述轴的属性,不同的制造商规定了不同轴的属性,其包含的变量可多大数百个,主要包括:
- 基本信息
- 管理信息
- 运动参数信息
- 出错信息
- 其它信息
根据 PLCopen 的定义,AXIS_REF结构的内容特定于每个制造商。在 ISG 实现的版本中,AXIS_REF包含轴索引的变量hli_axis_idx,可以使用该变量对 HLI 上的轴特定区域进行寻址。 在OPCUA/IEC61499 平台上,可以使用OPCUA 构建轴模型,而AXIS 可以是轴的OPCUA 节点路径(Path String)。
Acceleration Deceleration Jerk
加速度 Acceleration
减速度 Deceleration
加加速度 Jerk
Jerk是加速度对时间的导数,单位是m/s3 ,即米/秒的3次方。Jerk可以看做是加速度的变化率。
一些例子:
PLCopen功能块
单轴运动功能块
MC_Power
MC_Power开关Axis 指定驱动器的电源。
VAR_IN_OUT | ||
Variable name | Data type | Description |
Axis | AXIS_REF | Axis reference |
VAR_INPUT | ||
Variable name | Data type | Description |
Enable | BOOL | Must have the value TRUE otherwise power cannot be switched on. |
Enable_Positive | BOOL | Must have the value TRUE otherwise power cannot be switched on. Enable only for positive motion direction is not supported. |
Enable_Negative | BOOL | Must have the value TRUE otherwise power cannot be switched on. Enable only for negative motion direction is not supported. |
PowerDefaultState | MCV_DRIVE_ | Function available for CANopen drives: The function block sets the drive to this state as long as the “Status” output indicates FALSE, i.e. at least one of the Enable... inputs is assigned the value FALSE (see table below). The input is assigned mcvPowerStateDefault as default value |
VAR_OUTPUT | ||
Variable name | Data type | Description |
Status | BOOL | TRUE indicates that the drive has torque applied and is in control mode. |
Error | BOOL | Indicates whether an error occurred in the FB. |
ErrorID | WORD | Error identifier |
DriveEnabled | BOOL | TRUE indicates that the drive is ready for enabling power. |
DriveReady | BOOL | TRUE indicates that the drive is being controlled. |
PowerState | MCV_DRIVE_ | State in which the drive is currently (see table below). |
MC_Home
启动设置原点的过程。伺服驱动器提供了许多设置原点的过程。称为Home_method。注意,MC_Home 并非是将电机的当前位置回到原点,而是设置参考点(比如当前位置)作为原点。回到原点可以使用MC_MoveAbsolution.实现。
在具体实现中,设置原点的过程是十分复杂的,方法有许多种。基本的方法是设置一个原点开关,有原点开关触发MC_Home 功能块。
VAR_IN_OUT | ||
Variable name | Data type | Description |
axis | AXIS_REF | Axis reference |
VAR_INPUT | ||
Variable name | Data type | Description |
Execute | BOOL | Homing is commanded on a rising edge at the input. |
CamSignal | BOOL | Signal to command adoption of the homing position. For further application notes, see Section 2.8.1. |
VAR_OUTPUT | ||
Variable name | Data type | Description |
Done | BOOL | When TRUE, homing is completed and the axis is in “Standstill” state. |
CommandAborted | BOOL | TRUE indicates that the command was aborted by another command. |
Error | BOOL | Is TRUE when an error occurs in the FB. |
ErrorID | WORD | Error code. |
在伺服驱动器中,支持Home 的参数:
6060h Modes of operation 设置06 (Homing mode)
6098h Homing method 设置 1
609Ah homing_acceleration 设置 200000
607Ch Home offset
6099h 01 Speed_during_search_for_switch 设置为10000
6099h 02 Speed_during_search_for_zero 设置为500
ec_pdo_entry_reg_t domainServoOutput_regs[] = {
{estun_Pos0, estun, 0x6040, 0x00, &cntlwd, NULL},
{estun_Pos0, estun, 0x607a, 0x00, &ipData, NULL},
{estun_Pos0, estun, 0x6060, 0x00, &modes_of_operation, NULL}, //6060 模式选择
{estun_Pos0, estun, 0x6098, 0x00, &Homing_method, NULL}, //Homing_method 模式选择
{estun_Pos0, estun, 0x6099, 0x01, &speed_during_search_for_switch, NULL}, //speed_during_search_for_switch
{estun_Pos0, estun, 0x6099, 0x02, &speed_during_search_for_zero, NULL}, //speed_during_search_for_zero
{estun_Pos0, estun, 0x609a, 0x00, &homing_acceleration, NULL}, //homing_acceleration
{estun_Pos0, estun, 0x607c, 0x00, &home_offset, NULL}, //home_offset
{}
};
MC_MoveAbsolute
将轴移动到一个指定的绝对位置,实现绝对位置的前提是确定绝对的原点。也就是坐标点。没有坐标点就没有绝对位置。因此在绝对运动之前,要设置原点(MC_Home)。
VAR_INPUT | ||
Variable name | Data type | Description |
Execute | BOOL | A rising edge at the input commands the motion to an absolute position. |
Position | LREAL | Target position of the motion, |
Velocity | LREAL | Maximum velocity of the motion. This value must be specified positive. The velocity is not necessarily reached. Value range [1.0, 2147483647.0] |
Acceleration | LREAL | Acceleration value. This value must be specified positive. Value range [0.0, 2147483647.0] |
Deceleration | LREAL | Deceleration value. This value must be always be specified positive. Value range [0.0, 2147483647.0] |
Jerk | LREAL | Jerk value. This value must be always be specified positive. Value range [0.0, 2147483647.0] |
Direction | INT | Direction in which the motion is started. One of the 4 values: 1 positive direction 2 shortest path 3 negative direction 4 current direction Specifying the direction is effective only if a modulo coordinate system was defined for the axis in the axis-specific machine data using parameter kenngr.achs_mode (P-AXIS-00015) since the direction is always unambiguous with linear axes. |
VAR_OUTPUT | ||
Variable name | Data type | Description |
Done | BOOL | The axis is within a range close to the target position. The range is specified by the parameter getriebe[...].window (P-AXIS-00236) of the axis-specific machine data. |
CommandAborted | BOOL | TRUE indicates that the command was aborted by another command. |
Error | BOOL | Is TRUE if an error occurs in the FB. |
ErrorID | WORD | Error identifier |
Position
以用户自定义单位表示的目标绝对位置。ISG Kernel 中为0.1 µm 。
在EtherCAT 伺服MC_MoveAbsolute 对应的是Profie_Position 操作模式(pp Mode),涉及的参数包括:
Controlword 第6位设置为0 (absolute)
6060h Modes of operation 设置 Profile position mode 1
607Ah Target position
607Dh 01 Min position limit
607Dh 01 Max position limit
控制字
其中oms(操作模式指定的控制位)
例子:
MC_MoveAdditive
VAR_IN_OUT | ||
Variable name | Data type | Description |
Axis | AXIS_REF | Axis reference |
VAR_INPUT | ||
Variable name | Data type | Description |
Execute | BOOL | The motion starts on the rising edge of this input signal. |
Distance | LREAL | Target position of the motion, Value range [-2147483648.0, 2147483647.0] |
Velocity | LREAL | Maximum velocity of the motion. This value must be specified positive. The velocity is not necessarily reached. Value range [1.0, 2147483647.0] |
Acceleration | LREAL | Acceleration value. This value must be specified positive. Value range [0.0, 2147483647.0] |
Deceleration | LREAL | Deceleration value. This value must be always be specified positive. Value range [0.0, 2147483647.0] |
Jerk | LREAL | Jerk value. This value must be always be specified positive. Value range [0.0, 2147483647.0] |
VAR_OUTPUT | ||
Variable name | Data type | Description |
Done | BOOL | The axis is within a range close to the target position. The range is specified by the parameter getriebe[...].window (P-AXIS-00236) of the axis-specific machine data. |
CommandAborted | BOOL | TRUE indicates that the command was aborted by another command. |
Error | BOOL | Is TRUE if an error occurs in the FB. |
ErrorID | WORD | Error identifier |
MC_MoveRelative
在当前位置基础上移动一个距离(Distance),实现增量运动。下一个位置:
Next_Position=Current_Position+Distance.
VAR_IN_OUT | ||
Variable name | Data type | Description |
Axis | AXIS_REF | Axis reference |
VAR_INPUT | ||
Variable name | Data type | Description |
Execute | BOOL | The motion starts at the rising edge of this input signal. |
Distance | LREAL | Relative distance for the motion. Value range [-2147483648.0, 2147483647.0] |
Velocity | LREAL | Maximum velocity of the motion. This value must be specified positive. The velocity is not necessarily reached. Value range [1.0, 2147483647.0] |
Acceleration | LREAL | Acceleration value. This value must be specified positive. Value range [0.0, 2147483647.0] |
Deceleration | LREAL | Deceleration value. This value must be always be specified positive. Value range [0.0, 2147483647.0] |
Jerk | LREAL | Jerk value. This value must be always be specified positive. Value range [0.0, 2147483647.0] |
VAR_OUTPUT | ||
Variable name | Data type | Description |
Done | BOOL | The axis is within a range close to the target position. The range is specified by the parameter getriebe[...].window (P-AXIS-00236) of the axis-specific machine data. |
CommandAborted | BOOL | TRUE indicates that the command was aborted by another command. |
Error | BOOL | Is TRUE if an error occurs in the FB. |
ErrorID | WORD | Error identifier |
MC_MoveRelative 对应于伺服控制器的Profile_Position。EtherCAT 伺服控制器的参数:
Controlword 第6位设置为1 (relative)
其它参数设置应该与MC_MoveAbsolute类似。
下面是一个例子:
第一个功能块在位置0 开始移动6000 个单位,完成后再移动4000 ,达到10000位置。
下图的左边,描述了位置移动的变化时序图。在下图的右边,描述了另外一种情形,当第一个功能块还没有结束(只到达3250 的位置)就启动了第二个功能块,于是,最终只到达7250 的位置。
MC_MoveVelocity
VAR_INPUT | ||
Variable name | Data type | Description |
Execute | BOOL | The motion starts at the rising edge of this input signal. |
Velocity | LREAL | Velocity value of endless motion. This value must be specified positive. Value range [1. 0, 2147483647.0] |
Acceleration | LREAL | Acceleration value. This value must be specified positive. Value range [0. 0, 2147483647.0] |
Deceleration | LREAL | Deceleration value. This value must be always be specified positive. Value range [0. 0, 2147483647.0] |
Jerk | LREAL | Jerk value. This value must be always be specified positive. Value range [0. 0, 2147483647.0] |
Direction | INT | Direction in which the motion is started. One of the 3 values: Positive direction 3 negative direction 4 current direction |
VAR_OUTPUT | ||
Variable name | Data type | Description |
InVelocity | BOOL | The commanded velocity was reached (for the first time). |
CommandAborted | BOOL | TRUE indicates that the command was aborted by another command. |
Error | BOOL | Is TRUE if an error occurs in the FB. |
ErrorID | WORD | Error identifier |
在EtherCAT 伺服控制内部支持下面的参数:
6060H Modes of operation 设置为 Profile velocity mode (03)
6083H Profile acceleration
6084h Profile deceleration
MC_Stop
VAR_IN_OUT | ||
Variable name | Data type | Description |
Axis | AXIS_REF | Axis reference |
VAR_INPUT | ||
Variable name | Data type | Description |
Execute | BOOL | Starts the command on the rising edge. |
Deceleration | LREAL | Deceleration value. This value must be always be specified positive. Value range [0.0, 2147483647.0] |
Jerk | LREAL | Jerk value. This value must be always be specified positive. Value range [0.0, 2147483647.0] |
VAR_OUTPUT | ||
Variable name | Data type | Description |
Done | BOOL | 0 velocity was reached. Caution: The "Done“ output merely indicates that the axis is stationary. The automatic axis state indicator remains initially in the STOPPING state. Only when the "Execute” input is also FALSE does the automatic axis state indicator change to the “STANDSTILL” state. |
Error | BOOL | Is TRUE if an error occurs in the FB. |
ErrorID | WORD | Error identifier |
多轴功能块
许多运动控制应用是多维运动,它涉及多轴运动。多轴运动的关键是多轴同步运动。例如:
- 电子凸轮中主/从轴的运动。
- 主轴(虚拟轴)与多个从轴的同步运动
- 电子齿轮
多轴运动控制功能块分成:
- 多轴运动控制功能块
- 协调运动控制功能块(轴组运动控制功能块)
PLCopen Part 4: Coordinated Motion 是协调运动控制的标准。
多轴运动控制功能块
多轴运动是指多个轴的主从同步运动,例如电子凸轮,电子齿轮。
电子凸轮
MC_CamTableSelect
MC_CamIn
MC_CamOut
电子齿轮
MC_GearIn
MC_GearOut
轴组运动控制功能块
Function block | PLC systems | ||
3S | TwinCAT | KW | |
SIMU | SIMU | SIMU KUKA | |
SIMU | SIMU | SIMU KUKA | |
SIMU | SIMU | SIMU KUKA | |
SIMU | SIMU | SIMU KUKA | |
SIMU | SIMU | SIMU KUKA | |
SIMU | SIMU | SIMU KUKA | |
SIMU | SIMU | SIMU KUKA | |
SIMU | SIMU | SIMU KUKA | |
SIMU | SIMU | SIMU KUKA | |
SIMU | SIMU | SIMU KUKA | |
SIMU | SIMU | SIMU KUKA | |
SIMU | SIMU | SIMU KUKA | |
SIMU | SIMU | SIMU KUKA | |
SIMU | SIMU | SIMU KUKA |
SIMU | SIMU | SIMU KUKA | |
SIMU | SIMU | SIMU KUKA | |
SIMU | SIMU | SIMU KUKA | |
SIMU | SIMU | SIMU KUKA | |
SIMU | SIMU | SIMU KUKA | |
SIMU | SIMU | SIMU KUKA | |
SIMU | SIMU | SIMU KUKA | |
SIMU | SIMU | SIMU KUKA | |
SIMU | SIMU | SIMU KUKA |
主要的轴组功能块
在运动控制应用中,往往是多个轴协同运动,并且在2D/3D坐标系中运动。PLCopen Part4 是2D/3D 的坐标运动,它将多个轴构成轴组。机械臂,机器人等应用应该是多轴应用。下面是一些轴组的运动控制功能块。
这些轴组运动控制功能块看上去与单轴类似,其实内部实现要复杂的多。
MC_AddAxisToGrp
添加轴到轴组。
VAR_IN_OUT | ||
Variable name | Data type | Description |
AxesGroup | AXES_GROUP_REF | Axis group reference |
axis | AXIS_REF | Axis reference |
VAR_INPUT | ||
Variable name | Data type | Description |
Execute | BOOL | The axis is added to the axis group on a rising edge. |
IdentInGroup | IDENT_IN_GROUP_REF | Identification of the axis in the axis group. |
VAR_OUTPUT | ||
Variable name | Data type | Description |
Done | BOOL | TRUE indicates that axis was added to the axis group. |
Busy | BOOL | TRUE indicates that the function block is executing a job. |
Error | BOOL | TRUE indicates that an error occurred. |
ErrorID | WORD | Error code. |
MC_MoveCircAbs
MC_MoveCircRel
MC_MoveLinAbs
MC_MoveLinRel
MC_MovePath
坐标系
机械坐标系(MCS)
相对于机械装置的坐标系统,通常是笛卡尔直角坐标系。
产品坐标系(PCS)
也称为工件坐标系。它基于MCS ,经过坐标变换而成。
轴坐标系(ACS)
它基于物理轴,它们可以是笛卡尔坐标系,也可以是极坐标或者其它坐标系。
坐标系转换应该是运动控制功能块内部实现。
PLCopen 状态机
在运动控制系统中,将轴的运行状态分成若干个逻辑状态,而每个逻辑状态直接的转移,需要特定的条件、或指定的MC 运控指令。
下面是PLCopen 状态图
8 种可能状态:
- Power_off(Disabled):轴未上电使能,或未使能,需执行MC_Power 指令
- Errorstop 先执行MC_Reset/MC_Power 指令
- Stopping 等待停机操作完成
- Standstill 轴已停止运行,脱离同步
- Discrete_Motion 轴处于离散运行状态
- Continuous_Motion 轴处于连续运行中
- Synchronized_Motion 轴处于同步运行中
- Homing 轴处于回零运行中,等待归零操作执行完
由图中可以看到:
- 在轴停止状态(Standstill,即 Axis.nAxisState=3)可以转移到各种运行状态;
- 可以由多种状态转移到停止状态(Standstill,即 Axis.nAxisState=3),,
- 若伺服轴出现告警(Errorstop,即 Axis.nAxisState=1),就必需先运行 MC_Reset 指令、
- MC_Power 指令使轴进入Standstill 状态,才能让轴再次运行;
- 若不按上述转移图方式使用 MC 指令命令轴运动,就不会使轴响应,反而得到 MC 功能块的错误告警信息;
在实现过程中,每个轴对应一个AXIS 对象,每个对象中维护一个状态机。并且有两个入口,command 和 StatusUpdate。实现状态机的运行。command 来自于功能块对象,而StatusUpdate 来自于EtherCAT 线程。AXIS 对象通过callback 将状态变化返回给功能块。
速度与位置
电机的位置是通过编码器的精度确定的,比如编码器精度为2 的23次方=8388608。转一圈共计产生8388608个脉冲。电机的位置是以脉冲数确定的。电机转速*8388608是target velocity 的值。
实现平台架构
本文探讨基于OPCUA/IEC61499 平台实现PLCopen 运动控制信息模型和功能块的软件架构。最终目的是使用OPCUA 和IEC61499 平台实现机器人控制。
实验平台的功能
- 使用OPCUA 构建轴模型
- 使用IEC61499 构建运动控制功能块
- 使用IEC61499 功能块网络实现运动控制应用
OPCUA 信息模型
参照笔者的博文:OPCUA 配套协议:机器人
IEC61499 功能块
IEC61499 没有支持PLCopen 运动控制功能块。需要自行定义和开发类似于PLCopen 的运动控制FB。
IEC61131-3 功能块是不分事件和数据的。当转换为IEC61499 功能块时,需要区分一下。如下图所示。
实例1:
在上面的网络图中,我们只是测试了MC_Home,MC_moveVelocity ,MC_Stop 三个功能块。 具体参数的设置参考松下A6 伺服驱动器。
实例2:MC_MoveAbsolution 和MC_MoveRelation
实例3 MC_Master
MC_Master 实现EtherCAT Master 的初始化和激活。在PLCopen 中并没有MC_Master。在多轴系统中,先要对所有的从轴初始化之后才能够激活Master(在EtherCAT 伺服中,要求SDO 参数在非实时场合使用,所以,要先初始化从控制器,然后激活master。故在功能块中设置了MC_Master,也可以取名为EtherCAT_Master.
实例4:MC_MoveVelocity
电机转动,延时,切换方向,重复转动。
系统架构
EtherCAT 伺服驱动器
在这里,我们先以基于EtherCAT和CANopen 总线的伺服驱动器作为底层驱动,OPCUA/IEC61499 平台作为运动控制器。运动控制器是EtherCAT Master,伺服驱动器是Ether CAT的从设备。
实验中使用松下公司的A6 Ethercat伺服驱动器。
Ether CAT master
使用开源项目 IgH EtherCAT Master。
软件架构
在运动控制系统中最基本的控制对象是轴。轴同时对应于底层的伺服驱动器(我们假设一个伺服驱动器控制一个物理的轴)。多个轴的参数,控制命令和状态是通过EtherCAT PDO 级联方式传递的。所以轴具有承上启下功效的对象。
在OPCUA /IEC61499 平台上,可以使用OPCUA 信息模型描述轴的模型,类似于AXIS_REF包含的属性。OPCUA /IEC61499平台运行时根据轴模型构建内部的AXIS 对象(AXIS Class)实例。AXIS 对象实现运动控制块到EtherCAT 网络的映射(Mapping)。使用IEC61499 功能块实现类似PLCopen的功能块。
使用OPCUA 构建轴模型,运行时内部有对应的AXIS 对象。61499功能块修改AXIS 对象的参数,EtherCAT master 周期性地AXIS 与物理伺服驱动器交换数据。
结束语
运动控制是十分复杂的系统,涉及机械,电子控制的知识非常多。实现一个真正实用的运动控制功能块及其运行时是不容易的。需要时间与经验的积累。唯有前行,方得收获。
无论是OPCUA ,还是IEC61499 本质上都只是一种编程的方法。真正要实现落地应用。关键的是对应用的强大支持。其中功能块库是成功的关键之一。