рассуждения на тему state machine

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

Activity Автор
professor
professor
Сообщения: 3393
Зарегистрирован: 31 июл 2011, 23:05
Награды: 2
Версия LabVIEW: 12-18
Благодарил (а): 49 раз
Поблагодарили: 172 раза
Контактная информация:

Re: рассуждения на тему state machine

Сообщение Artem.spb »

Borjomy_1 писал(а):
Если брать одну очередь, то придётся парсить.
Ну парсить. Как будто это так сложно! Есть в конце концов, известный класс Taskings2.
да ничего сложного, дело вкуса, в данном случае мне нравится event. Под RT я предпочитаю очереди.
События можно обрабатывать каждое в своём кейсе, при этом все кейсы собраны в одну структуру
Моя практика говорит о том, что для серьезных задач так делать категорически нельзя (просто потом все равно придется переделывать). И вот почему: когда вы в событии должны выполнять работу со внешним устройством, вы должны быть готовы, что этот обмен выполняется неопределенное время.
Вы читаете написанное, или просто отвечает по принципу "надо покритиковать"?
Где я написал, что всё запихано в один цикл? Повторю свою мысль:
В принципе именно необходимость обрабатывать действия пользователя и привела сначала к использованию event (контролы), а позже к ним добавились события, генерируемые параллельными потоками (те самые потоки взаимодействия с железом).
rbl писал(а):
Artem.spb писал(а): Если брать одну очередь, то придётся парсить.
Что плохого в парсере?
например, потребность изменить тип передаваемых данных и добавление новых команд. При обработке строк могут проскочить ошибки. Вот чем мне нравится :labview: , так это тем, что изменив что-то в контроле, я практически автоматом получаю корректировку всех связанных вещей. А вот изменив отправляемую строку, я могу что-то пропустить. Впрочем, вопрос решается использованием typedef.
В чем профит усложнения структуры - я категорически не понимаю.
где именно вы видите усложение? Использование нескольких "почтальонов" для доставки сообщение от разных адресатов одному получателю? Дело вкуса.
Kosist писал(а):
Vitekkz88 писал(а):"Что лучше? очереди или User Event" тема древняя, на форуме офицалов разработчики не давали однозначного ответа, что лучше.
По моему, все зависит от того, что нужно делать. Не стоит забывать, что User Event - это Multiply Readers, Multiply Writers; а очередя - это Multiply Writer, Single Reader.
эта особенность событий и привлекает меня. Отправил одно событие "чуваки, меняем язык", и все открытые окна переименовали контролы. Отправили "суши вёсла", и все завершили работу.
А с очередями? ну вот у меня сейчас проект на 20+ одновременно открытых окон (это желание заказчика, я отговаривал). Будете 20 очередей в цикле обрабатывать? Да, можно. И да, дело вкуса.

Впрочем, есть ещё аргумент против очередей с парсером. Есть у меня некое предубеждение против строк, идущее с тех самых пор, как я вычитал механизмы их обработки. Та же справка NI рекомендует по возможности при хитрой работе со строками переводить их в массив U8.
Kosist писал(а):А что мешает создать для каждого источника данных свой кейс при использовании очередей? У Вас что так, что так получается дубликация кода. По такой логике, Вы же можете и через один User Events передавать данные + их источник, и делать парсинг. Но так не делаете, т.к. на каждый источник у Вас свой юзер евент. Но ведь то же самое можно сделать с очередью - через одну очередь передавать данные с разных источников на разные страницы кейс-структуры.
а если вы желаете в этом же цикле обрабатывать часть контролов на экране? если кнопка обрабатывается за миллисекунды (не требует диалога с пользователем), и при этом влияет на SM, то вполне логично её расположить тут же. Мне не нравится схема "UI отловил событие -> поставил в очередь команду -> её отработала SM", это на мой взгляд и есть усложнение кода.
Впрочем, тут двояко. Упростив в одном месте, усложняем в другом. Дело баланса и вопрос вкуса.
По events: с какой целью они были реализованы в DAQmx? А что кто то, где то, как то не смог пробиться к events structure, так это ни как не указывает на ее мифические недостатки, а говорит только об уровне программиста.
Ага.. Только NI не рекомендует использовать несколько Events Structure, запущенных одновременно (это ведь уже проходили - в зависимости от того, какая структура активна, ей и идут возникающие события).
Вы не смешиваете всё в кучу?
NI не то чтобы не рекомендует, а категорически настаивает не располагать несколько event-структур в одном цикле. В вот параллельно работающие структуры в разных циклах никто не запрещал. Если я ошибаюсь, пришлите ссылку, будет полезно освежить теорию.
и что значит "в зависимости от того, какая структура активна"? Структура "активна" всегда, она коллекционирует события, пока её не скажут прекратить делать это (unregister event). Причём не важно, "прошли" мы этот участок кода, или ещё не дошли до него. А вот обработка события зависит именно от активности участка кода. Именно в этом контексте нельзя параллелить event-структуры.
Я что-то User Events не встречал DAQmx. Он принимает их или выдает?
Возможно, это недавнее нововведение. по крайней мере я только недавно наткнулся на эти функции.
Есть несколько типов событий, генерирующих оповещение. В частности "данные пришли в буфер". Т.е. не надо подвешивать DAQmx read с таймаутом, можно параллельно другими делами заниматься (обрабатывать другие события), а по приходу оповещения считать готовые данные.
Но на мой взгляд реализация сырая. В частности, зарегистрировать событие можно только для запущенной задачи. Так что реализация схемы с стоп-пуск задачи по команде SM затрудняется. Я нашёл, как это сделать, но вариант мне не сильно нравится, я даже думал не извращаться, но всё же желание опробовать новый механизм одержало победу.
Blackman

