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 mensajes temáticos. La comunicación entre Publisher Publisher y Subscriber Subscribler utiliza mensajes temáticos. Este artículo primero define un mensaje de tema, luego un editor lo envía y otro suscriptor lo recibe. Primero el código C ++, luego el código Python, también puede elegir ver solo uno con el que esté familiarizado.
Delante del texto 2 ( editor del portal de desarrollo de aplicaciones ROS, programación del editor y suscriptores del portal de desarrollo de aplicaciones ROS, programación Subscribler ) para reducir la complejidad, usamos y simulamos la comunicación de tortugas pequeñas, las noticias del tema están disponibles, pero este artículo se presentará personalizado. mensajes temáticos, esto está en línea con las necesidades reales de mi aplicación. Espero que haya leído los dos artículos anteriores y al menos haya definido el paquete de funciones.
Mensaje de tema personalizado
Cree un nuevo directorio msg en el directorio del paquete del proyecto
cd ~ / catkin_ws / src / learning_topic
mkdir msg
cd msg
Luego crea un nuevo archivo Person.msg
nano Person.msg
El contenido del archivo es:
string name
uint8 age
uint8 sex
uint8 unknown = 0
uint8 male = 1
uint8 female = 2
Regrese al directorio del paquete del proyecto, abra y edite package.xml:
cd ~ / catkin_ws / src / learning_topic
nano package.xml
<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_message_files(
FILES
Person.msg
)
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_message_files(
FILES
Person.msg
)
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
De esta manera, la información del tema está definida y lista.
Mira la etapa final de la información de compilación.
Scanning dependencies of target learning_topic_generate_messages_py
[ 36%] Generating Python from MSG learning_topic/Person
[ 45%] Linking CXX executable /home/leon/catkin_ws/devel/lib/learning_topic/pose_subscriber
[ 54%] Generating Python msg __init__.py for learning_topic
[ 54%] Built target pose_subscriber
Scanning dependencies of target learning_topic_generate_messages_cpp
[ 63%] Generating C++ code from learning_topic/Person.msg
[ 63%] Built target learning_topic_generate_messages_py
Scanning dependencies of target learning_topic_generate_messages_eus
[ 72%] Generating EusLisp code from learning_topic/Person.msg
[ 72%] Built target learning_topic_generate_messages_cpp
Scanning dependencies of target learning_topic_generate_messages_lisp
[ 81%] Generating Lisp code from learning_topic/Person.msg
[ 90%] Generating EusLisp manifest code for learning_topic
[ 90%] Built target learning_topic_generate_messages_lisp
Scanning dependencies of target learning_topic_generate_messages_nodejs
[100%] Generating Javascript code from learning_topic/Person.msg
[100%] Built target learning_topic_generate_messages_nodejs
[100%] Built target learning_topic_generate_messages_eus
Scanning dependencies of target learning_topic_generate_messages
[100%] Built target learning_topic_generate_messages
leon@ubuntu:~/catkin_ws$
Parece estar listo para varios idiomas.
c ++ verificar el código fuente
Para usar la información del tema para verificar, necesita dos programas, editor y suscriptor, todos los colocamos en el directorio src del directorio del proyecto
Vaya al directorio src y cree los archivos person_publisher.cpp y person_subscriber.cpp respectivamente
~ / catkin_ws / src / learning_topic / src
nano person_publisher.cpp
El contenido del archivo es:
/**
* 该例程将发布/person_info话题,自定义消息类型learning_topic::Person
*/
#include <ros/ros.h>
#include "learning_topic/Person.h"
int main(int argc, char **argv)
{
// ROS节点初始化
ros::init(argc, argv, "person_publisher");
// 创建节点句柄
ros::NodeHandle n;
// 创建一个Publisher,发布名为/person_info的topic,消息类型为learning_topic::Person,队列长度10
ros::Publisher person_info_pub = n.advertise<learning_topic::Person>("/person_info", 10);
// 设置循环的频率
ros::Rate loop_rate(1);
int count = 0;
while (ros::ok())
{
// 初始化learning_topic::Person类型的消息
learning_topic::Person person_msg;
person_msg.name = "Tom";
person_msg.age = 18;
person_msg.sex = learning_topic::Person::male;
// 发布消息
person_info_pub.publish(person_msg);
ROS_INFO("Publish Person Info: name:%s age:%d sex:%d",
person_msg.name.c_str(), person_msg.age, person_msg.sex);
// 按照循环频率延时
loop_rate.sleep();
}
return 0;
}
nano person_subscriber.cpp
El contenido del archivo es:
/**
* 该例程将订阅/person_info话题,自定义消息类型learning_topic::Person
*/
#include <ros/ros.h>
#include "learning_topic/Person.h"
// 接收到订阅的消息后,会进入消息回调函数
void personInfoCallback(const learning_topic::Person::ConstPtr& msg)
{
// 将接收到的消息打印出来
ROS_INFO("Subcribe Person Info: name:%s age:%d sex:%d",
msg->name.c_str(), msg->age, msg->sex);
}
int main(int argc, char **argv)
{
// 初始化ROS节点
ros::init(argc, argv, "person_subscriber");
// 创建节点句柄
ros::NodeHandle n;
// 创建一个Subscriber,订阅名为/person_info的topic,注册回调函数personInfoCallback
ros::Subscriber person_info_sub = n.subscribe("/person_info", 10, personInfoCallback);
// 循环等待回调函数
ros::spin();
return 0;
}
2 archivos están listos, a continuación
Configurar el archivo cmake
En el directorio ~ / catkin_ws / src / learning_topic /, hay un archivo CMakeLists.txt, necesitamos modificar este archivo
cd ~ / catkin_ws / src / learning_topic /
nano CMakeLists.txt
Agregue las siguientes líneas a este archivo,
add_executable(person_publisher src/person_publisher.cpp)
target_link_libraries(person_publisher ${catkin_LIBRARIES})
add_dependencies(person_publisher ${PROJECT_NAME}_generate_messages_cpp)
add_executable(person_subscriber src/person_subscriber.cpp)
target_link_libraries(person_subscriber ${catkin_LIBRARIES})
add_dependencies(person_subscriber ${PROJECT_NAME}_generate_messages_cpp)
La ubicación para agregar es hacer referencia a la siguiente ubicación, que está frente a ## install ##, y luego el editor y los suscriptores anteriores 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(velocity_publisher src/velocity_publisher.cpp)
target_link_libraries(velocity_publisher ${catkin_LIBRARIES})
add_executable(pose_subscriber src/pose_subscriber.cpp)
target_link_libraries(pose_subscriber ${catkin_LIBRARIES})
add_executable(person_publisher src/person_publisher.cpp)
target_link_libraries(person_publisher ${catkin_LIBRARIES})
add_dependencies(person_publisher ${PROJECT_NAME}_generate_messages_cpp)
add_executable(person_subscriber src/person_subscriber.cpp)
target_link_libraries(person_subscriber ${catkin_LIBRARIES})
add_dependencies(person_subscriber ${PROJECT_NAME}_generate_messages_cpp)
#############
## 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, debe eliminar el error y luego ejecutar la prueba.
Abra una terminal, inicie ros, ejecute
roscore
Abra otro terminal, inicie el suscriptor, ejecute
rosrun learning_topic person_subscriber
Abra otra terminal e inicie el editor:
rosrun learning_topic person_publisher
Los resultados del programa son los siguientes:
La verificación de c ++ es exitosa.
Python verificar el código fuente
Para usar la información del tema para verificar, necesita dos programas, editor y suscriptor, todos los colocamos en el directorio de scripts del directorio del proyecto
Vaya al directorio de scripts y cree los archivos person_publisher.py y person_subscriber.py respectivamente
~ / catkin_ws / src / learning_topic / scripts
nano person_publisher.py
El contenido del archivo es:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 该例程将发布/person_info话题,自定义消息类型learning_topic::Person
import rospy
from learning_topic.msg import Person
def velocity_publisher():
# ROS节点初始化
rospy.init_node('person_publisher', anonymous=True)
# 创建一个Publisher,发布名为/person_info的topic,消息类型为learning_topic::Person,队列长度10
person_info_pub = rospy.Publisher('/person_info', Person, queue_size=10)
#设置循环的频率
rate = rospy.Rate(10)
while not rospy.is_shutdown():
# 初始化learning_topic::Person类型的消息
person_msg = Person()
person_msg.name = "Tom";
person_msg.age = 18;
person_msg.sex = Person.male;
# 发布消息
person_info_pub.publish(person_msg)
rospy.loginfo("Publsh person message[%s, %d, %d]",
person_msg.name, person_msg.age, person_msg.sex)
# 按照循环频率延时
rate.sleep()
if __name__ == '__main__':
try:
velocity_publisher()
except rospy.ROSInterruptException:
pass
nano person_subscriber.py
El contenido del archivo es:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 该例程将订阅/person_info话题,自定义消息类型learning_topic::Person
import rospy
from learning_topic.msg import Person
def personInfoCallback(msg):
rospy.loginfo("Subcribe Person Info: name:%s age:%d sex:%d",
msg.name, msg.age, msg.sex)
def person_subscriber():
# ROS节点初始化
rospy.init_node('person_subscriber', anonymous=True)
# 创建一个Subscriber,订阅名为/person_info的topic,注册回调函数personInfoCallback
rospy.Subscriber("/person_info", Person, personInfoCallback)
# 循环等待回调函数
rospy.spin()
if __name__ == '__main__':
person_subscriber()
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 otro terminal, inicie el suscriptor, ejecute
rosrun learning_topic person_subscriber.py
Abra otra terminal e inicie el editor:
rosrun learning_topic person_publisher.py
Los resultados del programa son los siguientes:
La verificación de Python es exitosa.
Mostrar relación de flujo de información
Abra una nueva terminal e ingrese el comando:
rqt_graph
Puede ver el siguiente diagrama de relación de información:
El código fuente también se puede descargar en https://github.com/huchunxu/ros_21_tutorials
El texto completo se presenta aquí.