ROS学习路(篇二)话题消息的定义与使用

1、自定义消息类型

打开catkin_ws/src/learning_topic/src路径:

~$ cd ~/catkin_ws/src/learning_topic/src

然后创建msg文件夹存放自定义的消息文件Person.msg。
ROS学习路(篇二)话题消息的定义与使用_第1张图片

string name
uint8 sex
uint8 age

uint8 unknown = 0
uint8 male = 1
uint8 female = 2

定义好之后依次修改learning_topic下的package.xml和CMakeList.txt文件,以让刚创建的msg文件可以被编译。
在pachage.xml中添加两行代码:

	message_generation
	message_runtime

这两行代码声明了编译和执行时所依赖的包。
package.xml文件修改如下:
ROS学习路(篇二)话题消息的定义与使用_第2张图片
同样的,在CMakeList.txt中做对应修改,在find_package下添加message_generation:

ROS学习路(篇二)话题消息的定义与使用_第3张图片
并在 ## Declare ROS messages, services and actions## 下添加下列代码:

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

完成后,回到工作空间下,并编译整个工作空间。

~$ cd ~/catkin_ws
~$ catkin_make

至此,自定义消息的工作就完成了,总结一下,流程为:
1、创建文件夹,自定义消息类型(本质是结构体的定义,消息是以结构体为单位传输的,但要符合ros的规则,如uint8等关键字);
2、修改pakage.xml和CMakeList.txt文件,本质就是修改编译规则,自定义的消息类型要在编译时可以被正确编译、解读。

2、添加发布者和订阅者

在learning_topic/src下添加发布者代码person_publisher.cpp:

/**
 * 该例程将发布/person_info话题,自定义消息类型learning_topic::Person
 */
 
#include 
#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;
}

同路径下添加订阅者代码person_subscriber.cpp:

/**
 * 该例程将订阅/person_info话题,自定义消息类型learning_topic::Person
 */
 
#include 
#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;
}

修改CMakeList.txt,添加下面六行代码,说明编译规则:
ROS学习路(篇二)话题消息的定义与使用_第4张图片
完成后编译,启动订阅者和发布者,运行成功。
ROS学习路(篇二)话题消息的定义与使用_第5张图片

3、总结

不管是自定义的消息还是订阅者和发布者,其流程都是一样的:
1、建立规则文件:
订阅者和发布者就是建立cpp源文件,定义名称、规则、回调函数等;
消息就是建立消息文件,定义新的消息类型应该是什么样的消息,具有什么样的规则;
2、建立好规则文件或者说源文件后,就是修改package.xml和CMakeList.txt文件,添加运行和编译应该依赖的包、编译时应该链接的库。

你可能感兴趣的:(ROS学习路)