Activity
leader
leader
Сообщения: 932
Зарегистрирован: 17 янв 2016, 15:02
Награды: 1
Версия LabVIEW: 6.1,8.5,20

Re: рассуждения на тему state machine

Сообщение Blackman »

Borjomy_1! Вы когда последний раз VIPM юзали? Там теперь даже кнопка есть "Abort Current Operation" для нетерпеливых пользователей)
Для DAQmx речь шла о динамически регистрируемых событиях, например "Done". Причем здесь User Events?
Не путайте регистрацию одного и того же статического события в 2 и более Event структурах на одной BD (что и не рекомендует NI) и динамическую регистрацию одного и того же события на любом количестве Event структур, независимо от того где они находятся. При возникновении этого события все структуры его успешно обработают.
alex3f
beginner
beginner
Сообщения: 26
Зарегистрирован: 23 авг 2016, 09:16
Версия LabVIEW: 2016
Контактная информация:

Re: рассуждения на тему state machine

Сообщение alex3f »

А так же, кто и как часто пользуется в LabVIEW семафорами, например.
Vitekkz88, я пользуюсь во всех проектах с источниками питания (а таких большинство). Обычно обращаюсь к источникам из двух разных потоков. В одном потоке, где идёт последовательность тестов, происходит управление режимом работы источника. В другом потоке происходит постоянный мониторинг работы источника: вывод на лицевую панель напряжения, тока, мощности, и проверка "в режиме перегрузки прибор"? Если прибор в режиме перегрузки более 2-х секунд, то питание от тестируемого изделия отключается. И для того чтобы одновременно из разных потоков не обратиться к источникам и использую семафоры.
Borjomy_1

Activity Professionalism Silver
doctor
doctor
Сообщения: 2210
Зарегистрирован: 28 июн 2012, 09:32
Награды: 3
Версия LabVIEW: 2009..2020
Откуда: город семи холмов
Благодарил (а): 27 раз
Поблагодарили: 26 раз

Re: рассуждения на тему state machine

Сообщение Borjomy_1 »

Будете 20 очередей в цикле обрабатывать?
Каждой очереди свой цикл. Если невозможно их совместить.
Artem.spb

Activity Автор
professor
professor
Сообщения: 3393
Зарегистрирован: 31 июл 2011, 23:05
Награды: 2
Версия LabVIEW: 12-18
Благодарил (а): 49 раз
Поблагодарили: 172 раза
Контактная информация:

Re: рассуждения на тему state machine

Сообщение Artem.spb »

Borjomy_1 писал(а):
Будете 20 очередей в цикле обрабатывать?
Каждой очереди свой цикл. Если невозможно их совместить.
это как и зачем? я имел ввиду необходимость оповестить все окна об одном и том же событии (например, смена языка интерфейса). из одного источника (например, МС). В этом случае при использовании очередей мне придётся одну и ту же команду отправить в 20 очередей. А с событиями я генерирую одно событие, которое разлетится ко всем получателям.
Borjomy_1

