首页 关于
树枝想去撕裂天空 / 却只戳了几个微小的窟窿 / 它透出天外的光亮 / 人们把它叫做月亮和星星
目录

创建msg文件

上一节中,我们用C++和python实现了两个talker和listener, 它们分别发布和订阅了一个'/chatter'的主题,主题的消息类型为'/std_msgs/String'。本文中我们将用msg文件创建一个自己的消息类型。

所谓的msg文件,就是描述node发布和订阅topic消息类型的文件。它就是一个简单的文本文件,每一行都由数据类型和数据名称两部分组成, 就有点像C语言中变量的定义,只是每一行只能定义一个变量。

1. 创建并编译msg

首先,让我们进入例程的根目录下,创建一个msg的子目录和Num.msg,并用我们最喜欢的编辑器写下如下右面所示的两条语句。

        $ roscd beginner_tutorials 
        $ mkdir msg
        $ touch Num.msg
int32 i32num
float64 f64num

msg文件创建起来很轻松,但我们要想办法把它用到C++, Python的程序中,这就要求我们做些功课了。 我们知道在C++通常通过头文件的形式引入其它模块或者库的API,在Python中通常是通过import来实现的。也就是说,为了使用我们刚刚新创建的Num.msg, 我们还需要把它转换称C++的头文件和py文件才可以在程序中使用。这点ROS已经为我们提供了比较方便的工具。

我们先要打开package.xml文件,在其中加入两个依赖。其中message_generation用于生成与msg文件相关的.h和.py文件。message_runtime则是运行时的依赖。

        <build_depend>message_generation</build_depend>
        <run_depend>message_runtime</run_depend>
接着在CMakeLists.txt文件中添加msg文件规则,在CMake的find_package调用中添加message_generation,添加message文件,并生成message。
        find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs message_generation)
        add_message_files(FILES Num.msg) 
        generate_messages(DEPENDENCIES std_msgs)
没有意外的话,我们已经可以通过rosmsg工具查看新建的message了。
        $ rosmsg show beginner_tutorials/Num
        int32 haha
        float64 hehe
此时,如果我们回到工作空间的根目录下catkin_make一下,就可以在'~/catkin_ws/devel/include/beginner_tutorials/'的目录下找到一个叫做'Num.h'的文件, 在'~/catkin_ws/devel/lib/python2.7/dist-packages/beginner_tutorials/msg'目录下找到'_Num.py'。

2. 应用新建的msg文件

我们对在上一节实现的talker和listener做出一些修改让它们发布和订阅一个以Num为类型的主题。 下面先给出C++版本的修改。左边是talker右边是listener。

     #include "ros/ros.h"
     #include "beginner_tutorials/Num.h"
     
     int main(int argc, char *argv[]) {
         ros::init(argc, argv, "talker");
         ros::NodeHandle n;
     
         ros::Publisher pub =
           n.advertise<beginner_tutorials::Num>("chatter", 1000);
         ros::Rate loop_rate(10);
     
         int count = 0;
         while (ros::ok()) {
             beginner_tutorials::Num msg;
             msg.haha = count;
             msg.hehe = 0.1 * count;
     
             pub.publish(msg);
             ros::spinOnce();
             loop_rate.sleep();
             count++;
         }
         return 0;
     }
     #include "ros/ros.h"
     #include "beginner_tutorials/Num.h"
     
     void callback(const beginner_tutorials::Num::ConstPtr &msg) {
         ROS_INFO("I heard: [%d], [%f]", msg->haha, msg->hehe);
     }
     
     int main(int argc, char *argv[]) {
         ros::init(argc, argv, "listener");
         ros::NodeHandle n;
     
         ros::Subscriber sub = n.subscribe("chatter", 1000, callback);
         ros::spin();
     
         return 0;
     }
在程序中,我们添加头文件"beginner_tutorials/Num.h",它就是在我们之前通过catkin_make生成的Num.h文件,程序中其余部分基本没有改动。 在程序中我们可以通过beginner_tutorial::Num创建一个消息对象msg。

3. 总结

在本文中,我们创建了一个msg文件,然后用在了C++程序中。我们应当把msg文件都保存在package中的msg子目录下,最后需要在package.xml和CMakeLists.txt中添加生成头文件的依赖和规则。 生成的头文件保存在'~/catkin_ws/devel/include/beginner_tutorials/'目录下,在程序中通过#include "PACKAGE_NAME/MSG_NAME.h"使用新建的msg文件。




Copyright @ 高乙超. All Rights Reserved. 京ICP备16033081号-1