0

我正在编写练习有限状态机代码,我无法理解我的“Switch”和“if”语句的顺序(应该先出现)。

目前,我是这样写的:

task main()
{
    // State variable default.
    SystemStateType SystemState = State1;

    While(1)
    {
        //Taken in from external sensors in real time
        int reading;

        if (reading == 0)
        {
            SystemState = State1;
        }
        else
        {
            SystemState = State2;
        }

        switch (SystemState)
        {
            case State1:
                //actions
                break;

            case State2:
                //other actions 
                break;
        }
    }
}

该代码旨在实时获取传感器数据并做出相应响应。我意识到这不是实际的功能代码,但我希望因为这个问题是理论上的,所以我当前显示的代码就足够了。如果我遗漏了什么,请告诉我。

谢谢!

4

2 回答 2

1

我无法理解我的“Switch”和“if”语句(应该先出现)的顺序。

您的switch语句检查SystemState变量的值,该值是通过您的if语句设置的。所以正确的顺序是要有你的if语句,让SystemStatevariable takes the desired value, and then examine the value of SystemState在你的switch语句中。

假设你有ifswitch陈述相反的方式,像这样:

task main()
{
    // State variable default.
    SystemStateType SystemState = State1;

    While(1)
    {
        //Taken in from external sensors in real time
        int reading;

        switch (SystemState)
        {
            case State1:
                //actions
                break;

            case State2:
                //other actions 
                break;
        }

        if (reading == 0)
        {
            SystemState = State1;
        }
        else
        {
            SystemState = State2;
        }

    }
}

然后,在switch语句中,您的SystemState变量将始终为State1.

当然,请记住,以您现在编写代码的方式,reading无法接收任何输入。您需要提供reading一种获得价值的方法。

于 2017-01-17T07:20:26.970 回答
0

IF 和 SWITCH 语句的顺序在 OP 示例中并不重要。在有限状态机中,对于每一个不同的状态,机器都会执行一组特定的操作。从一种状态到另一种状态的转换在概念上是分开的,但通常由相同的代码执行:这样,在某些状态下可以检查一组输入(而忽略其他状态),而在另一种状态下可以检查一组不同的输入检查。在检查的输入中,其中一个可以触发状态更改。

假设您有一个电机、一个启动按钮、一个停止按钮和一个用于设置电机速度的旋钮。当您按下 START 时,电机以旋钮设置的速度转动。当您按下 STOP 时,电机停止(直到再次按下 START)。本机有两种状态:STOPPED 和 RUNNING。Motor、Knob、Start 和 Stop 都是另一个线程关心读取或设置的 I/O。伪代码将是这样的。

STATE = STOPPED;
while (1) {
  switch (STATE) {

    case STOPPED:
      Motor = 0;   // the motor does not turn
      if (Start) STATE = RUNNING;
      break;

    case RUNNING:
      Motor = Knob;   // rotate with the speed given by Knob
      if (Stop) STATE = STOPPED;
      break;

  } // end switch
} // end of forever cycle

现在,想象一下电机必须进行斜升和斜降。可以添加两种状态,ACCEL 和 DECEL。在 STOPPED 状态下,代码检查 Start 是否被按下;如果是,则新状态变为 ACCEL。在 ACCEL 状态下,Motor 的值会增加,直到达到 Knob 的值。DECEL 状态也是如此,为简洁起见,我将其省略。

请注意,在 ACCEL 状态期间,不会检查按钮。不能中断 ACCEL 阶段可能是完全合法的。如果阶段必须支持中断,则阶段 ACCEL 必须检查停止按钮。这就是状态机的美妙之处:您可以将复杂的事物分解为不同的阶段,并分别专注于它们。

将 IF 放在外部的想法switch也可以发挥作用,事实上,紧急/安全停止按钮应该这样处理:无论机器的状态如何,停止命令都应该停止机器。为简单起见,这可以在状态机的正常流量之外完成:当按下紧急按钮时,停止所有动作,关闭一切,并强制进入状态 STOPPED(或者,更好的是,需要更多用户注意的状态 EMERGENCY)。

如果整个while (1) {循环以最大速度执行,则将 IF 放在 SWITCH 之前或之后没有区别。相反,如果机器的整个逻辑运行在一个循环调用的例程中,比如每毫秒,那么if如果它放在switch. 但这无论如何都无关紧要,因为整台机器都有 1 毫秒的延迟。

于 2017-01-17T08:58:02.473 回答