Действия (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.