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_generation</build_depend>
<run_depend>message_runtime</run_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_小叮当的博客-优快云博客_rospy.spin

ROS中,对于日期时间信息,通常不会直接创建一个自定义的消息类型,因为已经有内置的标准数据类型`std_msgs/Header`包含了时间戳字段。`Header`消息包含了一条消息的发布时间、空间站以及消息ID等信息,其中`time`字段就是用来存储系统时间的。 如果你想在Python中发布订阅包含日期时间的消息,可以结合使用`std_msgs/Header`以及自定义的数据类型,例如创建一个简单的`DateTimeMessage`。首先,定义一个自定义消息类型: ```python from std_msgs.msg import Header class DateTimeMessage: def __init__(self): self.header = Header() self.datetime = datetime.datetime.now().isoformat() + 'Z' ``` 这里假设你已经导入了`datetime`模块。 然后,发布者部分: ```python import rospy from your_package_name.srv import DateTimeService from datetime_message import DateTimeMessage def publish_datetime(): msg = DateTimeMessage() msg.header.stamp = rospy.Time.now() pub = rospy.Publisher('your_topic_name', DateTimeMessage, queue_size=10) pub.publish(msg) if __name__ == '__main__': rospy.init_node('date_time_publisher') rate = rospy.Rate(1) # 发布频率为每秒一次 while not rospy.is_shutdown(): publish_datetime() rate.sleep() ``` 订阅者部分: ```python from std_msgs.msg import Header from your_package_name.srv import DateTimeService from datetime_message import DateTimeMessage def callback(data): print(f"Received datetime message: {data.datetime}") def subscribe_datetime(): sub = rospy.Subscriber('your_topic_name', DateTimeMessage, callback) rospy.spin() if __name__ == '__main__': rospy.init_node('date_time_subscriber') subscribe_datetime() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值