Activity Professionalism Silver
doctor
doctor
Сообщения: 2210
Зарегистрирован: 28 июн 2012, 09:32
Награды: 3
Версия LabVIEW: 2009..2020
Откуда: город семи холмов
Благодарил (а): 27 раз
Поблагодарили: 26 раз

Re: рассуждения на тему state machine

Сообщение Borjomy_1 »

это как и зачем? я имел ввиду необходимость оповестить все окна об одном и том же событии (например, смена языка интерфейса). из одного источника (например, МС). В этом случае при использовании очередей мне придётся одну и ту же команду отправить в 20 очередей. А с событиями я генерирую одно событие, которое разлетится ко всем получателям.
Средствами класса Taskings2 это реализуется одним вызовом...
Кстати, если User Event делать типом String+Код операции, то можно обойтись одним эвентом на всех. А если еще добавить признак глобальной команды, то ваще всё еще упрощается.
Хотя внутри, стопудово, Event реализуется через массив очередей
Artem.spb

Activity Автор
professor
professor
Сообщения: 3393
Зарегистрирован: 31 июл 2011, 23:05
Награды: 2
Версия LabVIEW: 12-18
Благодарил (а): 49 раз
Поблагодарили: 172 раза
Контактная информация:

Re: рассуждения на тему state machine

Сообщение Artem.spb »

Borjomy_1 писал(а):Кстати, если User Event делать типом String+Код операции, то можно обойтись одним эвентом на всех.
мне иногда кажется, что я изъясняюсь на иностранном языке, потому что переписка выглядит примерно так:
я: я предпочитаю вариант А+Б
комментарий: а ещё можно сделать А+Б
А если еще добавить признак глобальной команды, то ваще всё еще упрощается.
не упрощается, а усложняется, потому что получаем кейс в кейсе и тот же самый парсер. Сначала кейс события, потом кейс обработки команды. Тогда уж действительно проще очередями пользоваться.
Хотя внутри, стопудово, Event реализуется через массив очередей
если даже так, то эти очереди сильно прокачаны, что облегчает работу с контролами да ещё и работу с несколькими "очередями" в одной структуре.
AlexanderKonoval
developer
developer
Сообщения: 257
Зарегистрирован: 03 янв 2014, 19:37
Версия LabVIEW: 2016
Откуда: Украина, Киев
Контактная информация:

Re: рассуждения на тему state machine

Сообщение AlexanderKonoval »

Artem.spb писал(а):
Я решаю эту задачу так:
на каждый тип железяки своя машина состояний отдельно для этой железяки. Занимается только обработкой данных от железяки. Принимает команды по очереди от "ядра". По факту обработки данных с железяки генерирует юзверь-ивент. Мыслю как железяку переделать на юзверь-ивенты тоже, но пока не придумал красиво.

Обработчик юзверь-ивентов обрабатывает эти самые ивенты. Он смотрит на полученные в ивенте данные, на общее состояние системы и соответственно реагирует.

Интерфейс работает отдельно. У нас это вообще отдельный экзешник, который общается с бэк-эндом по ТСП/ИП. Аналогично генерирует ивенты для обработчика ивентов, который по необходимости рассылает команды на модули. но это сделано ради красивых юзверь-фрэндли интерфейсов на других языках программирования, для нас важна красота и стильность :crazy:

По факту имеем очень гибкую структуру, идеальную для длительной поддержки, в ходе которой может измениться железо, потребуется новый функционал и т.д.

В топике ещё за семафоры спрашивали. Я юзаю, но нечасто. Иногда удобно. конкретные кейсы поднимать лениво, но в большинстве это связано как раз с юзверь-интерфейсами и общением с железом. К примеру, система инициализируется, заняли светофор. крутим вместо указателя мышки загрузку. быстрее и нагляднее, чем делать булевою переменную и т.д.
колдооооовствооооо! (С)
Artem.spb

Activity Автор
professor
professor
Сообщения: 3393
Зарегистрирован: 31 июл 2011, 23:05
Награды: 2
Версия LabVIEW: 12-18
Благодарил (а): 49 раз
Поблагодарили: 172 раза
Контактная информация:

Re: рассуждения на тему state machine

Сообщение Artem.spb »

