switch 和 if 语句顺序(机器人 C)

switch and if statement order (Robot C)

我正在编写练习有限状态机代码,无法理解我的 "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;
        }
    }
}

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

谢谢!

can't wrap my head around the order of my "Switch" and "if" statements (which should come first).

您的 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 一个获取值的方法。

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

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

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

现在,假设电机必须执行 ramp-up 和 ramp-down。可以添加两个状态,ACCEL 和 DECEL。在 STOPPED 状态下,代码检查 Start 是否被按下;如果是,则新状态变为 ACCEL。在 ACCEL 状态下,Motor 的值增加,直到达到 Knob 的值。对于 DECEL 状态也是如此,为了简洁起见,我将其省略。

请注意,在 ACCEL 状态下,按钮未被选中。说 ACCEL 阶段不能被打断是完全合法的。如果阶段必须支持中断,则阶段 ACCEL 必须检查停止按钮。这就是状态机的美妙之处:你可以将一个复杂的事物分解成不同的阶段,然后分别专注于它们。

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

如果整个while (1) {循环都以最大速度执行,IF放在SWITCH之前或之后没有区别。相反,如果机器的整个逻辑在循环调用的例程中运行,比如说,每毫秒调用一次,那么 if 如果放在 switch 之前,则可以提前 1 毫秒执行。不过这也没什么大不了的,因为整台机器都有1毫秒的延迟。