状态机/状态图循环转换
State machine/ State chart in-cycle transition
如果周期性调用状态机(在 MatLAB Simulink 或 PLC 程序中),是否可以在同一 plc cycle/simulink 步骤期间在状态之间转换?
在 Twincat 3 (PLC) 中有一个选项 "Cycle-internal" 如下 link 所示:
https://infosys.beckhoff.com/content/1033/tf1910_tc3_uml/63050395607969163.html
使用这样的选项有什么限制吗?该系统是否仍然具有实时能力?
编辑因为我不能写长评论:
1- 在您的示例中,如果状态为循环内状态并且负责为电机生成设定点直到达到所需的设定点(因此需要花费大量时间)。该程序可以 "stuck" 处于此状态,导致任务超限,并违反实时约束。
建议的解决方案:控制最大值。使用变量 "Max. DO cycle calls" 对该状态的调用次数:https://infosys.beckhoff.com/english.php?content=../content/1033/tf1910_tc3_uml/63050395607969163.html&id=,还是 possible/better 在单独的 PLC 任务中执行此任务?
2- 对于没有循环内状态的状态图,程序停止执行图,保存状态,并在对当前活动状态进行一次评估后执行程序的其余部分。
如果图表中的所有状态都是In-Cycle,程序在哪里停止执行图表以执行程序的其余部分?
是否唯一的解决方案是让一些状态不是 In-Cycle 并确保它们足够快地达到而不会导致任务超限?
PLC 制造 具有实时能力,因此回答您的最后一个问题,是的,无论您使用何种编程语言,系统都具有实时能力。
当您使用 tf1910 扩展时,Beckhoff 运行time 的代码会在后台生成,这将 运行 周期性地 每 x ms 取决于根据您的配置。
将 Cycle-Internal 操作转换为结构化语言可能如下所示:
假设您有一个软件组件 Motor 它扩展了一个软件组件 StateMachine.
StateMachine 定义了不同的(原始)状态,例如 Init、Ready、Busy、Idle、Error 等。
V Boot()
|
|
<Init>
|
|
| Start()
|
|
<Ready> -----------<--------------+-------------<-----------+
| | |
| | |
| Execute() | |
| | |
| | |
| | Reset() |
<Prepare> | |
| | |
| | |
| | |
Wait() | Fault() | |
<Waiting> ---<-------->--- <Busy> ----------->----------- <Error> |
EndWait() | |
| |
| |
| |
| Done() |
| |
| |
| |
<Idle> ---------------------->------------------------------+
因此 Motor 也继承了这些状态。
现在,如果 Motor 处于 Init 状态,调用 Start() 方法将改变状态 初始化到就绪。
根据您程序的体系结构,此更改可能会对程序流程(这意味着在 当前周期)或 下一个周期产生立竿见影的效果循环.
比方说,我们的 StateMachine 功能块将 Cycle-Internal 实现为布尔输入变量:bCycleInternal
它的当前状态作为枚举变量:eStateMachine
我们还可以这样说,根据 eStateMachine 的值(因此状态机的当前状态),StateMachine 调用特定方法(例如对于 Init Init(),对于 Ready Ready() 等)
当 bCycleInternal 为真且 Start() 方法将当前状态从 Init 更改为 Ready 时,调用 Ready() 在同一周期中的 Init() 之后直接。
否则,如果 bCycleInternal 为假,当使用 Start( ) 方法,Ready() 不在 下一个周期之前被调用。
是的,这是可能的。它完全取决于您如何定义状态机代码。 Filippo 的回答解释了如何使用 Cycle-Internal 选项。
另一种看待这个问题的方法是,在结构化文本中,状态机通常使用条件结构来实现。
为了在单个循环中有多个状态,您需要两个 Case 结构或 运行 相同的 Case 结构两次(例如使用 For 或 While 循环)
例如,假设您希望在进入错误状态后立即对错误状态采取行动。您的第一个 Case 语句会将状态转换为 "Error"。
在您的第二个 Case 语句中,您将检查 "Error" 状态并立即采取行动。
如果周期性调用状态机(在 MatLAB Simulink 或 PLC 程序中),是否可以在同一 plc cycle/simulink 步骤期间在状态之间转换?
在 Twincat 3 (PLC) 中有一个选项 "Cycle-internal" 如下 link 所示: https://infosys.beckhoff.com/content/1033/tf1910_tc3_uml/63050395607969163.html
使用这样的选项有什么限制吗?该系统是否仍然具有实时能力?
编辑因为我不能写长评论:
1- 在您的示例中,如果状态为循环内状态并且负责为电机生成设定点直到达到所需的设定点(因此需要花费大量时间)。该程序可以 "stuck" 处于此状态,导致任务超限,并违反实时约束。 建议的解决方案:控制最大值。使用变量 "Max. DO cycle calls" 对该状态的调用次数:https://infosys.beckhoff.com/english.php?content=../content/1033/tf1910_tc3_uml/63050395607969163.html&id=,还是 possible/better 在单独的 PLC 任务中执行此任务?
2- 对于没有循环内状态的状态图,程序停止执行图,保存状态,并在对当前活动状态进行一次评估后执行程序的其余部分。 如果图表中的所有状态都是In-Cycle,程序在哪里停止执行图表以执行程序的其余部分?
是否唯一的解决方案是让一些状态不是 In-Cycle 并确保它们足够快地达到而不会导致任务超限?
PLC 制造 具有实时能力,因此回答您的最后一个问题,是的,无论您使用何种编程语言,系统都具有实时能力。
当您使用 tf1910 扩展时,Beckhoff 运行time 的代码会在后台生成,这将 运行 周期性地 每 x ms 取决于根据您的配置。
将 Cycle-Internal 操作转换为结构化语言可能如下所示:
假设您有一个软件组件 Motor 它扩展了一个软件组件 StateMachine.
StateMachine 定义了不同的(原始)状态,例如 Init、Ready、Busy、Idle、Error 等。
V Boot()
|
|
<Init>
|
|
| Start()
|
|
<Ready> -----------<--------------+-------------<-----------+
| | |
| | |
| Execute() | |
| | |
| | |
| | Reset() |
<Prepare> | |
| | |
| | |
| | |
Wait() | Fault() | |
<Waiting> ---<-------->--- <Busy> ----------->----------- <Error> |
EndWait() | |
| |
| |
| |
| Done() |
| |
| |
| |
<Idle> ---------------------->------------------------------+
因此 Motor 也继承了这些状态。
现在,如果 Motor 处于 Init 状态,调用 Start() 方法将改变状态 初始化到就绪。
根据您程序的体系结构,此更改可能会对程序流程(这意味着在 当前周期)或 下一个周期产生立竿见影的效果循环.
比方说,我们的 StateMachine 功能块将 Cycle-Internal 实现为布尔输入变量:bCycleInternal 它的当前状态作为枚举变量:eStateMachine
我们还可以这样说,根据 eStateMachine 的值(因此状态机的当前状态),StateMachine 调用特定方法(例如对于 Init Init(),对于 Ready Ready() 等)
当 bCycleInternal 为真且 Start() 方法将当前状态从 Init 更改为 Ready 时,调用 Ready() 在同一周期中的 Init() 之后直接。 否则,如果 bCycleInternal 为假,当使用 Start( ) 方法,Ready() 不在 下一个周期之前被调用。
是的,这是可能的。它完全取决于您如何定义状态机代码。 Filippo 的回答解释了如何使用 Cycle-Internal 选项。
另一种看待这个问题的方法是,在结构化文本中,状态机通常使用条件结构来实现。
为了在单个循环中有多个状态,您需要两个 Case 结构或 运行 相同的 Case 结构两次(例如使用 For 或 While 循环)
例如,假设您希望在进入错误状态后立即对错误状态采取行动。您的第一个 Case 语句会将状态转换为 "Error"。
在您的第二个 Case 语句中,您将检查 "Error" 状态并立即采取行动。