1

如果定期调用状态机(在 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- 对于没有循环内状态的状态图,程序停止执行图,保存状态,并在对当前活动状态进行一次评估后执行程序的其余部分。如果图表中的所有状态都是 In-Cycle,程序在哪里停止执行图表以执行程序的其余部分?

唯一的解决方案是设置一些非循环内的状态并确保它们足够快地达到而不会导致任务溢出?

4

2 回答 2

1

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

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

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

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

在您的第二个案例语句中,您将检查“错误”状态并立即采取行动。

于 2019-12-14T12:36:18.723 回答
0

A PLC is made to be real time capable, so to answer your last question, yes the system is real time capable regardless of the programming language you are using.

When you use the tf1910 extension, code for the Beckhoff runtime is generated in the background, which will run cyclically every x ms depending on your configurations.

Translating the Cycle-Internal operation to a structured language could look like this:

Imagine you have a software-component Motor which extends a software-component StateMachine.

StateMachine defines different (primitive) states like Init, Ready, Busy, Idle, Error etc.

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

As a consequence Motor also inherits those states.

Now, if Motor is in the Init state, calling the Start() method will change the state from Init to Ready.

Depending on the architecture of your program this change can have an immediate effect on the program flow (this means in the current cycle) or in the next cycle.

Let's say, our StateMachine Function Block implements Cycle-Internal as a boolean input variable: bCycleInternal and it's current state as an enumaration variable: eStateMachine

Let's also say that, depending on the value of eStateMachine (thus the current state of the state machine), StateMachine calls a specific method (e.g. for Init Init(), for Ready Ready() etc.)

When bCycleInternal is true and the Start() method changes the current state from Init to Ready, Ready() is called directly after Init() in the same cycle. Otherwise, if bCycleInternal is false, when changing the state of the state machine (or the value of eStateMachine) from Init to Ready with the Start() method, Ready() is called not before the next cycle.

于 2019-12-14T12:26:07.337 回答