ROS2入门:为机器人搭建通信骨架

从零开始理解ROS2架构,掌握Node、Topic、Service核心概念,用Python快速搭建你的第一个机器人控制程序。

ROS2 机器人 Python 自动驾驶
ROS2入门:为机器人搭建通信骨架

ROS2入门:为机器人搭建通信骨架

ROS(Robot Operating System)是机器人开发领域的事实标准框架。ROS2作为其下一代版本,解决了ROS1在实时性、安全性和多机协同方面的诸多痛点。如果你正在用DonkeyCar、JetBot或其他平台做机器人项目,ROS2能帮你把传感器、执行器、算法模块有机地组织起来。

ROS2的核心架构

ROS2采用分布式通信架构,核心概念包括:

  • Node(节点):每个功能模块是一个独立进程,比如激光雷达驱动是一个Node,路径规划是另一个Node。
  • Topic(话题):Node之间通过Topic进行异步消息传递,发布/订阅模式。
  • Service(服务):同步的请求/响应通信,适合需要确认的操作。
  • Action(动作):带反馈的长时间任务,比如”导航到目标点”。

安装ROS2

以Ubuntu 22.04 + ROS2 Humble为例:

# 添加ROS2软件源
sudo apt update && sudo apt install -y software-properties-common
sudo add-apt-repository universe
sudo apt update && sudo apt install curl -y
sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key \
  -o /usr/share/keyrings/ros-archive-keyring.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] \
  http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | \
  sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null

# 安装桌面完整版
sudo apt update
sudo apt install ros-humble-desktop -y

# 配置环境
echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc
source ~/.bashrc

第一个Python节点

创建一个工作空间并编写你的第一个Node:

mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
ros2 pkg create --build-type ament_python my_robot_pkg

编写一个简单的Publisher节点:

# my_robot_pkg/my_robot_pkg/steering_node.py
import rclpy
from rclpy.node import Node
from std_msgs.msg import Float32

class SteeringNode(Node):
    def __init__(self):
        super().__init__('steering_controller')
        self.publisher_ = self.create_publisher(Float32, '/steering_angle', 10)
        self.timer = self.create_timer(0.1, self.timer_callback)
        self.angle = 0.0
        self.direction = 1

    def timer_callback(self):
        self.angle += 0.5 * self.direction
        if abs(self.angle) > 30.0:
            self.direction *= -1
        msg = Float32()
        msg.data = self.angle
        self.publisher_.publish(msg)
        self.get_logger().info(f'发布转向角: {self.angle:.1f}°')

def main(args=None):
    rclpy.init(args=args)
    node = SteeringNode()
    rclpy.spin(node)
    node.destroy_node()
    rclpy.shutdown()

if __name__ == '__main__':
    main()

对应的Subscriber节点,接收转向角并控制舵机:

# my_robot_pkg/my_robot_pkg/servo_driver.py
import rclpy
from rclpy.node import Node
from std_msgs.msg import Float32

class ServoDriver(Node):
    def __init__(self):
        super().__init__('servo_driver')
        self.subscription = self.create_subscription(
            Float32, '/steering_angle', self.angle_callback, 10)

    def angle_callback(self, msg):
        # 将角度映射到PWM脉宽 (2.5ms~3.5ms 对应 0°~180°)
        pwm = 2500 + int(msg.data / 180.0 * 1000)
        self.get_logger().info(f'设置PWM: {pwm}μs (角度: {msg.data:.1f}°)')
        # 这里调用实际的GPIO或PCA9685驱动

def main(args=None):
    rclpy.init(args=args)
    node = ServoDriver()
    rclpy.spin(node)
    node.destroy_node()
    rclpy.shutdown()

if __name__ == '__main__':
    main()

用Launch文件启动多个节点

实际项目中你不可能一个个启动节点,用Launch文件统一管理:

# my_robot_pkg/launch/robot.launch.py
from launch import LaunchDescription
from launch_ros.actions import Node

def generate_launch_description():
    return LaunchDescription([
        Node(
            package='my_robot_pkg',
            executable='steering_node',
            name='steering',
            output='screen'
        ),
        Node(
            package='my_robot_pkg',
            executable='servo_driver',
            name='servo',
            output='screen'
        ),
    ])

运行:ros2 launch my_robot_pkg robot.launch.py

ROS2与DonkeyCar/JetBot的集成思路

在模型车项目中,典型的ROS2节点划分:

节点功能发布/订阅
camera_driver摄像头采集发布 /image_raw
lidar_driver激光雷达发布 /scan
lane_detector车道线检测订阅 /image_raw,发布 /lane_cmd
motor_driver电机控制订阅 /cmd_vel

ros2 topic list查看所有活跃话题,ros2 topic echo /cmd_vel实时观察消息内容,调试效率比直接print高一个量级。

实用调试命令

# 查看节点列表
ros2 node list

# 查看某个节点的话题和服务
ros2 node info /steering_controller

# 查看话题的消息类型和发布频率
ros2 topic hz /steering_angle

# 查看服务列表
ros2 service list

# 参数动态调整
ros2 param set /steering_controller max_angle 45.0

下一步

掌握基础通信后,建议依次学习:

  1. TF2坐标变换——理解机器人各部件的空间关系
  2. URDF模型描述——为你的模型车建立3D模型
  3. Nav2导航栈——直接获得SLAM + 路径规划能力
  4. ros2_control——统一的硬件抽象层

ROS2的学习曲线比ROS1平缓不少,Python生态的支持也更加完善。对于模型车爱好者来说,它是连接底层硬件和上层算法的最佳桥梁。