Работа с Action

Модель коммуникации в режиме Действие (Action) используется, когда выполнение запрошенной команды занимает продолжительное время и необходима обратная связь с процессом. Это очень похоже на модель Service: (Service Request) используется как Задача (Action Goal), а ответ (Service Response) используется как Результат (Action Result). Также есть дополнительная сущность Обратная Связь (Action Feedback) для передачи промежуточных результатов выполнения процесса для клиента.

Например, как показано на рисунке, если клиент устанавливает цель -- мыть посуду, сервер начинает мыть посуду и в процессе информирует клиента о ходе мытья посуды в форме обратной связи. После окончания обработки, сервер отправляет клиенту сообщение об окончании процесса.

В отличие от службы (Service), действие (Action) часто используется для управления сложными задачами робота, такими как передвижение к заданной точке, запуск лазерного сканирования, перемещение манипуляторов робота по сложной траектории и т.п.

Файл описания действия (Action) .action

Файлы описания действия (Action) находятся в директории ./action пакета имеют расширение .action, и выглядят приблизительно так:

# Определение цели (goal)
uint32 dishes  # Сколько мыть тарелок
---
# Определение результата (result)
uint32 total_dishes_cleaned # Сколько всего было вымыто
---
# Определение обратной связи (feedback)
uint32 dishes_cleaned # Сколько вымыто посуды сейчас

На основе этого файла .action создаются 6 вспомогательных сообщений, чтобы клиент и сервер могли общаться. Это создание сообщений автоматически запускается во время процесса сборки пакета.

Для файла DoDishes.action будут созданы файлы

DoDishesAction.msg
DoDishesActionGoal.msg
DoDishesActionResult.msg
DoDishesActionFeedback.msg
DoDishesGoal.msg
DoDishesResult.msg
DoDishesFeadback.msg

Дополнительная информация о работе с Действиями (Action) доступна на станице ROS wiki http://wiki.ros.org/actionlib

Примеры работы на Python

Action Server

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

Для действия описанного в файле DoDishes.action пакета ros_book_samples напишем пример сервера action_server.py

#! /usr/bin/env python
# -*- coding: utf-8 -*-

import roslib
import rospy
import actionlib

from ros_book_samples.msg import DoDishesAction, DoDishesResult, DoDishesFeedback

class DoDishesServer:
    # Определяем обьекты Обратная связь и Результат
    _feedback = DoDishesFeedback()
    _result = DoDishesResult()

    def __init__(self):
        # Создаем и запускаем SimpleActionServer для обработки запросов
        self.server = actionlib.SimpleActionServer('do_dishes', DoDishesAction, self.execute, False)
        self.server.start()

    def execute(self, goal):
        # Определяем внутренние переменные каждого запроса
        r = rospy.Rate(1) # эмулируем задержку в 1 секунду на выполнение
        self.clear_dishes = 0

        # Моем каждую тарелку
        for i in range(1, goal.dishes+1):
            self.server.publish_feedback(DoDishesFeedback(i))
            self.clear_dishes+=1
            r.sleep()
        # После завершения цикла информируем клиента об окончании работы
        self.server.set_succeeded(DoDishesResult(self.clear_dishes))


if __name__ == '__main__':
    rospy.init_node('do_dishes_server')
    server = DoDishesServer()
    rospy.spin()

Полное описание класса SimpleActionServer доступно http://www.ros.org/doc/api/actionlib/html/classactionlib_1_1simple__action__server_1_1SimpleActionServer.html

Action Client

Клиент создает задачу на сервере, обрабатывает обратную связь и выводит финальный результат.

#! /usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import print_function

import rospy
import actionlib

# Подключение классов DoDishesAction и DoDishesGoal из пакета ros_book_samples
from ros_book_samples.msg import DoDishesAction, DoDishesGoal

# Функция для обработки сигнала Обратной связи (Action Feadback)
def action_feedback(fb):
    print(fb)

# Функция клиента
def action_client():
    # Создаем клиента для работы с Действиями с именем do_dishes
    client = actionlib.SimpleActionClient('do_dishes', DoDishesAction)

    # Ожидание подключение к серверу
    client.wait_for_server()

    # Создание задачи на 10 тарелок
    goal = DoDishesGoal(dishes=10)

    # Отправка задачи на сервер и определение метода обработки для Обратной связи (Action Feadback)
    client.send_goal(goal, feedback_cb=action_feedback)

    # Ожидание результата (Action Result) работы сервера
    client.wait_for_result()

    # Возвращаем полученный от сервера результат
    return client.get_result()

if __name__ == '__main__':
    try:
        # Инициализация ноды и запуск SimpleActionClient
        rospy.init_node('book_action_client_py')
        result = action_client()
        print("Result:", result)
    except rospy.ROSInterruptException:
        print("program interrupted before completion", file=sys.stderr)

Описание класса SimpleActionClient доступно http://www.ros.org/doc/api/actionlib/html/classactionlib_1_1simple__action__client_1_1SimpleActionClient.html

Запуск примеров возможен или через прямой запуск скриптов python или через запуск rosrun

rosrun ros_book_samples action_server.py
rosrun ros_book_samples action_client.py

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

rosrun ros_book_samples action_client.py

dishes_cleaned: 1
dishes_cleaned: 2
dishes_cleaned: 3
dishes_cleaned: 4
dishes_cleaned: 5
dishes_cleaned: 6
dishes_cleaned: 7
dishes_cleaned: 8
dishes_cleaned: 9
dishes_cleaned: 10
Result: total_dishes_cleaned: 10

Использование модели Action в новых пакетах

Для использования Actionlib в новых пакетах, необходимо удостовериться, что установлены все зависимости и внесены изменения в конфигурацию make.

В файле CMakeLists.txt необходимо внести изменения

find_package(catkin REQUIRED genmsg actionlib_msgs actionlib)
add_action_files(DIRECTORY action FILES DoDishes.action)
generate_messages(DEPENDENCIES actionlib_msgs)

В файле package.xml должны быть подключенны зависимости

<build_depend>actionlib</build_depend>
<build_depend>actionlib_msgs</build_depend>
<exec_depend>actionlib</exec_depend>
<exec_depend>actionlib_msgs</exec_depend>

Дополнительная информация

Модуль ActionLib имеет довольно сложную структуру взаимодействия и выполнения задач. Как Сервер так и Клиент обрабатывают запросы по принципу Машины состояния (State Machine). Задачи могут отменяться, останавливаться и заново запускаться. Подробное описание этого взаимодействия описано на Wiki странице http://wiki.ros.org/actionlib/DetailedDescription

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

results matching ""

    No results matching ""