Вопрос про State Machine

Общие принципы, проектирование, модуляризация, темплейты и шаблоны
Ответить
Аватара пользователя
FireFly

Activity Black
expert
expert
Сообщения: 1321
Зарегистрирован: 25 апр 2009, 08:58
Награды: 2
Версия LabVIEW: 2014
Откуда: Санкт-Петербург
Поблагодарили: 1 раз

Вопрос про State Machine

Сообщение FireFly »

Очередной (на мой взгляд) глупый вопрос от меня. Но т.к. с английским у меня совсем плохо (это я про статьи NI), то буду спрашивать тут по-русски :)
Итак вопрос: как правильно делать State Machine с неким содержимым имеющим инициализацию и закрытие (LV Class, Открытие файла, VISA ну и т.п.)? В этом случае провода для них начинаются с левой стороны цикла (обычно из Shift Register) и заканчиваются на правой стороне цикла. Ну и суть вопроса в том как правильно эти провода начать и закончить? В соответствующих Case "INIT" и "EXIT" или снаружи цикла?
Если снаружи то как-то теряется гармония State Machine...
А внутри кажется неправильным... И возникают проблемы с "правой стороной", т.е. что подавать на выходные тунели Case "EXIT" и что делать с Shift Register после цикла?

Следуюший вопрос - правильно ли использовать в State Machine на селекторе константу типа Enum? Она делает селектор и Case очень наглядными (текст в заголовке Case легко объясняет смысл этого Case). Но у меня уже развилась некая боязнь, что даже в самых простых вопросах есть свои подводные камни.
Ну и наконец что делать если вдруг уже в готовой программе возникла необходимость вставить ещё один State? Добавив один элемент в State селектор стоящий перед циклом (у меня это обычно Enum константа) приходится пересоздавать Shift Register и менять селектор во всех остальных Case. Или я что-то недогоняю?

В приложенных картинках два примера State Machine объясняющих мой первый вопрос.
Вложения
Вариант 1
Вариант 1
1_1.PNG (8.12 КБ) 10355 просмотров
Вариант 1
Вариант 1
1_2.PNG (8.16 КБ) 10355 просмотров
Иногда лучше молчать и слыть идиотом, чем заговорить и развеять все сомнения.
Аватара пользователя
FireFly

Activity Black
expert
expert
Сообщения: 1321
Зарегистрирован: 25 апр 2009, 08:58
Награды: 2
Версия LabVIEW: 2014
Откуда: Санкт-Петербург
Поблагодарили: 1 раз

Re: Вопрос про State Machine

Сообщение FireFly »

Вариант 2 не влез :)
Вложения
Вариант 2
Вариант 2
2_1.PNG (6.86 КБ) 10353 просмотра
Вариант 2
Вариант 2
2_2.PNG (6.47 КБ) 10353 просмотра
Вариант 2
Вариант 2
2_3.PNG (6.42 КБ) 10353 просмотра
Вариант 2
Вариант 2
2_4.PNG (6.36 КБ) 10353 просмотра
Иногда лучше молчать и слыть идиотом, чем заговорить и развеять все сомнения.
Аватара пользователя
Eugen Graf

Activity Professionalism Silver Black
guru
guru
Сообщения: 6502
Зарегистрирован: 13 ноя 2007, 02:20
Награды: 4
Версия LabVIEW: 2009
Откуда: Saarbrücken
Контактная информация:

Re: Вопрос про State Machine

Сообщение Eugen Graf »

1. Как захочешь, так и делай. У меня обычно Init и Close вне цикла, я не уважаю неинициализированные сдвиг. регистры (и обрубки вообще). Если используется LV Class то константу создаёшь вне цикла, а инициализацию в первом стейте.
2. Да, правильно. Она как нельзя лучше подходит для этого.
3. Тебе нужно сделать Typedef Control из твоего Enum, тогда никаких проблем с добавлениями стейтов не будет.

Кстати таким типом стейт машины я не пользуюсь, вместо этого намного лучше и удобнее Queued State Machine.
В этом примере я не использую Enum, на входе Case, а использую String-команды.
State_Machine.png
А вот тут Enum на входе Case селектора. Как видишь Exit находится внутри цикла, а Init отсутствует по некоторым причинам.
State_Enum.png
Аватара пользователя
mzu2006

Professionalism Tutorials Black
doctor
doctor
Сообщения: 2456
Зарегистрирован: 16 авг 2008, 02:12
Награды: 3
Версия LabVIEW: 7.1 10 11 12
Откуда: St-Petersburg (RU), Phila, Boston, Washington DC
Контактная информация:

Re: Вопрос про State Machine

Сообщение mzu2006 »

С инициализацией предпочитаю разбираться внутри специального состояния "Init". В основном потому, что иногда может потребоваться повторить инициализацию без перезапуска проги. Например после ошибки может быть хорошей идеей закрыть и открыть файл/дескриптор прибора итд итп. Моя любимая кнопка, которую я ставлю во многие свои интерфейсы называется "purge", которая даёт команду реинициализироваться всем конечным автоматам. Кроме того, так проще выделять их в отдельные subVI.
В твоём же примере, ты используешь control, гду указываешь путь к файлу, внутри конечного автомата, явно не предназначенного для обработки пользовательского интерфейса. Такое, IMHO, наружу.
Т.е. вообще я бы делал вариант 2, но в этом конкретном случае - 1.
Pavel

