ROS es la abreviatura de Robot Operating System Este artículo presenta la introducción del desarrollo de aplicaciones ROS, la definición y el uso de datos de servicio. La comunicación entre el cliente y el servidor utiliza datos de servicio. Este artículo primero define los datos de un servicio. Después de que la compilación sea exitosa, use un servidor y un cliente para verificar. El cliente también puede usar la llamada rosservice directamente, de modo que el cliente no necesite un programa. La verificación de la prueba es primero el código C ++ y luego el código Python. También puede optar por ver solo el que conoce.
Creación de paquetes de funciones
Este artículo es una continuación de la programación del Cliente Cliente en la introducción al desarrollo de aplicaciones ROS . Si ha creado un paquete de funciones en ese artículo, no lo necesita aquí, simplemente omita esta sección.
El espacio de trabajo de ROS se establece en el artículo Desarrollo de ROS y preparación de aplicaciones: crear un espacio de trabajo . Ahora, cree un paquete funcional:
cd ~ / catkin_ws / src
catkin_create_pkg servicio_de_aprendizaje std_msgs roscpp rospy geometry_msgs turtlesim
Datos de servicio personalizados
Cree un nuevo directorio srv en el directorio del paquete del proyecto
cd ~ / catkin_ws / src / learning_service
mkdir srv
cd srv
Luego crea un nuevo archivo Person.srv
nano Person.srv
El contenido del archivo es:
string name
uint8 age
uint8 sex
uint8 unknown = 0
uint8 male = 1
uint8 female = 2
---
string result
Echemos un vistazo a las características de este archivo:
Los datos de la solicitud y los datos de la respuesta están separados por --- 3 líneas horizontales-, la parte superior son los datos de la solicitud y la parte inferior son los datos de la respuesta.
Lo anterior es para enviar datos, el tipo de datos que no está asignado es el tipo de datos y el valor asignado puede ser una clase de enumeración, por lo que debe ingresar 3 variables nombre de cadena, uint8 age, uint8 sex
A continuación se muestran los datos de respuesta, aquí hay solo una cadena
Regrese al directorio del paquete del proyecto, abra y edite package.xml:
cd ~ / catkin_ws / src / learning_service
nano package.xml
Agregue las siguientes 2 líneas:
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
La posición agregada se refiere a la siguiente posición, que está encima del comentario delante de <export>:
<exec_depend>roscpp</exec_depend>
<exec_depend>rospy</exec_depend>
<exec_depend>std_msgs</exec_depend>
<exec_depend>turtlesim</exec_depend>
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
<!-- The export tag contains other, unspecified, tags -->
<export>
Luego abra y edite CMakeLists.txt, un total de 3
nano CMakeLists.txt
Primero agregue message_generation en find_package y
agréguelo de la siguiente manera:
find_package(catkin REQUIRED COMPONENTS
geometry_msgs
roscpp
rospy
std_msgs
turtlesim
message_generation
)
Agregue el siguiente código, que también se puede usar como 2 líneas,
add_service_files(
FILES
Person.srv
)
generate_messages(
DEPENDENCIES
std_msgs
)
La ubicación para agregar es la siguiente:
## Generate added messages and services with any dependencies listed here
# generate_messages(
# DEPENDENCIES
# geometry_msgs# std_msgs
# )
add_service_files(
FILES
Person.srv
)
generate_messages(
DEPENDENCIES
std_msgs
)
################################################
## Declare ROS dynamic reconfigure parameters ##
################################################
En catkin_package, descomente la línea CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs turtlesim y agregue message_runtime para
tener el siguiente efecto:
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES learning_topic
CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs turtlesim message_runtime
# DEPENDS system_lib
)
Después de modificar estos dos archivos, compile en el espacio de trabajo.
La compilación debe volver al directorio ~ / catkin_ws
cd ~ / catkin_ws
catkin_make
Si la compilación se realiza correctamente, los datos del servicio están definidos y listos.
Mira la etapa final de la información de compilación.
Scanning dependencies of target learning_service_generate_messages_py
[ 40%] Generating Python code from SRV learning_service/Person
[ 45%] Generating Python srv __init__.py for learning_service
[ 45%] Built target turtle_command_server
Scanning dependencies of target learning_service_generate_messages_eus
[ 50%] Generating EusLisp code from learning_service/Person.srv
[ 54%] Generating EusLisp manifest code for learning_service
[ 54%] Built target learning_service_generate_messages_py
Scanning dependencies of target learning_service_generate_messages_nodejs
[ 59%] Generating Javascript code from learning_service/Person.srv
[ 59%] Built target learning_service_generate_messages_nodejs
Scanning dependencies of target learning_service_generate_messages_cpp
[ 63%] Generating C++ code from learning_service/Person.srv
[ 63%] Built target learning_service_generate_messages_cpp
Scanning dependencies of target learning_service_generate_messages_lisp
[ 68%] Generating Lisp code from learning_service/Person.srv
[ 68%] Built target learning_service_generate_messages_lisp
[ 72%] Built target learning_topic_generate_messages_nodejs
[ 77%] Built target learning_topic_generate_messages_cpp
[ 86%] Built target learning_topic_generate_messages_eus
[ 95%] Built target learning_topic_generate_messages_py
[100%] Built target learning_topic_generate_messages_lisp
[100%] Built target learning_topic_generate_messages
[100%] Built target learning_service_generate_messages_eus
Scanning dependencies of target learning_service_generate_messages
[100%] Built target learning_service_generate_messages
Parece estar listo para varios idiomas.
c ++ verificar el código fuente
Para usar los datos del servicio para verificar, necesita dos programas para el servidor y el cliente, y los colocamos en el directorio src del directorio del proyecto.
Vaya al directorio src y cree los archivos person_client.cpp y person_server.cpp.cpp respectivamente
cd ~ / catkin_ws / src / servicio_aprendizaje / src
nano person_client.cpp
El contenido del archivo es:
/**
* 该例程将请求/show_person服务,服务数据类型learning_service::Person
*/
#include <ros/ros.h>
#include "learning_service/Person.h"
int main(int argc, char** argv)
{
// 初始化ROS节点
ros::init(argc, argv, "person_client");
// 创建节点句柄
ros::NodeHandle node;
// 发现/spawn服务后,创建一个服务客户端,连接名为/spawn的service
ros::service::waitForService("/show_person");
ros::ServiceClient person_client = node.serviceClient<learning_service::Person>("/show_person");
// 初始化learning_service::Person的请求数据
learning_service::Person srv;
srv.request.name = "Tom";
srv.request.age = 20;
srv.request.sex = learning_service::Person::Request::male;
// 请求服务调用
ROS_INFO("Call service to show person[name:%s, age:%d, sex:%d]",
srv.request.name.c_str(), srv.request.age, srv.request.sex);
person_client.call(srv);
// 显示服务调用结果
ROS_INFO("Show person result : %s", srv.response.result.c_str());
return 0;
};
nano person_server.cpp
El contenido del archivo es:
/**
* 该例程将执行/show_person服务,服务数据类型learning_service::Person
*/
#include <ros/ros.h>
#include "learning_service/Person.h"
// service回调函数,输入参数req,输出参数res
bool personCallback(learning_service::Person::Request &req,
learning_service::Person::Response &res)
{
// 显示请求数据
ROS_INFO("Person: name:%s age:%d sex:%d", req.name.c_str(), req.age, req.sex);
// 设置反馈数据
res.result = "OK";
return true;
}
int main(int argc, char **argv)
{
// ROS节点初始化
ros::init(argc, argv, "person_server");
// 创建节点句柄
ros::NodeHandle n;
// 创建一个名为/show_person的server,注册回调函数personCallback
ros::ServiceServer person_service = n.advertiseService("/show_person", personCallback);
// 循环等待回调函数
ROS_INFO("Ready to show person informtion.");
ros::spin();
return 0;
}
2 archivos están listos.
Configurar el archivo cmake
En el directorio ~ / catkin_ws / src / learning_service /, hay un archivo CMakeLists.txt, necesitamos modificar este archivo
cd ~ / catkin_ws / src / learning_service /
nano CMakeLists.txt
Agregue las siguientes líneas a este archivo,
add_executable(person_server src/person_server.cpp)
target_link_libraries(person_server ${catkin_LIBRARIES})
add_dependencies(person_server ${PROJECT_NAME}_gencpp)
add_executable(person_client src/person_client.cpp)
target_link_libraries(person_client ${catkin_LIBRARIES})
add_dependencies(person_client ${PROJECT_NAME}_gencpp)
La posición agregada es el final de la sección Build. Consulte la siguiente posición, que está frente a ## install ##, y luego el cliente anterior y el servidor agregan 2 líneas después de cada una:
## Specify libraries to link a library or executable target against
# target_link_libraries(${PROJECT_NAME}_node
# ${catkin_LIBRARIES}
# )
add_executable(turtle_spawn src/turtle_spawn.cpp)
target_link_libraries(turtle_spawn ${catkin_LIBRARIES})
add_executable(turtle_command_server src/turtle_command_server.cpp)
target_link_libraries(turtle_command_server ${catkin_LIBRARIES})
add_executable(person_server src/person_server.cpp)
target_link_libraries(person_server ${catkin_LIBRARIES})
add_dependencies(person_server ${PROJECT_NAME}_gencpp)
add_executable(person_client src/person_client.cpp)
target_link_libraries(person_client ${catkin_LIBRARIES})
add_dependencies(person_client ${PROJECT_NAME}_gencpp)
#############
## Install ##
#############
Guardar la salida
Esto completa la compilación y configuración.
Compila y ejecuta la prueba
La compilación debe volver al directorio ~ / catkin_ws
cd ~ / catkin_ws
catkin_make
Debe obtenerse una vez después de la compilación:
fuente devel / setup.bash
Si hay un error en la compilación, el error debe eliminarse y la prueba se ejecutará después de que se complete la compilación.
Abra una terminal, inicie ros, ejecute
roscore
Abra otra terminal, inicie el servidor y ejecute
rosrun learning_service person_server
Abra otra terminal e inicie el cliente:
rosrun learning_service person_client
De hecho, también puede utilizar rosservice directamente como cliente para realizar pruebas.
rosservice call / show_person leon 12 2
o
leon @ ubuntu: ~ $ rosservice call / show_person "nombre: 'Leon'
edad: 50
sexo: 20" Los
resultados de ejecución del programa son los siguientes: el cliente primero ejecuta el cliente dos veces, luego la llamada rosservice dos veces y luego el cliente nuevamente
La verificación de c ++ es exitosa.
Python verificar el código fuente
Para verificar los datos del servicio se requieren dos programas, el lado del servidor y el lado del cliente, los colocamos en el directorio de scripts del directorio del proyecto.
Vaya al directorio de scripts y cree los archivos person_client.py y person_server.py respectivamente, si no, cree uno (scripts mkdir).
~ / catkin_ws / src / learning_service / scripts
nano person_server.py
El contenido del archivo es:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 该例程将执行/show_person服务,服务数据类型learning_service::Person
import rospy
from learning_service.srv import Person, PersonResponse
def personCallback(req):
# 显示请求数据
rospy.loginfo("Person: name:%s age:%d sex:%d", req.name, req.age, req.sex)
# 反馈数据
return PersonResponse("OK")
def person_server():
# ROS节点初始化
rospy.init_node('person_server')
# 创建一个名为/show_person的server,注册回调函数personCallback
s = rospy.Service('/show_person', Person, personCallback)
# 循环等待回调函数
print "Ready to show person informtion."
rospy.spin()
if __name__ == "__main__":
person_server()
nano person_client.py
El contenido del archivo es:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 该例程将请求/show_person服务,服务数据类型learning_service::Person
import sys
import rospy
from learning_service.srv import Person, PersonRequest
def person_client():
# ROS节点初始化
rospy.init_node('person_client')
# 发现/spawn服务后,创建一个服务客户端,连接名为/spawn的service
rospy.wait_for_service('/show_person')
try:
person_client = rospy.ServiceProxy('/show_person', Person)
# 请求服务调用,输入请求数据
response = person_client("Tom", 20, PersonRequest.male)
return response.result
except rospy.ServiceException, e:
print "Service call failed: %s"%e
if __name__ == "__main__":
#服务调用并显示调用结果
print "Show person result : %s" %(person_client())
Ejecutar prueba
Porque no es necesario compilar python, pero debe configurarse como un archivo ejecutable
chmod + x * .py
Abra una terminal, inicie ros, ejecute
roscore
Primera fuente:
fuente ~ / catkin_ws / devel / setup.bash
Abra otra terminal, inicie el servidor y ejecute
rosrun learning_service person_server.py
Abra otra terminal e inicie el cliente:
rosrun learning_service person_client.py
La autenticación del cliente también puede usar directamente la llamada rosservice
rosservice call / show_person leon 12 2
o
leon @ ubuntu: ~ $ rosservice call / show_person "nombre: 'Leon'
edad: 50
sexo: 20"
rosservice list puede enumerar todos los nombres de servicios.
Los resultados del programa son los siguientes:
La verificación de Python es exitosa.
El código fuente también se puede descargar en https://github.com/huchunxu/ros_21_tutorials
El texto completo se presenta aquí.