
2. Part 2该装哪个版本ROS发行版选型与升级避坑上一篇聊完ROS的基础概念很多朋友最关心的其实是一件事我到底该装哪个版本这个问题我在不同群里被问了不下几十遍尤其是Ubuntu 22.04发布之后问得更密集了。今天先把这个问题讲透。2.1 一张表看清ROS发行版和Ubuntu的对应关系ROS的发行版和Ubuntu版本是强绑定的选错Ubuntu版本就意味着你可能要重装系统这个坑希望大家一步都不要踩。目前主流的对应关系如下Ubuntu版本对应ROS发行版支持状态建议Ubuntu 20.04NoeticROS 1维护至2025年学习ROS 1首选Ubuntu 22.04HumbleROS 2长期维护ROS 2生产环境首选Ubuntu 22.04FoxyROS 2已停止维护不建议新项目使用Ubuntu 24.04JazzyROS 2长期维护新硬件可尝试如果你用的是Ubuntu 22.04别犹豫直接装ROS 2 Humble。为什么因为Humble是LTS版本支持周期长社区资源多很多新出的硬件驱动和功能包都会优先适配它。至于ROS 1的Noetic虽然经典但ROS 1已经停止大版本更新新项目不建议再入坑了。注意如果你的工作流依赖ROS 1的老包比如某些只有ROS 1版本的工业相机驱动那么建议停留在Ubuntu 20.04 Noetic不要盲目升级系统。我见过好几次因为升级Ubuntu导致整条产线驱动全废的案例。2.2 官方安装和鱼香ROS一键安装到底怎么选装ROS对新手来说确实麻烦需要配置软件源、添加密钥、安装一大堆依赖包每一步都可能出错。所以现在很多人推荐用鱼香ROS一键安装这个工具它确实把安装过程压缩到了一行命令。这个工具的本质就是帮你自动完成以下操作配置国内镜像源、安装必要依赖、拉取ROS核心包、初始化环境变量。如果你在国内网络环境下用这个工具确实能省不少时间。但我的建议是无论用什么工具装你都必须理解背后的安装逻辑至少要知道ROS装到了哪个目录、环境变量在哪里配置的。我个人的习惯是第一次装用官方教程手动走一遍流程把每一步在干什么都搞清楚。后续如果需要在多台设备上快速部署再用一键脚本提升效率。这样既保证了理解深度又不浪费重复劳动的时间。如果你已经被依赖关系折磨得想砸电脑用一键安装完全没问题但装完后花半小时把官方安装文档读一遍这个时间花得值。2.3 Gazebo仿真环境与ROS的搭配思路Gazebo是我们做仿真最常用的工具之一热搜词里gazebo安装ros环境ubuntu22说明大家在这块也踩了不少坑。Gazebo和ROS是两个独立项目Gazebo负责物理仿真ROS负责通信和控制两者通过gazebo_ros_pkgs这个桥接包通信。在Ubuntu 22.04上如果已经装好了ROS 2 Humble安装Gazebo的ROS接口非常简单sudo apt install ros-humble-gazebo-ros-pkgs这个命令会安装gazebo_ros、gazebo_plugins、gazebo_msgs等核心接口包。安装完成后你可以用一个最简单的空世界测试是否正常ros2 launch gazebo_ros gazebo.launch.py如果顺利你会看到一个空荡荡的仿真世界窗口弹出。如果没弹出来最常见的两个原因一是显卡驱动问题导致OpenGL渲染失败二是环境变量没配好。前者可以尝试安装mesa-utils并检查glxinfo输出后者检查~/.bashrc里是否source了ROS的setup脚本。Gazebo跑起来之后你就可以往里面添加机器人模型、传感器、障碍物开始做真正意义上的仿真验证。这块内容下面专门用一节详细讲。3. 话题通信的进阶玩法可视化、录制与回放ROS里的话题Topic是整个系统的心脏所有传感器数据、控制指令都是通过话题传递的。Part 1里应该已经讲过话题是什么这里我重点讲三个实操中离不开的能力用Python对话题数据画图、用rosbag录制和回放数据、以及话题通信时容易踩的坑。3.1 用Python订阅话题并实时绘图在做机器人调试时最直观的需求就是看看传感器的数据长什么样。比如你接了一个IMU想看角速度曲线接了一个激光雷达想看扫描数据。ROS自带了一些可视化工具但有时候你希望更灵活地处理数据这时候Python就是最好的帮手。这里给一个实用的例子订阅ROS 2里的/scan话题激光雷达数据用matplotlib实时绘制距离曲线。import rclpy from rclpy.node import Node from sensor_msgs.msg import LaserScan import matplotlib.pyplot as plt import numpy as np from collections import deque class ScanPlotter(Node): def __init__(self): super().__init__(scan_plotter) self.subscription self.create_subscription( LaserScan, /scan, self.scan_callback, 10) self.subscription # 用队列保存最近100帧数据方便绘制趋势 self.ranges_history deque(maxlen100) plt.ion() self.fig, self.ax plt.subplots() self.line, self.ax.plot([], []) self.ax.set_xlabel(Scan Index) self.ax.set_ylabel(Distance (m)) self.ax.set_title(LaserScan Real-time Plot) self.ax.set_ylim(0, 10) def scan_callback(self, msg): ranges np.array(msg.ranges) ranges[~np.isfinite(ranges)] 0 # 把inf和nan替换为0 self.ranges_history.append(ranges) if len(self.ranges_history) 0: latest self.ranges_history[-1] self.line.set_data(np.arange(len(latest)), latest) self.ax.relim() self.ax.autoscale_view(scalexFalse, scaleyTrue) self.fig.canvas.draw() self.fig.canvas.flush_events() def main(argsNone): rclpy.init(argsargs) node ScanPlotter() try: rclpy.spin(node) except KeyboardInterrupt: pass finally: node.destroy_node() rclpy.shutdown() plt.ioff() plt.show() if __name__ __main__: main()这段代码有几点值得说明。首先是deque(maxlen100)它能自动丢弃最旧的数据避免内存无限增长。其次是np.isfinite()过滤激光雷达数据里经常会出现inf或nan表示没有测到有效值绘图前必须处理掉否则matplotlib会报警告。运行这个节点的前提是你的/scan话题有数据在发布。如果是在Gazebo仿真里需要在启动机器人模型时把激光雷达传感器加进去并确认发布的话题名是/scan。实操心得很多新手在写订阅回调时忘记在__init__里保存self.subscription导致订阅对象被Python垃圾回收机制回收话题收不到数据。这个问题排查起来非常隐蔽因为代码不会报错。记住create_subscription的返回值一定要赋给self的成员变量。3.2 rosbag录包与回放复现现场的神器调试机器人时最怕什么怕问题随机出现你盯着终端看半天它就是不犯病。这时候rosbag就是你的时间机器。它能把指定话题的数据完整录制下来之后在任何时间回放还原现场。ROS 2里录包的命令是ros2 bag record /scan /odom /cmd_vel这条命令启动后/scan、/odom、/cmd_vel这三个话题的所有消息都会被记录到当前目录下一个以时间戳命名的bag文件夹里。录制你想录的时长后按CtrlC结束录制。回放的命令是ros2 bag play bag_directory_name回放时有一个非常实用的参数-r可以控制回放速率。比如你录了10分钟的数据想快速浏览整个过程可以用-r 5让回放速度变成5倍速。反之如果你在调试算法需要慢慢分析可以用-r 0.5放慢速度。还有一个细节ros2 bag info可以查看bag文件里记录了哪些话题、多少帧数据、起始和结束时间。这在确认录制内容时非常方便。ros2 bag info my_bag_folder输出内容类似这样Files: my_bag_folder_0.db3 Bag size: 48.2 MiB Storage id: sqlite3 Duration: 62.3s Start: Nov 18 2024 15:30:22.123 End: Nov 18 2024 15:31:24.456 Messages: 12456 Topic information: Topic: /cmd_vel | Type: geometry_msgs/msg/Twist | Count: 623 | Serialization Format: cdr Topic: /odom | Type: nav_msgs/msg/Odometry | Count: 6230 | Serialization Format: cdr Topic: /scan | Type: sensor_msgs/msg/LaserScan | Count: 5603 | Serialization Format: cdr这组信息非常有用。比如你发现/odom的Count比/scan多说明里程计发布频率比激光雷达高这完全正常。但如果某个话题Count是0说明录制时这个话题根本没数据可能是发布方没启动或者话题名写错了。3.3 话题通信几个容易踩的坑话题通信看着简单实际使用中问题不少。根据我的经验最常遇到的是这三类第一类话题名不匹配。发布方发的是/laser_scan订阅方听的是/scan数据当然过不来。这个问题用ros2 topic list就能排查列出当前所有话题一眼就能看出命名差异。第二类消息类型不一致。有些人用ros2 topic list看到话题存在但订阅时还是报错大概率是消息类型对不上。用ros2 topic info /topic_name可以查看这个话题的消息类型对比一下就能定位问题。第三类通信质量问题。ROS 2的QoS策略和ROS 1完全不同默认情况下发布方和订阅方的QoS如果不匹配会导致订阅不到数据。最典型的场景是发布方用SensorDataQoS适合传感器数据允许丢包订阅方用默认的Reliable QoS结果订阅方收不到任何消息。解决办法是在创建订阅时指定兼容的QoSfrom rclpy.qos import qos_profile_sensor_data self.subscription self.create_subscription( LaserScan, /scan, self.callback, qos_profile_sensor_data)这里qos_profile_sensor_data就是专门为传感器数据设计的QoS配置它允许一定程度的丢包但保证低延迟适合高频传感器数据。反之如果你传输的是控制指令这种低频但关键的数据就要用Reliable QoS确保每条消息都不丢。4. 实战ROS小车自主导航仿真全流程拆解热搜词里ros小车自主导航仿真关注度很高。确实当你能让一个小车在仿真环境里自己跑到目标点那种成就感是很大的。这个流程把前面的知识点全部串起来了话题通信、传感器数据、机器人模型、导航算法。4.1 导航仿真需要哪些核心组件一套完整的ROS导航仿真至少需要以下组件机器人模型描述机器人的外形、质量、惯性、传感器位置通常用URDF或SDF格式传感器仿真激光雷达或深度相机用于感知环境里程计数据源仿真环境中通常由Gazebo的差速控制器插件发布地图服务利用SLAM算法建图或直接加载一张已知地图导航算法栈包括全局路径规划Global Planner和局部路径规划Local Planner可视化工具RViz用于查看地图、路径和机器人状态我建议你在动手之前先把这个整体架构画在纸上。机器人通过激光雷达扫描周围环境发布/scan话题导航栈订阅/scan和/odom计算出速度指令发布到/cmd_velGazebo接收/cmd_vel通过物理引擎驱动模型移动再更新里程计。这个闭环理解了整个导航系统的框架就清晰了。4.2 从零搭建一个TurtleBot3仿真环境TurtleBot3是ROS社区最经典的教学机器人平台它的仿真包非常完善是学习导航的最佳切入点。在Ubuntu 22.04 ROS 2 Humble环境下搭建步骤如下# 安装TurtleBot3相关功能包 sudo apt install ros-humble-turtlebot3-gazebo ros-humble-turtlebot3-cartographer ros-humble-turtlebot3-navigation # 设置机器人型号 echo export TURTLEBOT3_MODELburger ~/.bashrc source ~/.bashrc然后启动Gazebo仿真世界ros2 launch turtlebot3_gazebo turtlebot3_world.launch.py这个命令会启动一个带有障碍物的室内仿真环境TurtleBot3出现在地图中央激光雷达开始实时扫描。再开一个终端启动导航功能ros2 launch turtlebot3_navigation2 navigation2.launch.py map:/path/to/map.yaml注意这里需要指定地图文件路径。TurtleBot3包自带了一个示例地图路径一般在/opt/ros/humble/share/turtlebot3_navigation2/maps/下你可以用它先跑通流程。最后启动RViz可视化ros2 run rviz2 rviz2 -d /opt/ros/humble/share/turtlebot3_navigation2/rviz/navigation2.rviz如果一切正常RViz窗口里会看到激光扫描点云、机器人模型和地图。用RViz上方工具栏的2D Goal Pose按钮在地图上点一个目标点并拖出方向小车就会开始规划路径并向目标移动。4.3 导航参数调整心得很多人在这一步碰壁小车规划不出路径或者走到一半停下来、原地转圈。问题多半出在参数上。第一个要检查的是代价地图的膨胀半径inflation_radius。这个参数决定了机器人距离障碍物多远开始减速避让。如果设置得太小机器人会离障碍物非常近容易碰撞如果设置得太大窄通道可能直接被标记为不可通行导致规划失败。TurtleBot3 burger的尺寸较小膨胀半径通常设置在0.1到0.2米之间比较合适。第二个要检查的是机器人速度限制参数。如果你只在键盘控制时给过速度指令可能没意识到导航栈里还有独立的线速度和角速度上限。在nav2_params.yaml文件里找到robot_max_velocity相关配置把max_translation_vel和max_rotation_vel调整到合理范围。设置得太小机器人行动缓慢像蜗牛设置得太大在狭窄空间里容易失控。第三个很多人忽略的是frame_id的匹配。导航栈要求/odom话题的header.frame_id必须设为odom/scan的header.frame_id通常是base_scan或laser这些名称要和URDF模型里定义的坐标系完全一致否则TF树关系错乱导航直接罢工。检查TF树是否正确的命令是ros2 run tf2_ros tf2_echo map odom如果能看到持续的坐标变换输出说明map到odom的链路是通的。这个是排查导航问题第一步要做的事。5. 视觉传感器接入海康相机与RealSense的ROS实战传感器接入是机器人项目里最常遇到的硬骨头。很多新手买了一个相机装好驱动后却不知道怎么把数据送进ROS。这里以两个最常见的选择为例工业用的海康相机和消费级深度相机的代表RealSense D435i。5.1 海康相机驱动接入与录制数据海康威视的工业相机在科研和工业项目中使用率很高但它驱动接入ROS确实有一点门槛。海康官方提供的ROS驱动包通常是基于ROS 1的如果你用的是ROS 2需要做一层桥接或者找社区适配版。在ROS 1环境下海康相机的驱动接入流程是安装海康MVS SDK这一步需要在海康官网下载对应Linux版本编译海康ROS驱动包官方叫hikrobot_camera或hik_camera配置相机的IP地址和参数海康工业相机通常走GigE协议需要设置相机的IP和电脑网卡在同一网段启动驱动节点发布/hik_camera/image_raw话题启动后你可以用下面的命令查看图像话题rostopic hz /hik_camera/image_raw如果输出频率稳定在30Hz左右说明相机工作正常。接着可以用roslaunch启动录制把图像数据录成bag包rosbag record /hik_camera/image_raw /hik_camera/camera_info这里我强烈建议把camera_info话题一起录制因为后续做相机标定或三维重建时需要它提供的相机内参。海康相机接入ROS最常遇到的问题有两个一是SDK的权限问题相机节点无法打开设备通常是需要给当前用户授权USB或网卡的访问权限二是图像格式问题海康相机的输出格式可能是Bayer RAW或YUV需要正确设置pixel_format参数才能发布成ROS标准的sensor_msgs/Image消息。5.2 D435i接入ROS并关闭结构光Intel RealSense D435i是深度相机里的明星产品它不仅能输出彩色图像还能输出深度图像。在ROS 2下接入D435i非常方便Intel官方提供了完善的驱动sudo apt install ros-humble-realsense2-camera ros2 launch realsense2_camera rs_launch.py这条命令会启动相机节点默认发布/camera/color/image_raw彩色图、/camera/depth/image_rect_raw深度图、/camera/imuIMU数据等话题。热搜词里d435i ros 关闭结构光是个非常实际的场景。D435i使用的是主动红外结构光技术它会投射不可见的红外点阵来增强深度精度。但在某些场景下比如多个D435i同时工作或者深度相机和光学追踪系统同时运行结构光会相互干扰导致深度数据出现大量空洞。这时候就需要关闭结构光。关闭结构光的方法有几种我推荐在启动时直接配置参数。用launch文件启动时添加参数ros2 launch realsense2_camera rs_launch.py enable_infra1:false enable_infra2:false enable_depth:true红外发射器由enable_ir_emitter参数控制在运行时可以通过dynamic_reconfigure修改。但更彻底的办法是在启动时通过json_file_path加载相机高级配置里面可以显式关闭emitter_enabled。关闭结构光后的影响是深度图质量会下降尤其是在弱纹理环境下。所以如果你不是必须我不建议关闭。如果只是想减少干扰可以尝试把emitter_enabled设为1激光发射器常开或设为2激光发射器关闭但红外照明灯打开这两种模式在纯纹理环境下的深度效果会比完全关闭好很多。5.3 相机标定ROS里最该学会的滤镜热搜词里单独有一个ros标定说明很多人都卡在这一步。相机标定的本质是求解相机内参焦距、主点坐标、畸变系数ROS提供了非常方便的标定工具。sudo apt install ros-humble-camera-calibration ros2 run camera_calibration cameracalibrator --size 8x6 --square 0.108 image:/camera/color/image_raw camera:/camera这里的--size 8x6表示标定板的内部角点数量是8列6行--square 0.108表示每个棋盘格边长为0.108米。操作时手持标定板在相机前缓慢移动让标定板出现在画面的各个位置中心、角落、远近、倾斜使标定界面的X、Y、Size、Skew四个进度条全部变绿然后点击Calibrate。标定完成后ROS会输出相机内参矩阵和畸变系数并给出一个yaml格式的配置文件。这个配置要保存到你的相机驱动包的正确位置这样每次启动相机时驱动都会自动加载内参。实操心得标定时的光照条件很关键。太强的直射光会产生光斑让角点检测失败昏暗环境下棋盘格黑白边界不清晰同样检测不到。我一般在室内均匀光照下做标定窗帘拉一半不开顶灯直照标定板。这样一次成功率最高。6. 进阶玩法机械臂开发与RTK定位的ROS实现思路热搜词里ros机械臂开发和基于ros的rtk定位代表了ROS在机器人和定位领域的两个重要方向。虽然这两个话题都能单独写几篇长文但这里我把核心思路和关键技术路线梳理一下帮大家建立全局认识。6.1 机械臂开发从URDF到MoveItROS机械臂开发的核心是MoveIt运动规划框架。一套完整的机械臂控制流程包括用URDF描述机械臂的几何和运动学参数用MoveIt进行运动规划和碰撞检测用ROS的action通信下发运动指令用真实或仿真的控制器执行轨迹。URDF里最核心的内容是关节Joint定义。机械臂的每个旋转关节都要指定类型revolute、旋转轴位置和方向origin和axis、以及运动范围limit。如果关节定义错误机械臂在仿真里会出现奇怪的扭曲甚至直接散架。MoveIt的配置可以通过moveit_setup_assistant工具生成。你只需要提供URDF文件这个工具就会引导你完成自碰撞矩阵生成、规划组定义、末端执行器定义等步骤。生成配置包后启动仿真关节控制器的命令是ros2 launch your_moveit_config demo.launch.py这会启动一个RViz界面你可以在里面拖拽机械臂末端MoveIt会实时规划出关节轨迹。如果规划失败最常见的两个原因一是目标位姿在机械臂的工作空间之外二是自碰撞矩阵没生成好导致MoveIt认为机械臂自身就处于碰撞状态。6.2 RTK定位与ROS的融合思路基于ros的rtk定位是户外机器人定位的经典方案。RTK实时动态差分定位技术通过基准站和流动站之间的差分改正可以实现厘米级的定位精度。在ROS里使用RTK本质上是把RTK设备当作一个高精度的传感器接入系统。目前市场上主流的RTK设备如千寻、华测、司南等大多支持NMEA协议输出。NMEA数据里包含了经纬度和海拔信息。在ROS里处理这个数据最直接的方式是以nmea_msgs消息类型发布然后通过robot_localization包中的navsat_transform_node把经纬度坐标转换到机器人局部坐标系的odom或map坐标系。这套方案的整体流程是启动RTK串口读取节点将NMEA数据发布为sensor_msgs/NavSatFix消息配置navsat_transform_node输入RTK位置、IMU和里程计信息将融合后的位姿输出到EKF节点得到平滑的机器人位姿估计这里有一个容易被忽视的坑RTK的坐标系是WGS-84地理坐标系而机器人的导航坐标系是东北天ENU或北东地NED的局部坐标系。navsat_transform_node的输出频率通常只有10Hz而里程计和IMU的频率高达100Hz以上需要依靠EKF滤波把这些数据融合起来才能得到平滑且无漂移的位姿。另外要注意RTK不是在任何环境下都能达到厘米级精度。建筑遮挡、树木茂密、天线周围存在金属反射面都会导致多路径效应使定位精度降到分米甚至米级。所以在部署RTK前先检查作业环境的卫星可见性和信号质量这个比我说的任何参数都重要。