• ROS学习总结十七:自定义消息的使用


    在初学ROS时,一般都是使用的ROS标准库,包括激光电云laserscan、位姿posestamp等。这些库基本满足了我们的日常使用,但是在开发时,难免会遇到一些情况使用标准库不太合适,这时候使用自己的自定义消息格式就变得非常方便。

    1、新建msg

    1.1、新建msg文件

    首先建立一个名为catkin_ws的文件夹,在文件夹内执行:

    mkdir src
    cd src
    catkin_create_pkg msg_test roscpp rospy 
    
    • 1
    • 2
    • 3

    这里的含义是在src文件夹下新建一个catkin工程,工程名称为msg_test,依赖于roscpp以及rospy

    然后执行:

    cd msg_test
    mkdir msg
    cd msg
    gedit point.msg
    
    • 1
    • 2
    • 3
    • 4

    这里的含义是在msg_test文件夹下新建一个msg文件夹,并在该文件夹内添加一个point.msg消息。

    然后在该文件内添加如下代码:

    float64 x
    float64 y
    float64 z
    
    • 1
    • 2
    • 3

    最后显示如下:
    在这里插入图片描述
    到这里我们的一个自定义消息就建立完成了,但是如果需要让其生效的话需要修改cmakelist文件以及package.xml文件。

    1.2、编译msg文件

    首先对于cmakelist文件,需要确定以下几个地方:
    一、

    find_package(catkin REQUIRED COMPONENTS
      geometry_msgs
      roscpp
      rospy
      message_generation
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    find_package这里需要包含message_generation,初始时应该是只有roscpp以及rospy的,其他依赖需要自己根据需要添加

    二、

    ## Generate messages in the 'msg' folder
     add_message_files(
       FILES
       point.msg
    #   Message2.msg
     )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    Generate messages这里需要添加自己的msg消息,代表链接的是哪一个具体的msg,例如这里我需要生成的point.msg所以这里需要添加这一行

    point.msg
    
    • 1

    其他部分不用改动

    三、

    ## Generate added messages and services with any dependencies listed here
     generate_messages(
       DEPENDENCIES
    #   geometry_msgs
     )
    
    • 1
    • 2
    • 3
    • 4
    • 5

    generate_messages这里是一定要有的,要不然即使编译成功也不会生成自己的msg

    另外对于package.xml文件,需要确认其中这两行代码即可:

    <build_depend>message_generation</build_depend>
    <exec_depend>message_runtime</exec_depend>
    
    • 1
    • 2

    在这些地方都确认无误的情况下,在catkin_ws文件夹下打开终端,使用catkin_make命令编译文件夹。如果没有问题的话会在catkin_ws/devel路径下生成一个include文件夹,其中存储了名为point.h的文件。注意这个文件并不是一开始就有的,而是通过msg文件编译生成的。
    在这里插入图片描述

    2、使用msg

    这里可以建立一个简单的talker来使用上面定义的msg并进行话题的发布。代码比较简单就直接给出了:

    #include "ros/ros.h"   
    #include "msg_test/point.h" 
    int main(int argc, char **argv)  
    {  
     
      ros::init(argc, argv, "talker");  
      
      ros::NodeHandle n;  
    
      ros::Publisher chatter_pub = n.advertise<msg_test::point>("chatter", 1000);  
    
      ros::Rate loop_rate(10);  
       
      while (ros::ok())  
      {  
        msg_test::point point;
        point.x=1;
        point.y=2;
        point.z=3;
        chatter_pub.publish(point); 
        ros::spinOnce();  
        loop_rate.sleep();    
       }  
        return 0;  
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    这个文件写在src文件夹下,我们命名为msg_test.cpp。同样的在catkin_ws下进行编译一下,然后在终端中输入执行该node:

    roscore
    rosrun msg_test msg_test
    
    • 1
    • 2

    注意执行前先把路径添加到bashrc文件夹下,要不然会显示找不到该node,添加方式:

    gedit ~/.bashrc
    
    • 1

    打开bashrc文件,在最后名添加一行:

    source ~/catkin_ws/devel/setup.bash
    
    • 1

    点击保存,关闭该文件,然后执行:

    source ~/.bashrc
    
    • 1

    最后,新开一个终端,监听一下chatter话题,可以看到结果如下:
    在这里插入图片描述

    3、多msg使用

    在定义msg的时候,有时可以定义多个msg,或者在自己的msg中调用其他msg。例如我们可以定义如下的mg消息格式:

    string id
    msg_test/point[] data
    geometry_msgs/Pose pose
    
    • 1
    • 2
    • 3

    这是一个非标准的数据格式,包含了一个自定义的string,一个我们之前定义的消息类型point数组以及一个标准的ROS库函数geometry_msgs/Pose

    需要注意如果添加官方标准库的话要在cmakelist文件夹中的:

    ## Generate added messages and services with any dependencies listed here
     generate_messages(
       DEPENDENCIES
    #   geometry_msgs
     )
    
    • 1
    • 2
    • 3
    • 4
    • 5

    这里添加对应的库函数,例如这里需要改为:

    ## Generate added messages and services with any dependencies listed here
     generate_messages(
       DEPENDENCIES
       geometry_msgs
     )
    
    • 1
    • 2
    • 3
    • 4
    • 5

    要不然编译时会提示找不到geometry_msgs

    然后我们可以同样通过一个chatter测试一下msg:

    #include "ros/ros.h"    
    #include "msg_test/points.h" 
    int main(int argc, char **argv)  
    {  
     
      ros::init(argc, argv, "talker");  
      
      ros::NodeHandle n;  
    
      ros::Publisher chatter_pub = n.advertise<msg_test::points>("chatter", 1000);  
    
      ros::Rate loop_rate(10);  
       
      while (ros::ok())  
      {  
        msg_test::points points;
        points.id="123";
        msg_test::point point;
        for(int i=0;i<3;i++)
        {
          point.x=i;
          point.y=i+1;
          point.z=i+2;
          points.data.push_back(point);
        }
        points.pose.position.x=1;
        points.pose.position.y=2;
        chatter_pub.publish(points); 
        ros::spinOnce();  
        loop_rate.sleep();    
       }  
        return 0;  
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    监听话题输出如下:
    在这里插入图片描述

    代码存放在:

    https://download.csdn.net/download/YiYeZhiNian/86511347?spm=1001.2014.3001.5501
    
    • 1
  • 相关阅读:
    知名压缩软件 xz 被植入后门,黑客究竟是如何做到的?
    Ubuntu22.04版本安装对应版本ROS教程 (小白2024年)
    飞书公式总结
    冬季如何养胃?羊大师建议水果蔬菜不可少!
    两步搭建云成本管理指标中台
    Selenium自动化测试框架
    【JavaWeb】JSP学习笔记
    Java注释:类、方法和字段注释
    一文详解训练LLM流程
    Java异常机制
  • 原文地址:https://blog.csdn.net/YiYeZhiNian/article/details/126746166