ROS用python编写订阅者和发布者(使用存放在其他package的自定义msg文件)

本文记录一下用python编写使用自定义消息的ros订阅者和发布者时存在的一些问题。

声明一下,本文的代码是从自己项目工程截取的,不适合直接使用,只适合作为参照模板

1、首先是如何创建msg文件和编译

文件结构如图:

catkin_ws
├── build
├── devel
└── src
    ├── robot_msgs
    │   ├── CMakeLists.txt
    │   ├── msg
    │   │   └── Controldata.msg
    │   └── package.xml
    └── tcp_ros
        └── script
            └── test.py

catkin_ws工作空间里有两个package,一个只用来存放消息(可自行添加更多消息),一个用于存放代码。

Controldata.msg消息文件如下:

uint32   cmd
float32 param1
float32 param2

在robot_msgs包里的CMakerList.txt:

cmake_minimum_required(VERSION 2.8.3)
project(robot_msgs)
#这里添加依赖message_generation 用于生成消息
find_package(catkin REQUIRED COMPONENTS   
  message_generation 
  std_msgs 
  geometry_msgs
)
#这里添加消息文件Controldata.msg
add_message_files(        
  DIRECTORY msg
  FILES
  Controldata.msg
)

generate_messages(DEPENDENCIES std_msgs geometry_msgs)  
 #这里增加消息生成包message_runtime 
catkin_package(CATKIN_DEPENDS message_runtime std_msgs geometry_msgs)  

在robot_msgs包里的package.xml添加如下:

<build_depend>message_generationbuild_depend>
<run_depend>message_runtimerun_depend>

在tcp_ros包里的CMakerList:

find_package(catkin REQUIRED COMPONENTS   #查找robot_msgs包
  roscpp
  rospy
  std_msgs
  robot_msgs
)
catkin_package(                           #包含robot_msgs包
  INCLUDE_DIRS include
  LIBRARIES tjurobot
  CATKIN_DEPENDS roscpp rospy std_msgs robot_msgs message_runtime    
  DEPENDS system_lib
)

2、python编写的发布者节点

  • 发布者程序: 关键是如何在python节点里导入存在其他package的msg文件!!

    #!/usr/bin/env python
    # license removed for brevity
    import rospy
    from robot_msgs.msg import Controldata  #翻译为:从robot_msgs包里的msg文件夹内导入名为Controldata的msg文件!
    
    def talker():
        pub = rospy.Publisher('chatter', Controldata, queue_size=10)  #设置发布话题名为“chatter”,消息类型为Controldata.msg,消息队列最大容量为10帧的对象pub
        rospy.init_node('talker', anonymous=True)   #初始化名为“talker”的节点
        rate = rospy.Rate(10) # 10hz     
        while not rospy.is_shutdown():
            send_msg = Controldata()   #初始化一个消息结构体:直接以该msg文件名作为函数
            send_msg.cmd =0X15      #给send_msg结构体内参数赋值(也就是该msg文件内参数)
            send_msg.param1 = 123
            send_msg.param2 = 0
            pub.publish(send_msg)    #调用pub对象的publish函数发布话题
            rate.sleep()    #在循环中可以用刚刚好的睡眠时间维持期望的速率,适用于需要不停发布的话题
    
    if __name__ == '__main__':
        try:
            talker()
        except rospy.ROSInterruptException:
            pass
    

3、python编写的订阅者节点

  • 订阅者程序:关键是如何在回调函数里运用话题数据

    #!/usr/bin/env python
    import rospy
    from robot_msgs.msg import Controldata
    
    def callback_fuc(data):      #该data则相当于发布者的send_msg结构体
        rospy.loginfo("I heard %d,%d,%d", data.cmd,data.param1,data.param2)
        
    def listener():
        rospy.init_node('listener', anonymous=True)  #初始化名为“listener”的订阅者节点:anonymous=True会为节点生成唯一的名称避免节点重名
        rospy.Subscriber("chatter", Controldata, callback_fuc)  #设置订阅者属性:订阅的话题名“chatter”,话题对应的msg消息文件名,回调函数名
        rospy.spin()     #必须要有,否则无法接收,但会相当于死循环程序会卡在这里
        
    if __name__ == '__main__':
        listener()
    

    关于如何解决rospy.spin()后程序卡死无法执行的问题可参照该博客:

(94条消息) 解决rospy.spin()一直循环,无法执行剩余程序_DLUT_小叮当的博客-CSDN博客_rospy.spin

你可能感兴趣的:(ros,自动驾驶,人工智能,机器学习,python)