Основы программировния морских роботов

Машина состояний SMACH

logo
smtu logo

План занятия

  • Что такое машина состояний

  • Установка и окружение

  • Состояния, переходы, outcome

  • Простой пример

Что такое машина состояний

Машина состояний (Finite State Machine, FSM) — это модель поведения системы, в которой в каждый момент времени система находится в одном состоянии или в конкуренции, и может переходить в другое состояние, когда происходят определённые события.

SMACH state machine

Установка и окружение

Для установки SMACH на ROS2 Jazzy необходимо скачать два пакета:

$ sudo apt update
$ sudo apt install ros-jazzy-smach ros-jazzy-smach-ros

Проверка, что всё подтянулось:

$ ros2 pkg list | grep smach

Основные элементы: Состояния (State)

Состояние описывает, чем сейчас занята система: какое действие она выполняет или в каком режиме находится. Примеры состояний в роботе:

  • "Инициализируем датчики"

  • "Ждём команду"

  • "Едем к точке"

  • "Ищем объект(ы)"

  • "Возвращаемся"

state

Основные элементы: Состояния (State)

Каждое состояние — отдельный класс, у которого есть метод:

execute(self, userdata)

Он вызывает полезные действия и в конце возвращает outcome

Состояние — это статус системы в данный момент.

Основные элементы: Переходы (Transition)

Переход определяет, в какое состояние мы движемся дальше после завершения текущего.

transitions

Переходы задаются при добавлении состояния в машину:

# Добавляем новое состояние
smach.StateMachine.add('INIT',InitState(node),
    # Статусы переходов на следующее состояние
    transitions={'ok': 'SEARCH','fail': 'SM_ABORTED'})

То есть:

если INIT вернул 'ok' → переходим в SEARCH

если 'fail' → переходим в SM_ABORTED

Переходы всегда явно указаны словарём.

Основные элементы: Outcome (результат выполнения состояния)

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 Viewer

Для более удобного взаимодействия с smach существует утилита для визуализации smach-viewer.

Она позволяет отслеживать статус и строит дерево состояний

smach

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

Сегодня я многое понял

  • Узнал, что такое машина состояний

  • Установил smach и настроил окружение

  • Состояния, переходы, outcome

  • Разобрал простой пример машины состояний

KyleBroflovski

Дополнительные материалы

Установка 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