状态机/状态图周期内转换



如果定期调用状态机(在 MatLAB Simulink 或 PLC 程序中(,是否可以在相同的 plc 周期/simulink 步骤中在状态之间转换?

在Twincat 3(PLC(中,有一个选项"循环内部",如下面的链接所示: https://infosys.beckhoff.com/content/1033/tf1910_tc3_uml/63050395607969163.html

使用此类选项是否有任何限制? 系统是否仍然具有实时功能?

编辑为我无法写长评论:

1-在您的示例中,如果状态为循环中状态,并负责为电机生成设定点,直到达到所需的设定点(因此需要花费大量时间(。程序可能会"卡"在这种状态下,导致任务溢出,并违反实时约束。 建议的解决方案:使用变量"最大 DO 循环调用"控制此状态的最大调用次数:https://infosys.beckhoff.com/english.php?content=../content/1033/tf1910_tc3_uml/63050395607969163.html&id=,或者是否可以/更好地在单独的 PLC 任务中实现此任务?

2-对于没有周期内状态的状态图,程序将停止执行图表,保存状态,并在对当前活动状态进行一次评估后执行程序的其余部分。 如果图表中的所有状态都是周期中,则程序在哪里停止执行图表以执行程序的其余部分?

唯一的解决方案是让一些状态不是周期中,并确保它们足够快地到达,不会导致任务溢出?

是的,这是可能的。这完全取决于您如何定义状态机代码。Filippo的回答解释了如何使用循环内部选项。

另一种看待这个问题的方法是,在结构化文本中,状态机通常使用案例结构实现。

为了在单个循环中具有多个状态,您需要两个案例结构或运行相同的案例结构两次(例如,使用 For 或 While 循环(

例如,假设您希望在进入错误状态后立即对错误状态执行操作。您的第一个 Case 语句会将状态转换为"错误"。

在第二个 Case 语句中,您将检查"错误"状态并立即采取行动。

PLC具有实时功能,因此要回答您的最后一个问题,是的,无论您使用哪种编程语言,系统都是实时的。

使用 tf1910 扩展时,Beckhoff 运行时的代码将在后台生成,该代码将每 x 毫秒循环运行一次,具体取决于您的配置。

将 Cycle-Internal 操作转换为结构化语言可能如下所示:

假设您有一个软件组件Motor,它扩展了一个软件组件StateMachine

状态机定义了不同的(原始(状态,如初始化、就绪、忙碌、空闲、错误等

V  Boot()                        
|                                     
|
<Init>
|
|    
|  Start()
|
|
<Ready> -----------<--------------+-------------<-----------+
|                              |                         |
|                              |                         |
|  Execute()                   |                         |
|                              |                         |
|                              |                         |
|                              |   Reset()               |
<Prepare>                          |                         |
|                              |                         |
|                              |                         |
|                              |                         |
Wait()          |           Fault()            |                         |
<Waiting> ---<-------->--- <Busy> ----------->----------- <Error>                      |
EndWait()        |                                                        |
|                                                        |
|                                                        |
|                                                        |
|  Done()                                                |
|                                                        |
|                                                        |
|                                                        |
<Idle> ---------------------->------------------------------+

因此,电机也继承了这些状态。

现在,如果Motor处于 Init 状态,调用 Start(( 方法会将状态从Init更改为Ready

根据程序的体系结构,此更改可能会对程序流(这意味着在当前周期中(或下一个周期产生直接影响。

假设我们的状态机功能块将Cycle-Internal实现为布尔输入变量:bCycleInternal它的当前状态是一个 enumaration 变量:eStateMachine

假设,根据 eStateMachine 的值(因此状态机的当前状态(,StateMachine 调用一个特定的方法(例如,对于 InitInit((,对于 Ready Ready(( 等(。

当 bCycleInternal 为 true 并且 Start(( 方法将当前状态从 Init 更改为 Ready 时,在同一循环中直接在Init(( 之后调用Ready((。 否则,如果 bCycleInternal 为 false,则在使用 Start(( 方法将状态机的状态(或 eStateMachine 的值(从Init更改为 Ready 时,不会在下一个循环之前调用Ready((。

最新更新