Действия (actions): длительные задачи

Для долгих задач, за которыми хочется следить и которые можно отменить, в ROS есть действия.

Действие (action) — механизм для длительных задач: клиент посылает цель (goal), сервер выполняет её, периодически шлёт обратную связь (feedback) и в конце возвращает результат (result); цель можно отменить.

Почему не сервис

Команда «доедь до точки (5, 3)» выполняется секунды или минуты. Если оформить это сервисом, клиент молча зависнет до конца поездки: ни прогресса, ни возможности передумать. Действие решает обе проблемы. Пока робот едет, сервер шлёт feedback («проехал 60% пути»), а клиент в любой момент может отменить цель («стой, поехали в другое место»). В конце приходит result («доехал» или «застрял»).

Три части действия

Файл .action состоит из трёх секций, разделённых ---: цель, результат, обратная связь.

# MoveTo.action
# Goal — что сделать
float64 x
float64 y
---
# Result — итог
bool reached
float64 final_distance
---
# Feedback — промежуточный прогресс
float64 distance_remaining

Жизненный цикл цели

  клиент --(goal: ехать в 5,3)--> сервер
  сервер --(accepted)--> клиент
  сервер --(feedback: осталось 4.0 м)--> клиент
  сервер --(feedback: осталось 1.2 м)--> клиент
  сервер --(result: reached=true)--> клиент
          (в любой момент: клиент --(cancel)--> сервер)

Команды интроспекции

ros2 action list
ros2 action info /move_to
ros2 action send_goal /move_to my_robot/action/MoveTo "{x: 5.0, y: 3.0}" --feedback

Вывод (с --feedback):

Goal accepted with ID: a1b2c3
Feedback: distance_remaining=4.0
Feedback: distance_remaining=1.2
Result: reached=True final_distance=0.05

Действия = топики + сервис

Под капотом действие — не отдельный примитив, а композиция уже знакомых: два сервиса (отправка цели и отмена) плюс топики для обратной связи и статуса. ROS прячет эту кухню за удобным интерфейсом ActionClient/ActionServer, но полезно понимать, что внутри всё те же топики и сервисы. Поэтому действие наследует их свойства: обратная связь идёт потоком (как топик), а приём цели и отмена — это запрос/ответ (как сервис).

Как работает под капотом

Когда клиент шлёт цель, сервер сначала решает, принять её или отклонить (например, занят другой целью). Принятая цель получает уникальный goal_id и переходит в состояние EXECUTING. Сервер в отдельном потоке выполняет работу и периодически публикует feedback. По завершении цель уходит в SUCCEEDED, CANCELED или ABORTED, и клиент получает result. Эта машина состояний позволяет нескольким клиентам ставить цели и отслеживать их по goal_id.

Частые ошибки

  • Использовать топик вместо действия для задачи с целью. Теряете отмену, прогресс и понимание, выполнено ли.
  • Блокировать сервер в обработчике цели. Выполнение должно идти так, чтобы можно было принять запрос на отмену.
  • Игнорировать состояние ABORTED. Робот может застрять; клиент обязан обработать неудачный результат, а не считать любой ответ успехом.

Итоги

  • Действия — для длительных задач с обратной связью и отменой.
  • Файл .action: цель, результат, обратная связь (три секции через ---).
  • Под капотом действие — комбинация сервисов и топиков.
  • Цель проходит машину состояний и идентифицируется goal_id.
Проверьте себя
1. Для чего предназначены действия (actions)?
AДля разовых мгновенных команд
BДля длительных задач с обратной связью и возможностью отмены
CДля хранения параметров
DДля замены топиков
2. Из каких трёх частей состоит файл .action?
Ainit, run, stop
Bgoal, result, feedback
Crequest, response, error
Dheader, body, footer
3. Чем действие является под капотом?
AСовершенно новым примитивом без связи с топиками
BКомбинацией сервисов (цель/отмена) и топиков (feedback/статус)
CПросто переименованным топиком
DФайлом конфигурации