$ sudo apt update
$ sudo apt install ros-jazzy-smach ros-jazzy-smach-ros![]() | ![]() |
Счетчиков Юрий Андреевич
Что такое машина состояний
Установка и окружение
Состояния, переходы, outcome
Простой пример
Машина состояний (Finite State Machine, FSM) — это модель поведения системы, в которой в каждый момент времени система находится в одном состоянии или в конкуренции, и может переходить в другое состояние, когда происходят определённые события.

Для установки SMACH на ROS2 Jazzy необходимо скачать два пакета:
$ sudo apt update
$ sudo apt install ros-jazzy-smach ros-jazzy-smach-rosПроверка, что всё подтянулось:
$ ros2 pkg list | grep smachСостояние описывает, чем сейчас занята система: какое действие она выполняет или в каком режиме находится. Примеры состояний в роботе:
"Инициализируем датчики"
"Ждём команду"
"Едем к точке"
"Ищем объект(ы)"
"Возвращаемся"

Каждое состояние — отдельный класс, у которого есть метод:
execute(self, userdata)Он вызывает полезные действия и в конце возвращает outcome
Состояние — это статус системы в данный момент.
Переход определяет, в какое состояние мы движемся дальше после завершения текущего.

Переходы задаются при добавлении состояния в машину:
# Добавляем новое состояние
smach.StateMachine.add('INIT',InitState(node),
# Статусы переходов на следующее состояние
transitions={'ok': 'SEARCH','fail': 'SM_ABORTED'})То есть:
если INIT вернул 'ok' → переходим в SEARCH
если 'fail' → переходим в SM_ABORTED
Переходы всегда явно указаны словарём.
Outcome — это строка, которую возвращает метод execute().
Например:
return 'ok'
Именно эта строка используется как ключ выбора следующего состояния.
Если состояние объявлено с такими outcomes:
class Init(smach.State):
def __init__(self):
super().__init__(outcomes=['ok', 'fail'])то в переходах обязаны быть такие же значения:
transitions={'ok': 'SEARCH','fail': 'SM_ABORTED'}Если вернуть то, чего нет в списке outcomes — будет ошибка.
Давайте для наглядности разберем полный пример состояния smach:
class InitState(smach.State):
def __init__(self, node: Node) -> None:
super().__init__(outcomes=['ok', 'fail'])
self.node = node
# Точка входа состояния, которая выполняет основную логику и возвращает outcome.
def execute(self, userdata: Any) -> str:
self.node.get_logger().info('INIT: проверяем системы...')
# тут могла быть реальная проверка: датчики, связь и т.п.
time.sleep(10.0)
systems_ok = True # заглушка
if systems_ok:
self.node.get_logger().info('INIT: всё ок, переходим к следующему состоянию.')
return 'ok'
else:
self.node.get_logger().error('INIT: ошибка, остаёмся в fail.')
return 'fail'Далее добавление состояния smach:
with sm:
# Добавляем новое состояние
smach.StateMachine.add('INIT',InitState(node),
# Статусы переходов на следующее состояние
transitions={'ok': 'SEARCH','fail': 'SM_ABORTED'})
# Добавляем новое состояние
smach.StateMachine.add('SEARCH', SearchState(node),
# Статусы переходов на следующее состояние
transitions={'found': 'DONE', 'timeout': 'SM_ABORTED'})
# Добавляем новое состояние
smach.StateMachine.add( 'DONE', DoneState(node),
# Статус перехода на следующее состояние
transitions={'finished': 'SM_FINISHED'})
# запускаем машину состояний
outcome = sm.execute()Для более удобного взаимодействия с smach существует утилита для визуализации smach-viewer.
Она позволяет отслеживать статус и строит дерево состояний

Данное приложение плохо портировали на второй ROS, поэтому время от времени оно может работать с багами: не отображает текущего состояния, не показывает визуализацию. Данную утилиту следует использовать для приблизительной оценки перехода состояний._
Узнал, что такое машина состояний
Установил smach и настроил окружение
Состояния, переходы, outcome
Разобрал простой пример машины состояний

Установка ROS2 https://docs.ros.org/en/jazzy/Installation/Ubuntu-Install-Debs.html | https://docs.ros.org/en/jazzy/Installation/Ubuntu-Install-Debs.html |
Официальная справка https://docs.ros.org/en/jazzy/Tutorials/Beginner-CLI-Tools.html | https://docs.ros.org/en/jazzy/Tutorials/Beginner-CLI-Tools.html |
smach-viewer https://sdb.smtu.ru/gitlab/course2025/smach-viewer | https://sdb.smtu.ru/gitlab/course2025/smach-viewer |
Нужно реализовать FSM smach для катамарана в симуляторе с текущими состояниями:
пройти по таймеру вперед 5 секунд
при помощи нижней камеры определить фигуру на дне бассейна
в зависимости от распознанной фигуры катамаран должен:
круг - начать крутиться по часовой стрелке
квадрат - начать крутиться против часовой стрелки
треугольник - катамаран продолжает движение вперед 10 секунд
Катамаран должен постоянно отслылать логи. Отображение данных логов вы должны прикрепить в виде скриншота или текстового формата.
Визуализировать полученную машину состояний через smach_viewer