ROS 编写消息发布器和订阅器 &测试(Python catkin)

该博客主要介绍ROS节点的开发流程。首先讲解编写发布器节点talker和订阅器节点,包括创建目录、下载脚本、修改权限及代码解释;接着说明使用CMake编译节点;最后进行测试,分别启动发布器和订阅器节点,并展示输出信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一. 编写发布器节点talker

  • 进入之前创建的beginner_tutorials包
//如果roscd进不了包
export ROS_PACKAGE_PATH=~/catkin_ws/src:$ROS_PACKAGE_PATH
$ roscd beginner_tutorials
  • 首先创建scripts目录存放Python代码:
$ mkdir scripts
$ cd scripts
  • 下载例子脚本talker.py到scripts目录,并修改权限为可执行:
$ wget https://raw.github.com/ros/ros_tutorials/kinetic-devel/rospy_tutorials/001_talker_listener/talker.py
$ chmod +x talker.py     //可执行
  • 浏览和编辑:
$ rosed beginner_tutorials talker.py
  • 内容如下:
#!/usr/bin/env python
# license removed for brevity
import rospy
from std_msgs.msg import String

def talker():
    pub = rospy.Publisher('chatter', String, queue_size=10)
    rospy.init_node('talker', anonymous=True)
    rate = rospy.Rate(10) # 10hz
    while not rospy.is_shutdown():
        hello_str = "hello world %s" % rospy.get_time()
        rospy.loginfo(hello_str)
        pub.publish(hello_str)
        rate.sleep()

if __name__ == '__main__':
    try:
        talker()
    except rospy.ROSInterruptException:
        pass

代码解释

// 每个Python的ROS节点会在顶部描述,第一行确保你的脚本是使用Python执行的脚本
#!/usr/bin/env python
# license removed for brevity

/*
*你需要导入rospy客户端库
*导入std_msgs.msg 重用std_msgs/String消息类型
**/
import rospy
from std_msgs.msg import String

