Introducción a ROS (5): programación de comunicación ROS (programación de acción)

Referencia: "Práctica de desarrollo de robots ROS"
Nota: continúe implementando la programación de comunicación en el paquete de funciones learning_communication en el espacio de trabajo catkin_ws

1. Modelo de comunicación de acción.

Inserte la descripción de la imagen aquí

2. Programación de acciones.

1. Proceso de programación del servicio:

1. Cree un servidor;
2. Cree un cliente;
3. Agregue opciones de compilación;
4. Ejecute un archivo ejecutable;

2. Acción de archivo de acción personalizada

a. Cree un directorio de acciones en learning_communication y un archivo DoDishes.action en el directorio de acciones
Inserte la descripción de la imagen aquí

#Define the goal
uint32 dishwasher_id #Specify which dishwasher we want to use
---
#Define the result
uint32 total_dishes_cleaned
---
#Define a feedback message
float32 percent_complete

b. Agregar dependencia de paquete de funciones en package.xml

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

c. Agregar opciones de compilación en CMakeLists.txt

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

d. Compilación
Genere un archivo ejecutable en el espacio de trabajo catkin_ws:

catkin_make

3. Crear un servidor de acciones

a. Cree el archivo DoDishes_server.cpp en el siguiente directorio:
Inserte la descripción de la imagen aquí
b. El código del archivo DoDishes_server.cpp es el siguiente:

#include <ros/ros.h>
#include <actionlib/server/simple_action_server.h>
#include "learning_communication/DoDishesAction.h"

typedef actionlib::SimpleActionServer<learning_communication::DoDishesAction> Server;

// 收到action的goal后调用该回调函数
void execute(const learning_communication::DoDishesGoalConstPtr& goal, Server* as)
{
   ros::Rate r(1);
   learning_communication::DoDishesFeedback feedback;

   ROS_INFO("Dishwasher %d is working.", goal->dishwasher_id);

   // 假设洗盘子的进度,并且按照1hz的频率发布进度feedback
   for(int i=1; i<=10; i++)
   {
       feedback.percent_complete = i * 10;
       as->publishFeedback(feedback);
       r.sleep();
   }

   // 当action完成后,向客户端返回结果
   ROS_INFO("Dishwasher %d finish working.", goal->dishwasher_id);
   as->setSucceeded();
}

int main(int argc, char** argv)
{
   ros::init(argc, argv, "do_dishes_server");
   ros::NodeHandle n;

   // 定义一个服务器
   Server server(n, "do_dishes", boost::bind(&execute, _1, &server), false);
   
   // 服务器开始运行
   server.start();

   ros::spin();

   return 0;
}

c. Lógica de implementación
(1) Inicialice el nodo ROS;
(2) Cree una instancia de servidor de acción;
(3) Inicie el servidor y espere la solicitud de acción;
(4) Complete el procesamiento de la función de servicio de acción en la función de devolución de llamada y retroalimente la información de progreso;
(5 ) La acción se completa y se envía el mensaje final;

4. Crear un cliente de acción

a. Cree el archivo DoDishes_client.cpp en el siguiente directorio:
Inserte la descripción de la imagen aquí
b. El código del archivo DoDishes_client.cpp es el siguiente:

#include <actionlib/client/simple_action_client.h>
#include "learning_communication/DoDishesAction.h"

typedef actionlib::SimpleActionClient<learning_communication::DoDishesAction> Client;

// 当action完成后会调用该回调函数一次
void doneCb(const actionlib::SimpleClientGoalState& state,
       const learning_communication::DoDishesResultConstPtr& result)
{
   ROS_INFO("Yay! The dishes are now clean");
   ros::shutdown();
}

// 当action激活后会调用该回调函数一次
void activeCb()
{
   ROS_INFO("Goal just went active");
}

// 收到feedback后调用该回调函数
void feedbackCb(const learning_communication::DoDishesFeedbackConstPtr& feedback)
{
   ROS_INFO(" percent_complete : %f ", feedback->percent_complete);
}

int main(int argc, char** argv)
{
   ros::init(argc, argv, "do_dishes_client");

   // 定义一个客户端
   Client client("do_dishes", true);

   // 等待服务器端
   ROS_INFO("Waiting for action server to start.");
   client.waitForServer();
   ROS_INFO("Action server started, sending goal.");

   // 创建一个action的goal
   learning_communication::DoDishesGoal goal;
   goal.dishwasher_id = 1;

   // 发送action的goal给服务器端,并且设置回调函数
   client.sendGoal(goal,  &doneCb, &activeCb, &feedbackCb);

   ros::spin();

   return 0;
}

c. Lógica de implementación
(1) Inicializar nodo ROS;
(2) Crear instancia de cliente de acción;
(3) Conectarse al servidor de acción;
(4) Enviar objetivo de acción;
(5) Procesar la función de devolución de llamada de acuerdo con diferentes tipos de comentarios del servidor

5. Agregar opciones de compilación

Método de compilación

Compile el código en el archivo CMakeLists.txt:

(1) Establecer el código que se compilará y el archivo ejecutable generado;
(2) Establecer la biblioteca de enlaces;
(3) Establecer la dependencia;

Operación específica

Abra el archivo CMakeLists.txt en el paquete de funciones learning_communication y agregue el siguiente código:

add_executable(DoDishes_client src/DoDishes_client.cpp)
target_link_libraries(DoDishes_client ${catkin_LIBRARIES})
add_dependencies(DoDishes_client ${${PROJECT_NAME}_EXPORTED_TARGETS})

add_executable(DoDishes_server src/DoDishes_server.cpp)
target_link_libraries(DoDishes_server ${catkin_LIBRARIES})
add_dependencies(DoDishes_server ${${PROJECT_NAME}_EXPORTED_TARGETS})

Generar

Genere un archivo ejecutable en el espacio de trabajo catkin_ws:

catkin_make

6. Ejecute el archivo ejecutable

Tenga en cuenta que cada vez que abra una nueva terminal para agregar variables de entorno: (si necesita agregar manualmente)

source ~/test/catkin_ws/devel/setup.bash

a. Abra
la terminal de ROS Master :

roscore

b. Inicie el cliente y
abra la terminal:

rosrun learning_communication DoDishes_client

c. Inicie el servidor y
abra una nueva terminal:

rosrun learning_communication DoDishes_server

Inserte la descripción de la imagen aquí

26 artículos originales publicados · elogiados 0 · visitas 1206

Supongo que te gusta

Origin blog.csdn.net/weixin_44264994/article/details/105273388
Recomendado
Clasificación