Переключить и если порядок заявлений (Робот 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;
}
}
}
Код предназначен для получения данных датчика в режиме реального времени и соответствующего реагирования. Я понимаю, что это не совсем действующий код, но я надеюсь, что, поскольку вопрос теоретический, моего текущего кода будет достаточно. Пожалуйста, дайте мне знать, если я что-то упустил.
Спасибо!
2 ответа
не могу обернуть голову вокруг порядка моих операторов "Switch" и "if" (которые должны стоять первыми).
Ваш switch
В заявлении рассматривается ценность SystemState
переменная, которая устанавливается через ваш if
заявление. Таким образом, правильный порядок должен иметь ваш if
заявление, так что SystemStatevariable takes the desired value, and then examine the value of 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
способ получить значение.
Порядок операторов IF и SWITCH в примере OP не важен. В конечном автомате для каждого отдельного состояния машина выполняет определенный набор операций. Переход из одного состояния в другое концептуально разделено, но часто выполняется одним и тем же кодом: таким образом, в каком-то состоянии набор входов может быть проверен (а другие проигнорированы), а в другом состоянии может быть другой набор входов. проверено. Среди проверенных входов один из них может инициировать изменение состояния.
Предположим, у вас есть двигатель, кнопка запуска, кнопка остановки и ручка для установки скорости двигателя. Когда вы нажимаете START, двигатель вращается со скоростью, установленной ручкой. Когда вы нажимаете STOP, двигатель останавливается (пока снова не будет нажата кнопка START). Эта машина имеет два состояния: ОСТАНОВЛЕНО и РАБОТАЕТ. Motor, Knob, Start и Stop - это входы / выходы, которые другой поток хочет прочитать или установить. Псевдокод будет таким.
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 увеличивается, пока не достигнет значения регулятора. То же самое относится и к состоянию DECEL, для краткости я его опускаю.
Обратите внимание, что в состоянии ACCEL кнопки НЕ проверяются. Можно было бы совершенно законно сказать, что этап ACCEL не должен прерываться. Если фаза должна поддерживать прерывание, то фаза ACCEL должна проверить кнопку "Стоп". В этом прелесть конечного автомата: вы можете разбивать сложные вещи на разных этапах и концентрироваться на них по отдельности.
Идея поставить IF вне switch
может также играть роль, и на самом деле, кнопки аварийного / безопасного останова должны обрабатываться следующим образом: независимо от состояния машины, команда останова должна остановить машину. Для простоты это можно сделать за пределами обычного потока конечного автомата: когда нажата аварийная кнопка, останавливайте каждое движение, выключайте все и форсируйте состояние STOPPED (или, что еще лучше, аварийное состояние, которое требует большего внимания пользователя).
Если весь while (1) {
Цикл выполняется на максимальной скорости, нет разницы в установке ПЧ до ПЕРЕКЛЮЧАТЕЛЯ или после. Если вместо этого вся логика машины выполняется внутри подпрограммы, которая вызывается циклически, скажем, каждую миллисекунду, то if
может быть выполнен на 1 миллисекунду раньше, если его поставить перед switch
, Но в любом случае это не имеет большого значения, потому что вся машина страдает задержкой в 1 миллисекунду.