ROS自定义话题消息

定义msg文件

在catkin_ws/src/中相应功能包下创建文件夹msg,该文件用于存储.msg文件,注意此文件是与编程语言无关的。/.msg文件中的内容相当于是宏定义。

byw@byw-virtual-machine:~/catkin_ws/src/learing_topic/msg$ touch Person.msg

下列代码中的string 、uint8这些表示的是需要在不同的编程语言中扩展成相应语言可以使用的数据类型,而这个过程是在执行编译时进行的。所以需要根据这是数据接口设置一些编译规则。

string name
uint8 sex
uint8 age
uint8 unknown = 0
uint8 male = 1
uint8 female = 2

在这里插入图片描述

添加功能包的依赖

在package.xml中添加功能包依赖。分别添加一个编译依赖包message_generation和一个执行依赖包message_runtime。

<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>

在这里插入图片描述
第一,因为在package.xml中添加了一个依赖包,而在创建功能包时后面跟的依赖包不仅在package.xml中还在CMakeLists.txt中,所以还要添加到CMakeLists.txt中。
在这里插入图片描述
在这里插入图片描述

第二,前面讲到需要将/.msg文件编译成对应的不同文件配置项。
add_message_files是把定义的Person.msg作为编译接口,然后编译的时候针对该文件去编译;
generate_messages是在编译Person.msg时需要哪些ros已有的包,这里需要std_msgs,上文提到的string,uint8都是这里面定义的。

add_message_files(FILES Person.msg)
generate_messages(DEPENDENCIES std_msgs)

在这里插入图片描述
回到工作空间根目录进行编译,可以在编译文件夹./devel/include中查看编译产生的代码文件。注意要在编译成功后才有该c++头文件。
在这里插入图片描述

如何使用自定义话题消息

C++:person_publisher.cpp

/**
 * 该例程将发布/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_subscriber.cpp

**
 * 该例程将订阅/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();

由于是.cpp文件需要编译后才可以执行,所以添加编译配置。
• 设置需要编译的代码和生成的可执行文件;
• 设置链接库(执行编译生成的可执行文件时需要的库);
• 添加依赖项(由于有些代码时动态生成的,所以可执行文件也要和刚才动态生成的头文件链接)。

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)

在这里插入图片描述
在编译完成后,就可执行两个节点了。但不要忘记在rosrun之前需要roscore.

roscore

在这里插入图片描述

  • 5
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
ROS中,我们可以通过自定义消息类型来定义自己的话题消息。以下是一些ROS高级自定义话题消息的示例: 1. 多维数组消息类型 在ROS中,您可以通过定义多维数组消息类型来传递多维数据。例如,您可以定义一个名为“my_array”的消息类型,其中包含一个3x3的二维数组: ``` # my_array.msg float32[9] data ``` 这将定义一个名为“my_array”的消息类型,其中包含一个名为“data”的浮点数数组,大小为9。您可以使用以下代码在ROS中发布此消息类型: ```python import rospy from my_package.msg import my_array rospy.init_node('my_node') pub = rospy.Publisher('my_topic', my_array, queue_size=10) msg = my_array() msg.data = [1,2,3,4,5,6,7,8,9] pub.publish(msg) ``` 2. 自定义消息头 在ROS中,每个消息都具有一个消息头,其中包含有关消息的元数据(例如时间戳、帧ID等)。您可以通过定义自己的消息头来添加其他元数据。 例如,您可以定义一个名为“my_header”的消息头,其中包含一个名为“seq”的序列号和一个名为“frame_id”的帧ID: ``` # my_header.msg uint32 seq string frame_id ``` 然后,您可以将此消息头添加到您的自定义消息类型中: ``` # my_message.msg my_header header float32 data ``` 这将定义一个名为“my_message”的消息类型,其中包含一个名为“header”的消息头和一个名为“data”的浮点数。您可以使用以下代码在ROS中发布此消息类型: ```python import rospy from my_package.msg import my_header, my_message rospy.init_node('my_node') pub = rospy.Publisher('my_topic', my_message, queue_size=10) msg = my_message() msg.header.seq = 1 msg.header.frame_id = 'my_frame' msg.data = 3.14 pub.publish(msg) ``` 3. 嵌套消息类型 在ROS中,您可以将一个消息类型嵌套在另一个消息类型中,以创建更复杂的消息结构。 例如,您可以定义一个名为“my_point”的消息类型,其中包含x、y和z坐标,然后将其嵌套在名为“my_pose”的消息类型中,以表示一个3D位姿: ``` # my_point.msg float32 x float32 y float32 z # my_pose.msg my_point position my_point orientation ``` 这将定义一个名为“my_pose”的消息类型,其中包含名为“position”和“orientation”的两个嵌套的“my_point”消息类型。您可以使用以下代码在ROS中发布此消息类型: ```python import rospy from my_package.msg import my_point, my_pose rospy.init_node('my_node') pub = rospy.Publisher('my_topic', my_pose, queue_size=10) msg = my_pose() msg.position.x = 1.0 msg.position.y = 2.0 msg.position.z = 3.0 msg.orientation.x = 0.0 msg.orientation.y = 0.0 msg.orientation.z = 1.0 pub.publish(msg) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是雨玮a

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值