状态机/状态图周期转换

时间:2019-12-13 16:15:01

标签: simulink state-machine plc statechart

如果定期调用状态机(在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-对于没有周期内状态的状态图,该程序将停止执行该图,保存状态,并在对当前活动状态进行一次评估后执行其余程序。 如果图表中的所有状态均为“循环中”,程序将在何处停止执行图表以执行其余程序?

唯一的解决方案是使某些状态处于非循环状态,并确保它们达到足够快的速度而不会导致任务超限吗?

2 个答案:

答案 0 :(得分:1)

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

另一种看待这种情况的方式是,在结构化文本中,通常使用Case结构实现状态机。

要在一个周期内具有多个状态,您将需要两个Case结构或两次运行相同的Case结构(例如,使用For或While循环)

例如,假设您想在移至错误状态后立即对错误状态采取行动。您的第一个Case语句会将状态转换为“错误”。

在第二个Case语句中,您将检查“错误”状态并立即采取措施。

答案 1 :(得分:0)

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

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

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

想象一下,您有一个扩展了 StateMachine 软件组件的 Motor 软件组件。

StateMachine定义不同的(原始)状态,例如 Init,Ready,Busy,Idle,Error等

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

结果,电机也继承了这些状态。

现在,如果 Motor 处于 Init 状态,则调用Start()方法会将状态从 Init 更改为准备好了

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

比方说,我们的StateMachine功能块将 Cycle-Internal 实现为布尔输入变量: bCycleInternal 它是当前状态,是一个枚举变量: eStateMachine

我们也可以说,根据eStateMachine的值(即状态机的当前状态),StateMachine调用特定的方法(例如,对于 Init Init(),对于 Ready Ready()等)

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