ROS2入门:为机器人搭建通信骨架
从零开始理解ROS2架构,掌握Node、Topic、Service核心概念,用Python快速搭建你的第一个机器人控制程序。
ROS2 机器人 Python 自动驾驶
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
下一步
掌握基础通信后,建议依次学习:
- TF2坐标变换——理解机器人各部件的空间关系
- URDF模型描述——为你的模型车建立3D模型
- Nav2导航栈——直接获得SLAM + 路径规划能力
- ros2_control——统一的硬件抽象层
ROS2的学习曲线比ROS1平缓不少,Python生态的支持也更加完善。对于模型车爱好者来说,它是连接底层硬件和上层算法的最佳桥梁。