Конечный автомат (Finite State Machine) — Формальные модели поведения автономных систем
Конечный автомат — это не просто паттерн программирования, а фундаментальный математический формализм для описания дискретных динамических систем. В 2026 году FSM эволюционировали от простых переключателей состояний к сложным иерархическим вероятностным моделям, способным формально гарантировать корректность поведения автономных систем в условиях неопределённости.
Математические основы: От теории автоматов к формальной верификации
Формальное определение детерминированного конечного автомата (DFA)
Кортеж из пяти элементов: \( M = (Q, \Sigma, \delta, q_0, F) \)
- \( Q \) — конечное множество состояний
- \( \Sigma \) — конечный входной алфавит
- \( \delta: Q \times \Sigma \to Q \) — функция переходов
- \( q_0 \in Q \) — начальное состояние
- \( F \subseteq Q \) — множество принимающих (финальных) состояний
Для робототехники: \( F \) — часто состояния завершения задачи или ошибки.
Недетерминированный конечный автомат (NFA)
Более выразительная модель: \( \delta: Q \times \Sigma \to \mathcal{P}(Q) \)
Пример для робота: В состоянии MOVING при событии obstacle_detected автомат может перейти в AVOIDING или STOPPED в зависимости от дополнительных условий.
Теорема Рабина-Скотта (1959):
Иерархия конечных автоматов в робототехнике 2026
Уровень 1: Базовые DFA — рефлексивное поведение
Пример — контроллер безопасности:
// Формальное определение на языке Rust с проверкой типов
enum SafetyState {
Normal,
Warning { distance: f32 },
EmergencyStop,
Fault { code: u32 },
}
enum SafetyEvent {
ObstacleDetected(f32),
ButtonPressed,
SystemCheckPassed,
ErrorDetected(u32),
}
impl SafetyFSM {
fn transition(state: SafetyState, event: SafetyEvent) -> SafetyState {
match (state, event) {
(SafetyState::Normal, SafetyEvent::ObstacleDetected(d)) if d < 0.1 =>
SafetyState::EmergencyStop,
(SafetyState::Normal, SafetyEvent::ObstacleDetected(d)) if d < 0.5 =>
SafetyState::Warning { distance: d },
(SafetyState::Warning { .. }, SafetyEvent::ObstacleDetected(d)) if d >= 0.5 =>
SafetyState::Normal,
// ... другие переходы
_ => state, // Защита от неопределённых переходов
}
}
}
Матрица переходов (для верификации):
| Состояние \ Событие | Obstacle < 0.1m | Obstacle 0.1-0.5m | ButtonPressed | Error |
|---|---|---|---|---|
| Normal | EmergencyStop | Warning | - | Fault |
| Warning | EmergencyStop | Warning | Normal | Fault |
| EmergencyStop | - | - | Normal | Fault |
| Fault | - | - | - | Fault |
Уровень 2: Иерархические конечные автоматы (HFSM) — модульное поведение
где:
- \( M = \{M_1, M_2, ..., M_n\} \) — множество автоматов
- \( \prec \) — отношение вложенности
- \( \tau \) — функции передачи управления между уровнями
Реализация с поддержкой истории:
class HierarchicalFSM {
struct State {
string name;
function<void()> entry_action;
function<void()> exit_action;
function<void()> do_action;
map<Event, pair<State*, Condition>> transitions;
// Иерархия
State* parent = nullptr;
vector<State*> children;
State* initial_child = nullptr;
// История для возврата
State* history_state = nullptr;
};
State* current_state;
stack<State*> state_stack;
void process_event(Event event) {
// Поиск обработчика в иерархии снизу вверх
State* handler = find_handler(current_state, event);
if (handler) {
execute_transition(handler, event);
}
}
State* find_handler(State* state, Event event) {
while (state) {
if (state->transitions.contains(event)) {
auto& [next_state, condition] = state->transitions[event];
if (condition()) return state;
}
state = state->parent; // Поднимаемся вверх по иерархии
}
return nullptr;
}
};
Уровень 3: Конечные автоматы с таймерами (Timed Automata)
Формализм Альфа-Ули (Alur-Dill): Автомат расширен часами (clocks) \( C \) и ограничениями на них.
Пример — робот с таймаутами:
class TimedAutomaton:
def __init__(self):
self.clocks = {'t_action': 0, 't_safety': 0}
self.invariants = {
'EXECUTING': 't_action <= 5.0', # Максимум 5 секунд на действие
'WAITING': 't_safety <= 2.0', # Ожидание подтверждения 2 секунды
}
self.guards = {
('EXECUTING', 'TIMEOUT'): 't_action >= 5.0',
('WAITING', 'RESPONSE_MISSING'): 't_safety >= 2.0',
}
def transition(self, from_state, event):
guard = self.guards.get((from_state, event))
if guard and self.evaluate_guard(guard):
# Сброс часов при переходе
if event == 'ACTION_COMPLETE':
self.clocks['t_action'] = 0
return self.get_target_state(from_state, event)
return from_state
Уровень 4: Вероятностные конечные автоматы (PFA) — поведение в неопределённости
где \( \delta: Q \times \Sigma \times Q \to [0, 1] \) — вероятности переходов.
Пример для адаптивного поведения:
class ProbabilisticFSM:
def __init__(self):
self.transition_matrix = {
'EXPLORING': {
'object_detected': [
('INSPECTING', 0.7), # С вероятностью 70% исследовать
('IGNORING', 0.2), # С вероятностью 20% проигнорировать
('AVOIDING', 0.1), # С вероятностью 10% избегать
]
}
}
def transition(self, state, event):
if state in self.transition_matrix and event in self.transition_matrix[state]:
transitions = self.transition_matrix[state][event]
# Выбор на основе вероятностей
choices, probabilities = zip(*transitions)
next_state = np.random.choice(choices, p=probabilities)
return next_state
return state
Продвинутые архитектурные паттерны на основе FSM
Паттерн “Состояние-Действие-Модель” (State-Action-Model)
template<typename State, typename Action, typename Model>
class StateActionFSM {
struct Transition {
State from;
Action trigger;
function<bool(const Model&)> guard;
function<void(Model&)> action;
State to;
};
State current_state;
Model world_model;
vector<Transition> transitions;
void process_action(Action action) {
// Поиск подходящего перехода
for (const auto& trans : transitions) {
if (trans.from == current_state &&
trans.trigger == action &&
trans.guard(world_model)) {
// Выполнение перехода
trans.action(world_model);
current_state = trans.to;
log_transition(trans);
return;
}
}
// Обработка неопределённого перехода
handle_undefined_transition(current_state, action);
}
};
Паттерн “Ортогональные регионы” для параллельного поведения
Пример — робот с независимыми подсистемами:
Основной FSM: Навигационный FSM: Манипулятор FSM:
[IDLE] [PLANNING] [STOWED]
| | |
v v v
[NAVIGATING] <------> [EXECUTING] [GRASPING]
| | |
v v v
[WORKING] [REPLANNING] [PLACING]
Реализация:
class OrthogonalRegionsFSM:
def __init__(self):
self.regions = {
'mission': MissionFSM(),
'navigation': NavigationFSM(),
'manipulation': ManipulationFSM(),
}
self.coordination_rules = [
# Правила координации между регионами
lambda: (self.regions['navigation'].state == 'BLOCKED' and
self.regions['mission'].state == 'EXECUTING') ->
self.regions['mission'].trigger('NAVIGATION_FAILED')
]
def process_event(self, event):
# Распространение события во все регионы
for region_name, fsm in self.regions.items():
fsm.process_event(event)
# Применение правил координации
for rule in self.coordination_rules:
rule.apply_if_condition_met()
FSM с поддержкой обучения (Learning FSM)
Автомат, который адаптирует свои переходы:
class LearningFSM:
def __init__(self):
self.transitions = {} # Q × A → Q
self.q_values = defaultdict(lambda: defaultdict(float)) # Q × A → R
self.learning_rate = 0.1
self.discount_factor = 0.9
def choose_action(self, state, epsilon=0.1):
# ε-жадная стратегия
if random.random() < epsilon:
return random.choice(self.available_actions(state))
else:
actions = self.available_actions(state)
return max(actions, key=lambda a: self.q_values[state][a])
def learn(self, state, action, reward, next_state):
# Обновление Q-значений (упрощённый Q-learning)
best_next_action = max(self.available_actions(next_state),
key=lambda a: self.q_values[next_state][a])
td_target = reward + self.discount_factor * self.q_values[next_state][best_next_action]
td_error = td_target - self.q_values[state][action]
self.q_values[state][action] += self.learning_rate * td_error
# Адаптация переходов при достижении порога уверенности
if self.confidence(state, action) > 0.95:
self.transitions[(state, action)] = next_state
Формальная верификация и анализ FSM
Модельная проверка (Model Checking) с помощью темпоральной логики
Спецификации на LTL (Linear Temporal Logic):
// Формулы для проверки свойств безопасности робота
vector<LTLFormula> safety_properties = {
// Всегда: если EmergencyStop, то не двигаться
LTL::Always(LTL::Implies(
state == "EMERGENCY_STOP",
motor_speed == 0
)),
// В конце концов всегда можно вернуться в Normal
LTL::Eventually(LTL::Always(
LTL::Possible(state == "NORMAL")
)),
// Никогда не находиться одновременно в двух конфликтующих состояниях
LTL::Always(LTL::Not(
state == "MOVING" && state == "CHARGING"
))
};
// Проверка с помощью model checker'а
ModelChecker checker;
for (const auto& property : safety_properties) {
bool holds = checker.verify(robot_fsm, property);
if (!holds) {
cout << "Нарушено свойство: " << property << endl;
cout << "Контрпример: " << checker.get_counterexample() << endl;
}
}
Анализ достижимости (Reachability Analysis)
Алгоритм обхода состояний:
def analyze_reachability(fsm):
visited = set()
queue = [fsm.initial_state]
deadlock_states = []
while queue:
state = queue.pop(0)
if state in visited:
continue
visited.add(state)
# Проверка на тупик
if not fsm.get_enabled_events(state):
deadlock_states.append(state)
# Добавление достижимых состояний
for event in fsm.get_possible_events(state):
next_state = fsm.get_transition(state, event)
if next_state not in visited:
queue.append(next_state)
return {
'reachable_states': visited,
'deadlock_states': deadlock_states,
'coverage': len(visited) / len(fsm.all_states)
}
Генерация тестов из FSM
Метод китайских почтальонов (Chinese Postman) для покрытия переходов:
def generate_test_paths(fsm):
# Построение графа автомата
graph = nx.DiGraph()
for from_state, transitions in fsm.transitions.items():
for event, to_state in transitions.items():
graph.add_edge(from_state, to_state, event=event)
# Нахождение эйлерова пути или цикла
if nx.is_eulerian(graph):
path = list(nx.eulerian_circuit(graph))
else:
# Добавление минимального числа рёбер для эйлерова графа
graph = nx.eulerize(graph)
path = list(nx.eulerian_circuit(graph))
# Преобразование в последовательность тестов
test_cases = []
for (from_state, to_state, data) in path:
test_cases.append({
'initial_state': from_state,
'event': data['event'],
'expected_state': to_state
})
return test_cases
Практикум: “Проектирование и верификация FSM для робота-курьера”
Задача: Разработать FSM для автономного робота-курьера, выполняющего заказы в офисе.
Шаг 1: Определение требований (формальная спецификация)
Требования безопасности (LTL):
1. □(charging → ¬moving) // Во время зарядки не двигаться
2. □(emergency → ○(stopped)) // При аварии немедленно остановиться
3. ◇□(battery_low → charging) // При низком заряде в конце концов зарядиться
Требования живости (Liveness):
1. ◇(order_received → ◇delivered) // Заказ в конце концов будет доставлен
2. ◇(obstacle → ◇¬obstacle) // Препятствие в конце концов будет преодолено
Шаг 2: Проектирование иерархического FSM
class DeliveryRobotFSM:
def __init__(self):
# Верхний уровень: миссия
self.mission = HierarchicalFSM(
initial_state='WAITING_FOR_ORDER',
states={
'WAITING_FOR_ORDER': {
'order_received': ('PROCESSING_ORDER', self.validate_order),
},
'PROCESSING_ORDER': {
'order_valid': ('EXECUTING_DELIVERY', self.plan_route),
'order_invalid': ('WAITING_FOR_ORDER', self.notify_error),
},
'EXECUTING_DELIVERY': {
'at_destination': ('COMPLETING_DELIVERY', self.prepare_delivery),
'delivery_failed': ('HANDLING_FAILURE', self.analyze_failure),
},
'COMPLETING_DELIVERY': {
'delivery_complete': ('WAITING_FOR_ORDER', self.confirm_delivery),
},
'HANDLING_FAILURE': {
'failure_resolved': ('EXECUTING_DELIVERY', self.replan),
'failure_permanent': ('WAITING_FOR_ORDER', self.abort_delivery),
},
}
)
# Средний уровень: навигация
self.navigation = ParallelFSM([
LocalNavigationFSM(), # Избегание препятствий
GlobalNavigationFSM(), # Следование маршруту
LocalizationFSM(), # Определение позиции
])
# Нижний уровень: безопасность
self.safety = SafetyFSM(
sensors=['lidar', 'bumper', 'current_sensor'],
emergency_actions=['cut_power', 'activate_brakes']
)
Шаг 3: Формальная верификация с помощью NuSMV
MODULE main
VAR
state: {WAITING, EXECUTING, CHARGING, EMERGENCY};
battery: 0..100;
obstacle: boolean;
ASSIGN
init(state) := WAITING;
next(state) := case
state = WAITING & battery > 20 & !obstacle: EXECUTING;
state = EXECUTING & battery < 15: CHARGING;
state = EXECUTING & obstacle: EMERGENCY;
state = CHARGING & battery > 90: WAITING;
state = EMERGENCY & !obstacle: WAITING;
1: state; -- по умолчанию остаёмся в текущем состоянии
esac;
-- Проверка свойств безопасности
SPEC AG (state = EMERGENCY -> AX state != EXECUTING) -- После аварии не двигаться
SPEC AG (battery < 5 -> AF state = CHARGING) -- Низкий заряд ведёт к зарядке
SPEC !EF (state = EXECUTING & state = CHARGING) -- Невозможно одновременно выполнять и заряжаться
Шаг 4: Генерация кода и тестов
# Автоматическая генерация кода из спецификации
code_generator = FSMCodeGenerator(
target_language='cpp',
template='embedded_rtos',
optimizations=['minimize_states', 'optimize_transitions']
)
generated_code = code_generator.generate(self.delivery_robot_fsm)
# Генерация тестов с покрытием всех переходов
test_generator = TestGenerator(coverage_criteria='transition_coverage')
test_suite = test_generator.generate(self.delivery_robot_fsm)
# Статическая проверка свойств
verification_result = model_checker.verify(
model=self.delivery_robot_fsm,
properties=safety_properties + liveness_properties
)
Метрики качества FSM:
Размерность:
- Число состояний: \( |Q| \)
- Число переходов: \( |\delta| \)
- Цикломатическая сложность: \( |\delta| - |Q| + 2 \)
Качество проектирования:
- Коэффициент связности: \( \frac{|\delta|}{|Q|^2} \)
- Глубина иерархии
- Число ортогональных регионов
Верифицируемость:
- Процент формально проверенных свойств
- Время model checking’а
- Размер контрпримеров (если есть)
Интеграция с современными технологиями 2026
FSM в ROS 2 (Lifecycle Nodes)
class LifecycleFSMNode : public rclcpp_lifecycle::LifecycleNode {
enum State {UNCONFIGURED, INACTIVE, ACTIVE, FINALIZED};
CallbackReturn on_configure(const State &) override {
// Переход в INACTIVE
return CallbackReturn::SUCCESS;
}
CallbackReturn on_activate(const State &) override {
// Переход в ACTIVE
publisher_->on_activate();
return CallbackReturn::SUCCESS;
}
CallbackReturn on_deactivate(const State &) override {
// Возврат в INACTIVE
publisher_->on_deactivate();
return CallbackReturn::SUCCESS;
}
};
FSM для машинного обучения (FSM-RL гибриды)
class HybridFSMRL:
def __init__(self):
self.fsm = DeterministicFSM() # Для гарантированной безопасности
self.rl_agent = PPOAgent() # Для адаптивного поведения
def decide_action(self, state):
# FSM определяет допустимые действия
allowed_actions = self.fsm.get_allowed_actions(state)
# RL агент выбирает оптимальное действие среди допустимых
if allowed_actions:
q_values = self.rl_agent.predict(state)
# Фильтрация по допустимым действиям
allowed_q_values = {a: q for a, q in q_values.items()
if a in allowed_actions}
if allowed_q_values:
return max(allowed_q_values, key=allowed_q_values.get)
# Резервное действие от FSM
return self.fsm.get_default_action(state)
Распределённые FSM для роев роботов
class DistributedFSM:
def __init__(self, robot_id, neighbors):
self.local_fsm = LocalFSM()
self.neighbors = neighbors
self.consensus_algorithm = PaxosFSM()
def global_transition(self, global_event):
# Достижение консенсуса о глобальном переходе
proposal = (self.robot_id, global_event, time.time())
agreed_event = self.consensus_algorithm.propose(proposal)
if agreed_event:
# Все роботы выполняют синхронизированный переход
self.local_fsm.process_event(agreed_event)
self.broadcast_transition(agreed_event)
Бустое FSM (2026+)
1. Нейросимволические FSM
Гибридные модели, где:
- Символическая часть: FSM для гарантий безопасности
- Нейросетевая часть: Глубокое обучение для распознавания состояний
2. Квантовые FSM
3. Спайковые FSM
FSM, работающие на спайковых нейронных сетях для энергоэффективности.
4. Самоверифицирующиеся FSM
Автоматы, которые доказывают свои свойства во время выполнения.
5. Биомиметические FSM
Модели, вдохновлённые нейронными сетями животных для робастного поведения.
Инструменты и библиотеки 2026
- SCCharts: Синхронные диаграммы состояний с формальной семантикой
- YAKINDU Statechart Tools: Моделирование, генерация кода, симуляция
- FSM4Rust: Типобезопасные FSM на языке Rust
- Boost.MSM (Meta State Machine): Шаблонная библиотека для C++
- Python-StateMachine: Декоратор-based FSM для Python
- NuSMV, UPPAAL: Инструменты формальной верификации
Что дальше?
- Паттерны проектирования — другие архитектурные паттерны
- Формальные методы — математическая верификация систем
- Машинное обучение — гибридные подходы FSM+RL
- Распределённые системы — координация множества FSM
Философский итог: Конечные автоматы в 2026 году — это не просто способ организации кода, а фундаментальный язык для описания дискретного поведения. Они представляют собой мост между интуитивным проектированием поведения и формальной математикой, между гибкостью эвристик и надёжностью детерминизма. В эпоху нейросетей и вероятностного программирования FSM остаются островком предсказуемости в океане неопределённости — формальной гарантией того, что автономная система, каким бы сложным ни был её «разум», будет вести себя корректно в критических ситуациях. Это договор между творцом и творением: свобода в рамках правил, адаптивность в границах безопасности, интеллект с фундаментом из формальной логики.
