• ROS 笔记(06)— 话题消息的定义和使用


    ROS 中通过 std_msgs 封装了一些原生的数据类型,比如: StringInt32Int64CharBoolEmpty… 但是,这些数据一般只包含一个 data 字段,结构的单一意味着功能上的局限性,当传输一些复杂的数据,比如:激光雷达的信息… std_msgs 由于描述性较差而显得力不从心,这种场景下可以使用自定义的消息类型。

    msgs 只是简单的文本文件,每行具有字段类型和字段名称,可以使用的字段类型有:

    • int8, int16, int32, int64 (或者无符号类型: uint*)
    • float32, float64
    • string
    • time, duration
    • other msg files
    • variable-length array[] and fixed-length array[C]

    ROS 中还有一种特殊类型:Header ,标头包含时间戳和 ROS 中常用的坐标帧信息。会经常看到msg 文件的第一行具有 Header 标头。

    1. 话题模型

    我们要实现的话题模型如下:
    tp其中 Message 中的 Person 为我们自定义的消息格式,该消息在订阅者和发布者之间传递。

    2. 自定义消息实现

    2.1 定义 msg 文件

    在功能包 topic_demo 目录下创建一个 msg 文件夹,在该文件夹中创建一个 Person.msg 文件,如下图所示:
    p
    Person.msg 中有我们自定义的消息格式

    string name
    uint8  age
    uint8  gender
    
    uint8 unknown = 0
    uint8 male    = 1
    uint8 female  = 2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2.2 添加功能包依赖

    package.xml 中添加以下 exec_depend 运行依赖:

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

    2.3 添加编译选项

    cmake

    find_package(catkin REQUIRED COMPONENTS
      geometry_msgs
      rospy
      std_msgs
      turtlesim
      message_generation   # 新增内容
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    add_message_files(
       FILES
       Person.msg
     )
    
    • 1
    • 2
    • 3
    • 4
    generate_messages(
       DEPENDENCIES
       std_msgs
     )
    
    • 1
    • 2
    • 3
    • 4
    catkin_package(
    #  INCLUDE_DIRS include
    #  LIBRARIES topic_demo
       CATKIN_DEPENDS geometry_msgs rospy std_msgs turtlesim message_runtime
    #  DEPENDS system_lib
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.4 编译生成语言相关的文件

    到项目根目录下执行 catkin_make 命令

    $ catkin_make
    Base path: /home/wohu/project/ros/ros_demo
    Source space: /home/wohu/project/ros/ros_demo/src
    Build space: /home/wohu/project/ros/ros_demo/build
    Devel space: /home/wohu/project/ros/ros_demo/devel
    Install space: /home/wohu/project/ros/ros_demo/install
    ####
    #### Running command: "make cmake_check_build_system" in "/home/wohu/project/ros/ros_demo/build"
    ####
    ####
    #### Running command: "make -j12 -l12" in "/home/wohu/project/ros/ros_demo/build"
    ####
    [  0%] Built target std_msgs_generate_messages_py
    [  0%] Built target std_msgs_generate_messages_eus
    [  0%] Built target std_msgs_generate_messages_lisp
    [  0%] Built target std_msgs_generate_messages_nodejs
    [  0%] Built target std_msgs_generate_messages_cpp
    [  0%] Built target _topic_demo_generate_messages_check_deps_Person
    [ 57%] Built target topic_demo_generate_messages_py
    [ 57%] Built target topic_demo_generate_messages_eus
    [ 71%] Built target topic_demo_generate_messages_cpp
    [ 85%] Built target topic_demo_generate_messages_nodejs
    [100%] Built target topic_demo_generate_messages_lisp
    [100%] Built target topic_demo_generate_messages
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    可以看到会生成各种语言的代码文件。其中 Python 相关的代码文件在

    /devel/lib/python2.7/dist-packages
    
    • 1

    目录下

    2.5 运行代码

    发布者代码 person_publisher.py :

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    # 该例程将发布/person_info话题,自定义消息类型learning_topic::Person
    
    import rospy
    from topic_demo.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.gender  = Person.male;
    
    		# 发布消息
            person_info_pub.publish(person_msg)
        	rospy.loginfo("Publsh person message[%s, %d, %d]", 
    				person_msg.name, person_msg.age, person_msg.gender)
    
    		# 按照循环频率延时
            rate.sleep()
    
    if __name__ == '__main__':
        try:
            velocity_publisher()
        except rospy.ROSInterruptException:
            pass
    
    • 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
    • 34
    • 35
    • 36
    • 37
    • 38

    订阅者代码 person_subscriber.py 内容:

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    # 该例程将订阅/person_info话题,自定义消息类型learning_topic::Person
    
    import rospy
    from topic_demo.msg import Person
    
    def personInfoCallback(msg):
        rospy.loginfo("Subcribe Person Info: name:%s  age:%d  gender:%d", 
    			 msg.name, msg.age, msg.gender)
    
    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()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    运行代码命令:

    $ cd  ~/catkin_ws
    $ catkin_make 
    $ source ./devel/setup.bash
    $ rescore
    $ rosrun topic_demo person_subscriber.py
    $ rosrun topic_demo person_publisher.py
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
  • 相关阅读:
    ChatGPT在数据分析学习阶段的应用
    计算机毕业设计(附源码)python-重庆工程学校学生体测监测系统-微信小程序
    SQLserver数据库事务和快照复制兼容性矩阵
    代码随想录算法训练营第23期day7| 454.四数相加II 、383. 赎金信 、15. 三数之和、18. 四数之和
    java基于ssm的快递物流管理系统
    安装向量数据库milvus及其Attu
    状态模式(状态和行为分离)
    “圆”来如此——关于圆周率 π 的36 个有趣事实
    难辨真假的Midjourney案例(附提示词):适合练手
    《单链表》的实现(不含哨兵位的单向链表)
  • 原文地址:https://blog.csdn.net/wohu1104/article/details/125350119