3、发布者节点编写:用Python写一个速度发布节点

好,咱们直接进入正题。这一节,我带你手写一个ROS发布者节点。说白了,就是让机器人听你的话,按你给的速度动起来。

我个人习惯,每次写节点前先想清楚三件事:发什么话题?发什么类型?多久发一次? 想清楚了,代码就是填空。

3.1 先搭个骨架

打开终端,进到你的工作空间。我假设你已经建好了 catkin_ws/src 目录。如果没有,先建一个:

mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/src
catkin_create_pkg robot_control std_msgs rospy geometry_msgs

这里我创建了一个叫 robot_control 的包。依赖里加了 geometry_msgs,因为速度消息 Twist 就在这个包里。嗯,这一步容易忘,我刚开始学的时候就漏过,结果编译报错找了半天。

3.2 写发布者节点

在 robot_control/src 目录下新建一个文件,叫 velocity_publisher.py。直接上代码:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import rospy
from geometry_msgs.msg import Twist

def velocity_publisher():
    # 初始化节点,名字叫 'velocity_publisher_node'
    rospy.init_node('velocity_publisher_node', anonymous=True)
    
    # 创建一个发布者,发布到 /cmd_vel 话题,消息类型是 Twist
    pub = rospy.Publisher('/cmd_vel', Twist, queue_size=10)
    
    # 设置发布频率,10Hz
    rate = rospy.Rate(10)
    
    # 创建一个 Twist 消息对象
    vel_msg = Twist()
    
    # 设置线速度(前进速度)和角速度(转向速度)
    vel_msg.linear.x = 0.2   # 前进 0.2 m/s
    vel_msg.angular.z = 0.1  # 转弯 0.1 rad/s
    
    rospy.loginfo("开始发布速度指令:线速度 %.2f m/s,角速度 %.2f rad/s", 
                  vel_msg.linear.x, vel_msg.angular.z)
    
    # 循环发布,直到节点被关闭
    while not rospy.is_shutdown():
        pub.publish(vel_msg)
        rate.sleep()

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

代码不长,我拆开讲几个关键点。

3.3 关键点解析

代码行 作用 我的经验
rospy.init_node(...) 初始化节点,名字唯一 anonymous=True 可以避免重名冲突,调试时很有用
rospy.Publisher(...) 创建发布者,指定话题和消息类型 queue_size=10 是缓冲区大小,太小会丢消息
Twist() 创建速度消息对象 linear.x 是前后,angular.z 是左右转
rospy.Rate(10) 控制循环频率 10Hz 适合大多数移动机器人,太快了电机反应不过来
重要提醒: Twist 消息有6个分量:linear.x/y/z 和 angular.x/y/z。对于两轮差速机器人,通常只用 linear.x 和 angular.z。其他分量设为0即可。

3.4 让节点跑起来

写完后,别忘了给文件执行权限:

chmod +x ~/catkin_ws/src/robot_control/src/velocity_publisher.py

然后编译工作空间:

cd ~/catkin_ws
catkin_make
source devel/setup.bash

启动节点前,先开一个终端运行 roscore:

roscore

再开一个新终端,运行你的发布者节点:

rosrun robot_control velocity_publisher.py

如果一切正常,你会看到终端打印出:

[INFO] [时间戳]: 开始发布速度指令:线速度 0.20 m/s,角速度 0.10 rad/s
小技巧: 用 rostopic echo /cmd_vel 可以实时查看发布的消息内容。我调试时经常开着这个窗口,确认数据对不对。

3.5 核心逻辑流程图

下面这张图,帮你理清整个发布流程:

初始化节点 创建发布者 设置速度值 循环发布消息 机器人移动 循环直到 rospy.is_shutdown()
注意: 如果你在Gazebo仿真中测试,确保机器人模型订阅了 /cmd_vel 话题。我曾经遇到过话题名写错,机器人半天不动,最后发现是少了个斜杠。

3.6 避坑指南

  • 话题名大小写敏感:/cmd_vel 和 /Cmd_Vel 是两个不同的话题,写错了机器人不理你。
  • 记得 source 工作空间:每次新开终端,都要 source devel/setup.bash,否则找不到你的节点。
  • 速度值别太大:我刚开始测试时设了 1.0 m/s,结果机器人直接撞墙。建议从 0.1 开始试。
  • Ctrl+C 停止节点:发布者会一直循环,按 Ctrl+C 才能退出。

好了,到这里你已经学会写一个最简单的速度发布节点了。下一节,我们会让这个节点更智能——根据键盘输入来控制机器人运动。不过那是后话了,先把今天的内容消化掉。

可可精品资料库