AlexanderKonoval писал(а):. Мыслю как железяку переделать на юзверь-ивенты тоже, но пока не придумал красиво.
а в чём сложность заменить всё на события? суть от этого не изменится.
AlexanderKonoval
developer
developer
Сообщения: 257
Зарегистрирован: 03 янв 2014, 19:37
Версия LabVIEW: 2016
Откуда: Украина, Киев
Контактная информация:

Re: рассуждения на тему state machine

Сообщение AlexanderKonoval »

Artem.spb писал(а):
AlexanderKonoval писал(а):. Мыслю как железяку переделать на юзверь-ивенты тоже, но пока не придумал красиво.
а в чём сложность заменить всё на события? суть от этого не изменится.
да, по сути, ни в чём. Просто уже есть определённые интерфейсы на железо, с енум-тайпдефами команд (включить, выключить, перезапустить, и т.д.) и не вижу особого смысла переделывать это на юзер-ивенты. По сути, смысл есть только для одной железяки.
По сути, у меня на каждую железяку своя очередь со своими енум-тайпдеф. В каждом енуме 5-15 элементов. То есть, надо будет делать 5-15 юзверь-ивентов. Больше времени на реализацию, при этом сомнительна целесообразность.
Поэтому пока что железяки у меня работают на обычной машине состояний, а система в целом - на обработчике ивентов.
колдооооовствооооо! (С)
Аватара пользователя
Kosist

Activity Gold
expert
expert
Сообщения: 1236
Зарегистрирован: 21 фев 2011, 23:44
Награды: 2
Версия LabVIEW: 2013-2020
Благодарил (а): 23 раза
Поблагодарили: 30 раз
Контактная информация:

Re: рассуждения на тему state machine

Сообщение Kosist »

AlexanderKonoval писал(а):да, по сути, ни в чём. Просто уже есть определённые интерфейсы на железо, с енум-тайпдефами команд (включить, выключить, перезапустить, и т.д.) и не вижу особого смысла переделывать это на юзер-ивенты. По сути, смысл есть только для одной железяки.
По сути, у меня на каждую железяку своя очередь со своими енум-тайпдеф. В каждом енуме 5-15 элементов. То есть, надо будет делать 5-15 юзверь-ивентов. Больше времени на реализацию, при этом сомнительна целесообразность.
Поэтому пока что железяки у меня работают на обычной машине состояний, а система в целом - на обработчике ивентов.
На каждую железяку свой енум-тайпдеф таскать? А зачем? Я пришел к тому, что лучше использовать для очередей, в качестве названия стейта строку, а не енум-тайпдеф. Повышается реюзабилити, так сказать, плюс остальные выгоды есть - я для пробы пера расписал был это здесь - http://kosist.org/2016/11/labview-queue ... or-string/. Но, само собой, вопрос спорный + дело привычки/вкуса.
Мы делили апельсин - много наших полегло...
Аватара пользователя
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 »

Kosist писал(а):Я пришел к тому, что лучше использовать для очередей, в качестве названия стейта строку, а не енум-тайпдеф.
Достоинство Enum TypeDef, это обновление во всех местах и практически исключение ошибки, в строке пробел лишний поставил случайно и будешь час гонять ошибку искать.

Вот например на Enum сделано. На скрине как раз ошибка видна "Windows..." и это не мешает нормально функционировать :D
И состояния не все видны, не влезли....
Без имени.png
Аватара пользователя
Kosist

Activity Gold
expert
expert
Сообщения: 1236
Зарегистрирован: 21 фев 2011, 23:44
Награды: 2
Версия LabVIEW: 2013-2020
Благодарил (а): 23 раза
Поблагодарили: 30 раз
Контактная информация:

Re: рассуждения на тему state machine

Сообщение Kosist »

IvanLis писал(а):
Kosist писал(а):Я пришел к тому, что лучше использовать для очередей, в качестве названия стейта строку, а не енум-тайпдеф.
Достоинство Enum TypeDef, это обновление во всех местах и практически исключение ошибки, в строке пробел лишний поставил случайно и будешь час гонять ошибку искать.

Вот например на Enum сделано. На скрине как раз ошибка видна "Windows..." и это не мешает нормально функционировать :D
И состояния не все видны, не влезли....
Понятно, что не мешает функционировать :wink:
Лишний пробел "ловится" дефолтным стейтом в стейт машине. А найти, откуда этот стейт пришел, не составит труда при продуманной архитектуре...
А вообще, повторюсь - все это дело привычки, стиля, предпочтений.
Мы делили апельсин - много наших полегло...
Ответить

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