В этом смысле мне очень нравится цитата из книги Ha-Joon Chang "Economics:The User's Guide"
экономическая теория никогда не станет наукой в том смысле, какой мы подразумеваем, говоря о физике или химии. Существует множество различных школ экономической теории, каждая из которых подчеркивает различные аспекты сложной реальности, высказывая различные этические и политические оценочные суждения и делая на их основе те или иные выводы. Кроме того, ни одна из школ экономической теории еще ни разу не сумела предсказать реальное развитие событий даже в тех областях, на которые ориентирована, не в последнюю очередь потому, что у людей есть собственные желания — в отличие от молекул или физических объектов
Тут вы просто противоречите повсеместному эмпирическому опыту.
Свой код от Claude я тоже могу объявить библиотекой и сказать какие у него незаменимые фичи типа: "поля можно объявить optional с дефолтами". Он ракетой такие либы умеет делать. Хуже. Что ни попроси, он всегда накидывает лишнего API, чтобы сразу полная либа получилась.
Вообще, где доказательства, что ваша либа не от Claude или чего-то подобного? Бросайте это. Либы на коленке в ближайшие тысячу лет никому не будут нужны. Лучше опубликуйте полезное приложение с применением JSON. Вот тогда будет понятно, что имеем дело с человеческим трудом.
Извините, не знал что вы разработчик всех "индустриальных MCU/RTOS-проектов". Шучу.
В реальности есть постоянная проблема когда новая версия JSON не повторяет старую. У меня, скажем, в индустриальной системе JSON меняется каждую неделю! Почему я должен держаться за формат который устарел?
А у тому клоню, что нет нынче никакой необходимости создавать обертки над такими эффективными и прозрачными либами как jansson. Claude создаст весь прикладной код на лету на нативном API и под любой вкус. Была бы ему либа эта вся задокументрирована.
А вот когда одна либа поверх другой, а та поверх третьей, вот тут вы реально стреляете себе в ногу. Раздуваете контекст, усложняете работу агентам и запутываете их. Потом остается только пенять на заточенность под "STL, шаблоны и типичные C++-механизмы"
Автоматический папинг делает кодирующий агент, я же написал. Агенты это делают превосходно. А у вас псевдоавтоматизм. Поскольку структуру JSON надо знать заранее.
Куча: все JSON-объекты (json_object, json_array, строки и т.п.) аллоцируются через malloc. malloc надо портировать через свое API, поэтому тут свобода реализации. В ThreadX, например malloc умеет делать статистику и ожидать освобождения памяти заданное время.
Каждая строка хранится отдельно (длина + копия текста). Сколько сырой JSON без пробелов занимает, столько памяти приблизительно и нужно будет
По стеку. Там рекурсивный парсинг. Одна функция разбора (parse_value/parse_object/parse_array) тянет локальные переменные порядка 16–32 байт. Глубина рекурсии = глубине вложенности JSON. Но это контролируется, потому что глубину разбора задает макрос.
За скорость не скажу, там главный тормоз - медианоситель.
Непонятно что тут означает "контролируемая работа с памятью". Если есть неизвестный JSON в котором надо что-то выловить, то парсить дерево нужно. И без динамической памяти никак. И откуда там утечки если библиотека протестирована. Динамическая память - это всегда фрагментация, и риск потери чистой памяти. Но проблема решается элементарно просто наложением мьютека на выделение памяти другими задачами на время парсинга JSON. Я бы конечно рекомендовал https://github.com/akheron/jansson В современной реальности самые лучшие библиотеке - это те что понятны и доступны для кодирующих агентов. Так вот с jansson агент Claude работает безукоризненно. Может построить парсигн и генерацию любого дерева. Делает практически безошибочно. Это то, что агенты с самого начала научились хорошо делать.
Это ни о чем. Где сравнение с реальными GPS модулями. Где расходы трасивера на связь с облаком? Где расходы на работу процессора, шифрацию и прочие? А на джаминг?
Claude Sonnet в качестве агента стал нормально кодить всего несколько месяцев назад. Функция делегирования агенту в облака на сам GitHub скажем в GitHub Copilot появилось вообще пару дней назад.
А главное - агенты еще очень медленно работают. Ожидание в пару минут на простые запросы просто тормозит работу. Никогда не угадаеш когда он тормознет. Да и сборщики еще очень медленные.
Ну и наконец, промптинг не имеет никакого значения. В скорости разработки имеет значение подстройка агентских инструментов, инструкций и MCP серверов под свой рабочий процесс. Именно от этого зависит сколько бесплодных попыток что-то сделать будут тратить агенты и в какой бюджет это выльется.
Я считаю что ускорение с агентами реально достигает 5-10 раз. Но при условии отлаженного рабочего процесса и дорогого плана.
Тут надо бы еще телеметрию контактов реле делать. Т.е. диагностику залипаний. Про котлы не знаю, но тоже как-то странно брать от них только температуру и больше ничего.
Но самая песня тут будет с беспроводной связью. Говорят телеграмам на ладан дышит и во многих странах его собираются банить, сам телеграм может банить подозрительный нецелевой тафик. Как банят теперь емайлы. Но это не самое больное. Самое больное - это зависания точек доступа. Этому дивайсику следовало бы еще научится сбрасывать помимо котла еще и свою точку доступа. А еще научится как-то менять каналы W-Fi в поисках свободных. А лучше иметь резервные AP на объекте. Антенка тоже так себе, лучше бы внешнюю. Самое то смешное что дивайс должен стабильно работать при сбоях в электросети, но эти сбои даже миллисекундные и никем не замеченные первыми убивают роутеры.
Ардуина просто избыточна и переусложнена. У ардуин цель - образование. Поэтому там много лишнего в виде голых пинов, отдельных не адаптированых и не оптимальных плат и специфичных перенасыщенных абстрактных API библиотек. Открываешь страницу проекта Arduino и тебя сразу встречает море разных платок и модулей. С другой стороны экосистема ардуино скатывается в область индустриальных систем и там оказывается не имеет никаких преимуществ. Схема закрыта, микроконтроллер STM32H747XIH6 - сверхнавороченный, никакой ардуинщик не возьмется его изучать (а если возьмется, то перестанет быть ардуинщиком ). Проще напрямик взять референс дизайны у ST и делать на них.
Я как понял, ничего там не обрабатывается. AI еще не прекрутили и идей нет как прикрутить. И не будет в ближайшем будущем, поскольку AI до сих пор хорошо работает только в дискретном пространстве слов, а в физическом аналоговом мире он полный дуб. Да и отсчет в 10 мс - это ни о чем. Поэтому просто строят графики и выводят таблицы. Как и наши деды.
Не... Маркс утверждал, что норма прибыли у капиталистов со временем упадет и капитализм рухнет неизбежно. А Пикетти говорит, что норма прибыли и не думает падать и это фундаментальная константа, как скорость света в вакууме. А потому капитализм вечен. Пикетти - апологет капитализма, а Маркс - оппонент.
В этом сила гибридных схем. Да, они кажутся простыми и сразу понятными. Сразу ясно что там надо 100 строчек. А к Муру у вас сразу притензии. Не там поставил видиш ли надписи. Надо их куда убирать. А это рассеивает внимание и т.д.
Но вот вам на самом деле скрипт кторый скрывается за простенькими условиями типа Wrong Direction на диаграмме StateFlow (там уже 253 строки)
Скрипт MATLAB
function [IsOverCurrent, IsAccV_good, IsSysV_good, IsPSRC_ON, IsDischarging, IsPGood, IsWrongDirection] = ...
Charging_handler(CHRG_IN, CHRG_SETS)
% Charging_handler - Functions for charging system state monitoring
% This script implements the Stateflow functions for charging control
%
% Inputs:
% CHRG_IN - Structure containing charging input signals:
% .charge_current - Current charging current value
% .accum_voltage - Accumulator voltage value
% .system_voltage - System voltage value
% .power_src_current - Power source current value
% .discharge_current - Current discharge current value
% .charger_pgood - Charger power good signal
% CHRG_SETS - Structure containing charging settings:
% .accum_capacity - Accumulator capacity (Ah)
% .accum_idle_voltage - Accumulator idle voltage (V)
% .accum_max_voltage - Maximum accumulator voltage (V)
% .accum_max_current - Maximum accumulator current (A)
%
% Outputs:
% IsOverCurrent - TRUE if charging current exceeds maximum allowed
% IsAccV_good - TRUE if accumulator voltage is within valid range
% IsSysV_good - TRUE if system voltage is above minimum threshold
% IsPSRC_ON - TRUE if power source current is detected
% IsDischarging - TRUE if discharge current exceeds charge current for specified time
% IsPGood - TRUE if charger power good signal is active for specified time
% IsWrongDirection- TRUE if power flows in wrong direction (battery discharging while external power > 27V for 2 sec)
% --- Charging system settings (constants) ---
% Voltage thresholds
ACCUM_MIN_VOLTAGE = single(15.0); % Minimum accumulator voltage
SYSTEM_MIN_VOLTAGE = single(24.0); % Minimum system voltage
% Discharge detection settings
DISCHARGE_TIME_DELAY = int32(100); % Time delay for discharge detection (in 10ms ticks, 100 = 1 second)
% PGood detection settings
PGOOD_TIME_DELAY = int32(50); % Time delay for PGood detection (in 10ms ticks, 50 = 0.5 second)
% Wrong direction power flow detection settings
WRONG_DIR_VOLTAGE_THRESHOLD = single(27.0); % External power voltage threshold (V)
WRONG_DIR_TIME_DELAY = int32(200); % Time delay for wrong direction detection (in 10ms ticks, 200 = 2 seconds)
% --- Persistent variables for discharge timing ---
persistent discharge_timer discharge_active
persistent pgood_timer pgood_active pgood_reset_timer pgood_reset_active
persistent wrong_dir_timer wrong_dir_active
if isempty(discharge_timer)
discharge_timer = int32(0);
discharge_active = false;
pgood_timer = int32(0);
pgood_active = false;
pgood_reset_timer = int32(0);
pgood_reset_active = false;
wrong_dir_timer = int32(0);
wrong_dir_active = false;
end
%-------------------------------------------------------------
% IsOverCurrent - Check if charging current exceeds maximum
%-------------------------------------------------------------
IsOverCurrent = false;
if single(CHRG_IN.charge_current) > (single(CHRG_SETS.accum_max_current) + single(2.0))
IsOverCurrent = true;
end
%-------------------------------------------------------------
% IsAccV_good - Check if accumulator voltage is in valid range
%-------------------------------------------------------------
IsAccV_good = false;
if (single(CHRG_IN.accum_voltage) > ACCUM_MIN_VOLTAGE) && ...
(single(CHRG_IN.accum_voltage) < (single(CHRG_SETS.accum_max_voltage) + single(2.0)))
IsAccV_good = true;
end
%-------------------------------------------------------------
% IsSysV_good - Check if system voltage is above minimum
%-------------------------------------------------------------
IsSysV_good = false;
if single(CHRG_IN.system_voltage) > SYSTEM_MIN_VOLTAGE
IsSysV_good = true;
end
%-------------------------------------------------------------
% IsPSRC_ON - Check if power source is active
%-------------------------------------------------------------
IsPSRC_ON = false;
if single(CHRG_IN.power_src_current) > single(0)
IsPSRC_ON = true;
end
%-------------------------------------------------------------
% IsDischarging - Check if discharge current exceeds charge current for specified time
%-------------------------------------------------------------
persistent IsDischarging_state
if isempty(IsDischarging_state)
IsDischarging_state = false;
end
IsDischarging = IsDischarging_state;
% Check current state based on which current is higher
if single(CHRG_IN.discharge_current) > single(CHRG_IN.charge_current)
% Discharge current is higher - trending towards discharge state
if ~IsDischarging_state
% Currently in charging state, check if we should switch to discharge
if ~discharge_active
% Start timing for discharge state
discharge_active = true;
discharge_timer = int32(0);
else
% Increment timer (count 10ms ticks)
discharge_timer = discharge_timer + int32(1);
% Check if delay time has elapsed
if discharge_timer >= DISCHARGE_TIME_DELAY
IsDischarging_state = true;
IsDischarging = true;
discharge_active = false;
discharge_timer = int32(0);
end
end
else
% Already in discharge state - stay there
discharge_active = false;
discharge_timer = int32(0);
end
else
% Charge current is higher - trending towards charging state
if IsDischarging_state
% Currently in discharge state, check if we should switch to charging
if ~discharge_active
% Start timing for charging state
discharge_active = true;
discharge_timer = int32(0);
else
% Increment timer (count 10ms ticks)
discharge_timer = discharge_timer + int32(1);
% Check if delay time has elapsed
if discharge_timer >= DISCHARGE_TIME_DELAY
IsDischarging_state = false;
IsDischarging = false;
discharge_active = false;
discharge_timer = int32(0);
end
end
else
% Already in charging state - stay there
discharge_active = false;
discharge_timer = int32(0);
end
end
%-------------------------------------------------------------
% IsPGood - Check if charger power good signal is active for specified time
%-------------------------------------------------------------
persistent IsPGood_state
if isempty(IsPGood_state)
IsPGood_state = false;
end
IsPGood = IsPGood_state;
% Check if charger power good signal is active
if single(CHRG_IN.charger_pgood) > single(0)
% Reset the reset timer when pgood signal is active
pgood_reset_active = false;
pgood_reset_timer = int32(0);
if ~pgood_active
% Start timing when signal becomes active
pgood_active = true;
pgood_timer = int32(0);
else
% Increment timer (count 10ms ticks)
pgood_timer = pgood_timer + int32(1);
% Check if delay time has elapsed
if pgood_timer >= PGOOD_TIME_DELAY
IsPGood_state = true;
IsPGood = true;
end
end
else
% Signal is inactive - reset pgood timer
pgood_active = false;
pgood_timer = int32(0);
% Start reset timer only if currently in pgood state
if IsPGood_state
if ~pgood_reset_active
% Start timing for reset
pgood_reset_active = true;
pgood_reset_timer = int32(0);
else
% Increment reset timer
pgood_reset_timer = pgood_reset_timer + int32(1);
% Check if reset delay time has elapsed
if pgood_reset_timer >= PGOOD_TIME_DELAY
IsPGood_state = false;
IsPGood = false;
pgood_reset_active = false;
pgood_reset_timer = int32(0);
end
end
end
end
%-------------------------------------------------------------
% IsWrongDirection - Check if power flows in wrong direction
% (battery discharging while external power > 27V for 2 seconds)
%-------------------------------------------------------------
persistent IsWrongDirection_state
if isempty(IsWrongDirection_state)
IsWrongDirection_state = false;
end
IsWrongDirection = IsWrongDirection_state;
% Check if external power voltage > 27V and discharge current > 0
if (single(CHRG_IN.system_voltage) > WRONG_DIR_VOLTAGE_THRESHOLD) && ...
(single(CHRG_IN.discharge_current) > single(0))
if ~wrong_dir_active
% Start timing when conditions are first met
wrong_dir_active = true;
wrong_dir_timer = int32(0);
else
% Increment timer (count 10ms ticks)
wrong_dir_timer = wrong_dir_timer + int32(1);
% Check if delay time has elapsed (2 seconds)
if wrong_dir_timer >= WRONG_DIR_TIME_DELAY
IsWrongDirection_state = true;
IsWrongDirection = true;
end
end
else
% Conditions not met - reset immediately if discharge current is zero
wrong_dir_active = false;
wrong_dir_timer = int32(0);
% Reset state immediately when discharge current becomes zero
if single(CHRG_IN.discharge_current) <= single(0)
IsWrongDirection_state = false;
IsWrongDirection = false;
end
end
end
И тут сразу станет ясно, что на диаграмме изображена только вершина айсберга. А на Муре пришлось бы весь айсберг рисовать. Т.е. заниматься сизифовым трудом. Диаграмма Мура которую я дал, конечно не является таковой. В реале она должна стать монструозной и совершенно нечитаемой чтобы отразить в точности диаграмму StateFlow.
А почему бы у Claude не спросить как делать загрузчики?
Агенты такие вещи сейчас мгновенно делают
Вот, например, мне за день с учетом отладки Claude вот такой загрузчик по CAN сделал https://github.com/Indemsys/Landing_controller_LNDC_bootloader/blob/main/src/CAN_Bootloader/can_bootloader.c
Причем с глубокой трассировкой и исчерпывающими коментариями.
И еще полную спецификацию написал -
https://github.com/Indemsys/Landing_controller_LNDC_bootloader/blob/main/src/CAN_Bootloader/README.md
По этой спецификации он написал потом менеджер загрузки для центрального контроллера.
Там же моментом и скрипты для загрузки с ПК написал.
Шифрация , сжатие, и подпись по ECDSA (Elliptic Curve Digital Signature Algorithm) тоже были, но убраны.
В этом смысле мне очень нравится цитата из книги
Ha-Joon Chang "Economics:The User's Guide"
Так есть ли смысл умничать про деньги?
Тут вы просто противоречите повсеместному эмпирическому опыту.
Свой код от Claude я тоже могу объявить библиотекой и сказать какие у него незаменимые фичи типа: "поля можно объявить optional с дефолтами". Он ракетой такие либы умеет делать. Хуже. Что ни попроси, он всегда накидывает лишнего API, чтобы сразу полная либа получилась.
Вообще, где доказательства, что ваша либа не от Claude или чего-то подобного?
Бросайте это. Либы на коленке в ближайшие тысячу лет никому не будут нужны.
Лучше опубликуйте полезное приложение с применением JSON. Вот тогда будет понятно, что имеем дело с человеческим трудом.
Извините, не знал что вы разработчик всех "индустриальных MCU/RTOS-проектов".
Шучу.
В реальности есть постоянная проблема когда новая версия JSON не повторяет старую. У меня, скажем, в индустриальной системе JSON меняется каждую неделю! Почему я должен держаться за формат который устарел?
Так вот jansson избавляет от многих хлопот.
Я пишу исключительно на голом С и вот десериализатор сгенеренный целиком Claude на основе API jansson - https://github.com/Indemsys/MC80_4DC/blob/main/src/Parameters/Parameters_deserializer.c
А еще есть сериализатор, и еще есть куча мест где идет парсинг JSON.
А у тому клоню, что нет нынче никакой необходимости создавать обертки над такими эффективными и прозрачными либами как jansson.
Claude создаст весь прикладной код на лету на нативном API и под любой вкус. Была бы ему либа эта вся задокументрирована.
А вот когда одна либа поверх другой, а та поверх третьей, вот тут вы реально стреляете себе в ногу. Раздуваете контекст, усложняете работу агентам и запутываете их. Потом остается только пенять на заточенность под "STL, шаблоны и типичные C++-механизмы"
Автоматический папинг делает кодирующий агент, я же написал.
Агенты это делают превосходно.
А у вас псевдоавтоматизм. Поскольку структуру JSON надо знать заранее.
Код Jansson: ~5,3 КБ.
Глобальные данные / константы: ≈0 Б.
Куча: все JSON-объекты (json_object, json_array, строки и т.п.) аллоцируются через malloc. malloc надо портировать через свое API, поэтому тут свобода реализации. В ThreadX, например malloc умеет делать статистику и ожидать освобождения памяти заданное время.
Пример: пустой json_object ≈ 32–64 байта + хэш-таблица.
Каждая строка хранится отдельно (длина + копия текста). Сколько сырой JSON без пробелов занимает, столько памяти приблизительно и нужно будет
По стеку. Там рекурсивный парсинг. Одна функция разбора (parse_value/parse_object/parse_array) тянет локальные переменные порядка 16–32 байт. Глубина рекурсии = глубине вложенности JSON. Но это контролируется, потому что глубину разбора задает макрос.
За скорость не скажу, там главный тормоз - медианоситель.
Непонятно что тут означает "контролируемая работа с памятью".
Если есть неизвестный JSON в котором надо что-то выловить, то парсить дерево нужно. И без динамической памяти никак. И откуда там утечки если библиотека протестирована.
Динамическая память - это всегда фрагментация, и риск потери чистой памяти.
Но проблема решается элементарно просто наложением мьютека на выделение памяти другими задачами на время парсинга JSON.
Я бы конечно рекомендовал https://github.com/akheron/jansson
В современной реальности самые лучшие библиотеке - это те что понятны и доступны для кодирующих агентов.
Так вот с jansson агент Claude работает безукоризненно. Может построить парсигн и генерацию любого дерева. Делает практически безошибочно. Это то, что агенты с самого начала научились хорошо делать.
Чел забыл упомянуть, что свой SLIP он прогоняет через RP2040, а потом через PC чтобы достичь интернета.
Обкурился?
Это вот эта что-ли:
Это ни о чем.
Где сравнение с реальными GPS модулями. Где расходы трасивера на связь с облаком? Где расходы на работу процессора, шифрацию и прочие? А на джаминг?
Зыбко все это.
Там вся статья про это. Но где цифры? Где статистика?
Я только не понял где то самое потребление ради которого вся эта заваруха?
Есть тут лукавства.
Claude Sonnet в качестве агента стал нормально кодить всего несколько месяцев назад.
Функция делегирования агенту в облака на сам GitHub скажем в GitHub Copilot появилось вообще пару дней назад.
А главное - агенты еще очень медленно работают. Ожидание в пару минут на простые запросы просто тормозит работу. Никогда не угадаеш когда он тормознет.
Да и сборщики еще очень медленные.
Ну и наконец, промптинг не имеет никакого значения.
В скорости разработки имеет значение подстройка агентских инструментов, инструкций и MCP серверов под свой рабочий процесс. Именно от этого зависит сколько бесплодных попыток что-то сделать будут тратить агенты и в какой бюджет это выльется.
Я считаю что ускорение с агентами реально достигает 5-10 раз. Но при условии отлаженного рабочего процесса и дорогого плана.
Тут надо бы еще телеметрию контактов реле делать. Т.е. диагностику залипаний.
Про котлы не знаю, но тоже как-то странно брать от них только температуру и больше ничего.
Но самая песня тут будет с беспроводной связью.
Говорят телеграмам на ладан дышит и во многих странах его собираются банить, сам телеграм может банить подозрительный нецелевой тафик. Как банят теперь емайлы.
Но это не самое больное. Самое больное - это зависания точек доступа.
Этому дивайсику следовало бы еще научится сбрасывать помимо котла еще и свою точку доступа. А еще научится как-то менять каналы W-Fi в поисках свободных. А лучше иметь резервные AP на объекте. Антенка тоже так себе, лучше бы внешнюю.
Самое то смешное что дивайс должен стабильно работать при сбоях в электросети, но эти сбои даже миллисекундные и никем не замеченные первыми убивают роутеры.
Ардуина просто избыточна и переусложнена.
У ардуин цель - образование. Поэтому там много лишнего в виде голых пинов, отдельных не адаптированых и не оптимальных плат и специфичных перенасыщенных абстрактных API библиотек.
Открываешь страницу проекта Arduino и тебя сразу встречает море разных платок и модулей.
С другой стороны экосистема ардуино скатывается в область индустриальных систем и там оказывается не имеет никаких преимуществ. Схема закрыта, микроконтроллер STM32H747XIH6 - сверхнавороченный, никакой ардуинщик не возьмется его изучать (а если возьмется, то перестанет быть ардуинщиком ).
Проще напрямик взять референс дизайны у ST и делать на них.
Я как понял, ничего там не обрабатывается.
AI еще не прекрутили и идей нет как прикрутить.
И не будет в ближайшем будущем, поскольку AI до сих пор хорошо работает только в дискретном пространстве слов, а в физическом аналоговом мире он полный дуб.
Да и отсчет в 10 мс - это ни о чем.
Поэтому просто строят графики и выводят таблицы. Как и наши деды.
Не...
Маркс утверждал, что норма прибыли у капиталистов со временем упадет и капитализм рухнет неизбежно.
А Пикетти говорит, что норма прибыли и не думает падать и это фундаментальная константа, как скорость света в вакууме. А потому капитализм вечен.
Пикетти - апологет капитализма, а Маркс - оппонент.
За плавное замедление отвечает частотный преобразователь. Контроллер лифта к нему отношения не имеет.
В этом сила гибридных схем. Да, они кажутся простыми и сразу понятными. Сразу ясно что там надо 100 строчек.
А к Муру у вас сразу притензии. Не там поставил видиш ли надписи. Надо их куда убирать. А это рассеивает внимание и т.д.
Но вот вам на самом деле скрипт кторый скрывается за простенькими условиями типа Wrong Direction на диаграмме StateFlow (там уже 253 строки)
Скрипт MATLAB
И тут сразу станет ясно, что на диаграмме изображена только вершина айсберга.
А на Муре пришлось бы весь айсберг рисовать. Т.е. заниматься сизифовым трудом.
Диаграмма Мура которую я дал, конечно не является таковой. В реале она должна стать монструозной и совершенно нечитаемой чтобы отразить в точности диаграмму StateFlow.
А вот управление лифта на контроллере проще чем Arduino
Сложность лифтовых контроллеров обусловлена не алгоритмом работы лифта, а сервисами диагностики, инсталляции, обслуживания и производства.
Ну сравните нотацию в стиле автомата Мура
И гибридную нотацию StateFlow того же алгоритма
Кто понятней?