def talker():
    /*
    *定义talker接口,pub = rospy.Publisher("chatter", String, queue_size=10)表示节点发布 
    *chatter话题,使用String字符类型,实际上就是类std_msgs.msg.String。queue_size表示队列的大小 
    *(适合hydro以后版本),如果队列消息处理不够快,就会丢弃旧的消息。
    **/
    pub = rospy.Publisher('chatter', String, queue_size=10)
    //rospy.init_node(NAME),初始化节点,开始跟ROS master通讯。
    rospy.init_node('talker', anonymous=True)

    
    //创建Rate对象,与sleep()函数结合使用,控制话题消息的发布频率。10hz表示每秒发布10次。
    rate = rospy.Rate(10) # 10hz


    /*rospy.is_shutdown()返回false就会退出(例如按下Ctrl-C)

    while not rospy.is_shutdown():
        hello_str = "hello world %s" % rospy.get_time()
        //rospy.loginfo(str)函数在屏幕输出调试信息,同时写入到节点日志文件和rosout节点
        //可以通过rqt_console查看调式信息。
        rospy.loginfo(hello_str)
        pub.publish(hello_str)
        //r.sleep()通过睡眠来,保持消息发送频率
        rate.sleep()

if __name__ == '__main__':
    try:
        talker()
    //当按下Ctrl-C或节点关闭的话,即使在rospy.sleep()和rospy.Rate.sleep()函数里都会抛出异常
    except rospy.ROSInterruptException:
        pass
  • 您也可以传递没有参数和直接初始化字段,例如:
msg = String()
msg.data = str
  • 或者你能初始化某些字段,剩余保持默认值:
String(data=str)

 

 

二.编写订阅器节点

$ roscd beginner_tutorials/scripts/
$ wget https://raw.github.com/ros/ros_tutorials/kinetic-devel/rospy_tutorials/001_talker_listener/listener.py
  • 文件内容如下:
#!/usr/bin/env python
import rospy
from std_msgs.msg import String

def callback(data):
    rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.data)
    
def listener():

    # In ROS, nodes are uniquely named. If two nodes with the same
    # node are launched, the previous one is kicked off. The
    # anonymous=True flag means that rospy will choose a unique
    # name for our 'listener' node so that multiple listeners can
    # run simultaneously.
    rospy.init_node('listener', anonymous=True)

    rospy.Subscriber("chatter", String, callback)

    # spin() simply keeps python from exiting until this node is stopped
    rospy.spin()

if __name__ == '__main__':
    listener()
  • 增加可执行权限:
$ chmod +x listener.py

代码解释

#!/usr/bin/env python
import rospy
from std_msgs.msg import String

def callback(data):
    rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.data)
    
def listener():

    # 这表示节点订阅话题chatter,消息类型是 std_msgs.msgs.String
    # 当接受到新消息,回调函数就触发处理这些信息,并把消息作为第一个参数传递到函数里
    # ROS要求每个节点要有唯一名称,如果相同的名称,就会中止之前同名的节点。
    # anonymous=True标识就会告诉rospy,要生成一个唯一的节点名称,因此你可以有多个listener.py同时运行
    # run simultaneously.
    rospy.init_node('listener', anonymous=True)

    rospy.Subscriber("chatter", String, callback)

    # spin() simply keeps python from exiting until this node is stopped
    rospy.spin()

if __name__ == '__main__':
    listener()

 

 

三.编译节点

  • 我们使用CMake作为构建系统,即使是Python节点也需要使用。
  • 这确保针对消息和服务能自动生成Python代码
  • 进入catkin工作空间,运行catkin_make:
$ cd ~/catkin_ws
$ catkin_make

四.测试

启动发布器

  • 确保roscore可用,并运行:
$ roscore
  • catkin specific 如果使用catkin,确保你在调用catkin_make后,在运行你自己的程序前,已经source了catkin工作空间下的setup.sh文件:
# In your catkin workspace
$ cd ~/catkin_ws
$ source ./devel/setup.bash
  • 上个教程开发了发布节点"talker". 现在运行它:
$ rosrun beginner_tutorials talker.py   (Python) 

  • 你将看到如下的输出信息:
[INFO] [WallTime: 1314931831.774057] hello world 1314931831.77
[INFO] [WallTime: 1314931832.775497] hello world 1314931832.77
[INFO] [WallTime: 1314931833.778937] hello world 1314931833.78
[INFO] [WallTime: 1314931834.782059] hello world 1314931834.78
[INFO] [WallTime: 1314931835.784853] hello world 1314931835.78
[INFO] [WallTime: 1314931836.788106] hello world 1314931836.79
  • 发布器节点已经启动运行。现在需要一个订阅器节点来接受发布的消息。

启动订阅器

  • 上一教程,我们编写了一个名为"listener"的订阅器节点。现在运行它:
$ rosrun beginner_tutorials listener.py  (Python) 

你将会看到如下的输出信息:

[INFO] [WallTime: 1314931969.258941] /listener_17657_1314931968795I heard hello world 1314931969.26
[INFO] [WallTime: 1314931970.262246] /listener_17657_1314931968795I heard hello world 1314931970.26
[INFO] [WallTime: 1314931971.266348] /listener_17657_1314931968795I heard hello world 1314931971.26
[INFO] [WallTime: 1314931972.270429] /listener_17657_1314931968795I heard hello world 1314931972.27
[INFO] [WallTime: 1314931973.274382] /listener_17657_1314931968795I heard hello world 1314931973.27
[INFO] [WallTime: 1314931974.277694] /listener_17657_1314931968795I heard hello world 1314931974.28
[INFO] [WallTime: 1314931975.283708] /listener_17657_1314931968795I heard hello world 1314931975.28

 

 

 

<think>嗯,用户想了解如何用Python编写ROS消息发布节点主题订阅节点。首先,我需要回忆一下ROS的基本概念结构。ROS中的节点是独立的可执行进程,通过发布订阅主题进行通信。发布者节点将消息发送到主题,而订阅节点则监听这些主题以接收消息。 接下来,我应该分步骤来指导用户如何创建这两个节点。首先,需要确保他们有一个ROS的工作空间,并且已经创建了功能包。用户可能需要安装必要的依赖,比如`rospy`,这是ROSPython客户端库。然后,编写发布者节点的代码,初始化节点,创建发布者对象,并循环发布消息。同时,订阅节点需要初始化节点,创建订阅者,并定义回调函数来处理接收到的消息。 用户可能对如何编译运行这些节点不太清楚,所以需要详细说明使用`catkin_make`来构建工作空间,以及如何运行`roscore`、发布者订阅节点。此外,可能还需要提醒他们设置执行权限,使用`chmod +x`命令。 另外,用户可能遇到的问题包括节点无法通信、主题名称不匹配或消息类型不一致。需要指出这些常见错误,并给出检查建议。例如,使用`rostopic list`来确认主题是否存在,或者用`rosmsg show`检查消息类型是否正确。 最后,生成相关问题可以帮助用户进一步深入学习,比如如何自定义消息类型或处理多个订阅者的情况。同时,确保引用格式正确,按照用户的要求在引用部分添加标识符,但看起来用户提供的引用可能与当前问题关联不大,可能需要确认或调整引用内容的相关性。</think>### Python实现ROS发布者与订阅节点 #### 一、环境准备 1. 创建ROS工作空间功能包 ```bash mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src catkin_create_pkg my_pkg rospy std_msgs ``` 2. 安装Python依赖 ```bash sudo apt-get install python-rospy ``` #### 二、发布者节点实现 创建`publisher.py`文件: ```python #!/usr/bin/env python import rospy from std_msgs.msg import String def publisher(): pub = rospy.Publisher('chat_topic', String, queue_size=10) rospy.init_node('talker', anonymous=True) rate = rospy.Rate(1) # 1Hz while not rospy.is_shutdown(): msg_str = "Hello at %s" % rospy.get_time() pub.publish(msg_str) rate.sleep() if __name__ == '__main__': try: publisher() except rospy.ROSInterruptException: pass ``` #### 三、订阅节点实现 创建`subscriber.py`文件: ```python #!/usr/bin/env python import rospy from std_msgs.msg import String def callback(data): rospy.loginfo(rospy.get_caller_id() + " Received: %s", data.data) def subscriber(): rospy.init_node('listener', anonymous=True) rospy.Subscriber('chat_topic', String, callback) rospy.spin() if __name__ == '__main__': subscriber() ``` #### 四、编译与运行 1. 设置执行权限 ```bash chmod +x publisher.py subscriber.py ``` 2. 构建工作空间 ```bash cd ~/catkin_ws catkin_make source devel/setup.bash ``` 3. 启动节点(三个独立终端) ```bash # 终端1 roscore # 终端2 rosrun my_pkg publisher.py # 终端3 rosrun my_pkg subscriber.py ``` #### 五、关键参数说明 1. `queue_size`:消息队列长度,防止高频消息丢失 2. `anonymous=True`:允许同名节点共存 3. `rospy.spin()`:保持节点持续监听 [^1]: 消息序列化采用ROS内置的序列化机制 [^2]: 节点发现机制基于ROS Master实现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值