我正在编写练习有限状态机代码,无法绕过我的“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;
}
}
}
该代码旨在实时获取传感器数据并做出相应的响应。我意识到这不是实际运行的代码,但我希望,因为问题是理论上我现在的代码就足够了。如果我遗失任何东西,请告诉我。
谢谢!
答案 0 :(得分:1)
无法绕过我的“Switch”和“if”语句(应该首先出现)的顺序。
您的switch
语句会检查SystemState
变量的值,该变量是通过if
语句设置的。因此,正确的顺序是使用if
语句,以便variable takes the desired value, and then examine the value of SystemState
语句中的SystemState switch
。
假设您有相反的if
和switch
语句,如下所示:
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毫秒。