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

时间:2017-01-17 07:07:39

标签: c switch-statement state-machine robotc

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

该代码旨在实时获取传感器数据并做出相应的响应。我意识到这不是实际运行的代码,但我希望,因为问题是理论上我现在的代码就足够了。如果我遗失任何东西,请告诉我。

谢谢!

2 个答案:

答案 0 :(得分:1)

  

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

您的switch语句会检查SystemState变量的值,该变量是通过if语句设置的。因此,正确的顺序是使用if语句,以便variable takes the desired value, and then examine the value of SystemState语句中的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提供获取值的方法。

答案 1 :(得分:0)

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

假设您有一个电机,一个启动按钮,一个停止按钮和一个用于设置电机速度的旋钮。按START键时,电机以旋钮设定的速度旋转。按STOP键时,电机停止(直到再次按下START)。本机有两种状态:STOPPED和RUNNING。电机,旋钮,启动和停止都是另一个线程需要读取或设置的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之外的想法也可以发挥作用,事实上,紧急/安全停止按钮应该这样对待:无论机器的状态如何,停止命令都应该停止机器。为简单起见,这可以在状态机的正常通量之外完成:当按下紧急按钮时停止每个动作,关闭所有动作,并强制状态停止(或者更好的是,需要更多用户注意的状态紧急情况)。

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