Activity
developer
developer
Сообщения: 271
Зарегистрирован: 31 июл 2009, 08:07
Награды: 1
Версия LabVIEW: 8.5

Re: Вопрос про State Machine

Сообщение Pavel »

imho все состояния должны быть внутри цикла на то она и машина состояний.
Аватара пользователя
IvanLis

Activity Professionalism Tutorials Gold Man of the year 2012
Автор
guru
guru
Сообщения: 5462
Зарегистрирован: 02 дек 2009, 17:44
Награды: 7
Версия LabVIEW: 2015, 2016
Откуда: СССР
Благодарил (а): 28 раз
Поблагодарили: 86 раз

Re: Вопрос про State Machine

Сообщение IvanLis »

:haha: даже при программировании микроконтроллеров используется модель программирования "Машина состояний" (State Machine, Конечный автомат)

Код: Выделить всё

//first define states with obvious names and different values
#define START 0
#define RED 1
#define BLUE 2

//next define which pin is which
#define RED_PIN 9
#define BLUE_PIN 10

int state = START; //create state variable and initialize it to START state 3

void setup(){
   pinMode(RED_PIN, OUTPUT);
   pinMode(BLUE_PIN, OUTPUT);
   digitalWrite(BLUE_PIN,LOW); //turn blue led off
   digitalWrite(RED_PIN,LOW); //turn red led off
}

void loop(){
//FSM time
   switch(state){
  
      case START:
         digitalWrite(BLUE_PIN,LOW); //turn blue led off
         digitalWrite(RED_PIN,LOW); //turn red led off
         delay(100); //wait 100ms
         state = RED; //transition to red state
         break; //end of START case

      case RED:
         digitalWrite(BLUE_PIN,LOW); //turn blue led off
         digitalWrite(RED_PIN,HIGH); //turn red led on
         delay(200); //wait 200ms
         state = BLUE; //transition to blue state
         break; //end of RED case

      case BLUE:
         digitalWrite(RED_PIN,LOW); //turn red led off
         digitalWrite(BLUE_PIN,HIGH); //turn blue led on
         delay(200); //wait 200ms
         state = START; //transition to start state
         break; //end of BLUE case
   }
}
Это пример взятый отсюда:
Finite State Machines (FSM).pdf
(148.9 КБ) 325 скачиваний
Аватара пользователя
inmaze
user
user
Сообщения: 75
Зарегистрирован: 21 сен 2011, 10:43
Версия LabVIEW: 2011
Откуда: Dresden/Germany
Контактная информация:

Re: Вопрос про State Machine

Сообщение inmaze »

По поводу стейт машин:
Есть такая штука как JKI State Machine (см скриншот) - готовый шаблон, с строковым управлением, с возможностью постановки в очередь состояний.
В текущей работе использовал его. Находиться в опен сорсе (http://jki.net/state-machine). Если лень скачивать с официального сайта - библиотека прикреплена.

Офф топ:
Вопрос к Eugen Graf.
А в чем приемущество работы с классами (увидел на скриншоте) перед простыми Виай? В текущей программе реализовал общение с LakeShore'ом и Kiethley'ем тоже описав для них классы и методы. Но сделал это больше из интереса.
Вложения
jki.png
_jki_lib_state_machine.llb
(117.12 КБ) 312 скачиваний
AI233
user
user
Сообщения: 73
Зарегистрирован: 22 ноя 2011, 12:23
Версия LabVIEW: 2011
Контактная информация:

Re: Вопрос про State Machine

Сообщение AI233 »

Ну и наконец что делать если вдруг уже в готовой программе возникла необходимость вставить ещё один State? Добавив один элемент в State селектор стоящий перед циклом (у меня это обычно Enum константа) приходится пересоздавать Shift Register и менять селектор во всех остальных Case. Или я что-то недогоняю?
Меня это тоже бесит. Лучше использовать простую текстовою константу, а в шапке кейса значения ручками прописывать.
AndreyDmitriev

Activity Professionalism Tutorials Gold Black
VIP
VIP
Сообщения: 1327
Зарегистрирован: 03 фев 2010, 00:42
Награды: 6
Версия LabVIEW: 6.1 - 2024
Откуда: Германия
Благодарил (а): 1 раз
Поблагодарили: 38 раз
Контактная информация:

Re: Вопрос про State Machine

Сообщение AndreyDmitriev »

AI233 писал(а):
Ну и наконец что делать если вдруг уже в готовой программе возникла необходимость вставить ещё один State? Добавив один элемент в State селектор стоящий перед циклом (у меня это обычно Enum константа) приходится пересоздавать Shift Register и менять селектор во всех остальных Case. Или я что-то недогоняю?
Меня это тоже бесит. Лучше использовать простую текстовою константу, а в шапке кейса значения ручками прописывать.
Коллеги, вы что?! Enum обязательно должен быть Typedefом!
AI233
user
user
Сообщения: 73
Зарегистрирован: 22 ноя 2011, 12:23
Версия LabVIEW: 2011
Контактная информация:

Re: Вопрос про State Machine

Сообщение AI233 »

AndreyDmitriev писал(а): Коллеги, вы что?! Enum обязательно должен быть Typedefом!
Ах вот зачем эта фича нужна :crazy:
Ответить
  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Модели программирования»