返回
机器人基础教程 第八课:机器人操作系统与软件架构


这一课把“机器人软件怎么搭起来、怎么跑起来、怎么和硬件连起来”讲清楚。你可以把它当作:从“会写算法”走向“能做完整机器人系统”的分水岭。

8.1 机器人操作系统(ROS)概述
8.1.1 ROS 是什么?为什么它是现代机器人开发的核心?

ROS(Robot Operating System)更像是机器人软件中间件 + 工具链 + 生态,它解决的不是“某一个算法”,而是“把很多算法、硬件、工程流程拼成一个可用系统”。

ROS 帮你解决这些真实痛点:

模块化协作:感知、定位、规划、控制、UI 各写各的,靠统一通信机制拼起来

复用与生态:SLAM、导航、机械臂规划、相机驱动……大量现成包直接用

工程化工具:录包回放、可视化、调参、日志、仿真、发布部署

跨硬件:同一套上层算法能跑在不同底盘、不同雷达/相机上(只要驱动和话题对上)

补充一个重要现实:ROS 1(Noetic)已在 2025-05-31 达到 EOL,新项目更建议以 ROS 2 为主。

8.1.2 ROS 的结构与组件:节点、话题、消息(再加上你必须知道的 4 个概念)

ROS 2 把系统拆成很多“进程/组件”,每个组件做一件事:

(1) Node 节点
一个节点负责一个清晰功能:例如“读取雷达”“发布里程计”“做 SLAM”“做路径规划”。官方教程也强调节点应当职责单一、模块化。

(2) Topic 话题(发布/订阅)
最常用通信方式:A 节点发布数据到某个 topic,B 节点订阅它。ROS 2 官方把 topic 形容为“节点交换消息的总线”。

(3) Message 消息
topic 里传的数据结构(强类型),例如 sensor_msgs/LaserScan、geometry_msgs/Twist。

(4) Service 服务(请求/响应)
像函数调用:请求一次,返回一次。适合“设置模式、触发一次动作”。

(5) Action 动作(可反馈、可取消的长任务)
例如“导航到目标点”:过程中会反馈进度,也可以取消。

(6) Parameter 参数
节点运行参数:PID 增益、滤波系数、地图分辨率、控制频率等。

再加一个你后面绕不过去的:TF 坐标变换
机器人一切感知与控制都离不开坐标系:map / odom / base_link / camera_link / laser,TF2 用来维护这些变换关系。很多“导航跑不起来”的问题,本质是 TF 错了或时间戳不对。

8.2 ROS 开发环境的搭建
8.2.1 选 ROS 1 还是 ROS 2?选哪个版本?

新项目:优先 ROS 2(生态和维护趋势都在 ROS 2)

ROS 2 的一个常用选择是 Jazzy Jalisco。官方安装文档显示:Jazzy 的 Ubuntu deb 包面向 Ubuntu 24.04 (Noble)。

ROS 1 Noetic:已 EOL(上面已引用),除非维护存量项目否则不建议新上。

8.2.2 在 Ubuntu 上安装与配置(以 ROS 2 Jazzy 为例)

下面给你一个“新手最少踩坑”安装路径(思路:官方 deb + colcon 工作空间):

A. 系统准备

Ubuntu 24.04

保持系统更新、时间同步(机器人分布式通信很怕时间飘)

B. 按官方文档走 deb 安装
官方写明 Jazzy 的 deb 包适配 Ubuntu 24.04。
安装完成后,重点是这两件事:

source 环境(让 shell 认识 ros2 命令、包路径)

建立自己的 colcon workspace

典型工作空间结构:

~/ros2_ws/src:放你自己的包

~/ros2_ws/build / install / log:编译生成

8.2.3 ROS 开发常用工具与模拟器(你会频繁用)

命令行工具(必须熟)

ros2 node list / info

ros2 topic list / echo / hz / bw

ros2 service list / call

ros2 action list / send_goal

ros2 param list / get / set

ros2 bag record / play(录包回放,复现问题神器)

可视化 / 调试

RViz2:看激光点云、地图、TF、路径、代价地图

rqt 系列:rqt_graph 看通信拓扑、rqt_plot 看曲线

仿真

Gazebo:注意“Gazebo Classic 已在 2025-01 EOL”,建议迁移到新 Gazebo(Gazebo Sim)。
这点很关键:很多老教程用 Gazebo 11(Classic),你照着装可能会越走越偏。

8.3 机器人算法与控制模块

这里不只讲“算法名字”,而是讲它们在系统里怎么串起来。

8.3.1 基本运动控制:PID 控制(举 3 个常见例子)

PID 在机器人里无处不在:轮速、角速度、姿态、关节位置、末端力控都能用。

例 1:差速底盘轮速控制

输入:目标轮速 v_ref

测量:编码器反馈 v_meas

输出:电机 PWM / 电流给定

难点:编码器噪声、死区、低速爬行、负载变化

常见工程做法:

速度环 PID + 前馈(加速度前馈能明显改善跟随)

输出限幅、防积分饱和

低速段做摩擦补偿(或者设定最小驱动)

例 2:云台/小机械臂关节位置控制

输入:目标角度

测量:编码器角度

输出:驱动器位置/速度指令
工程上常见是“位置环 + 速度环 + 电流环”(电流环多在驱动器内部)。

例 3:沿墙/循线控制

输入:期望距离/轨迹

测量:侧向雷达距离/视觉偏差

输出:角速度 w
这类 PID 的关键不是公式,而是测量信号滤波与控制频率。

8.3.2 路径规划(把它拆成“全局 + 局部 + 控制”)

以移动机器人为例,一个成熟框架通常分三层:

全局规划:从 A 到 B,在地图上找一条总体可行路径(A*、Dijkstra 等)

局部规划/避障:考虑动态障碍、代价地图、机器人运动学约束(DWB、TEB 思路等)

轨迹跟踪控制:把局部轨迹变成底盘速度指令(Pure Pursuit、MPC、PID 等)

一个非常典型的 ROS 2 组合是:SLAM/定位 + Nav2(导航) + ros2_control(控制)
你可以把它理解为“软件架构模板”。

8.3.3 高级算法:SLAM、视觉识别、物体抓取(讲清楚系统链路)
A. SLAM(同步定位与建图)

SLAM 的输入通常来自:

LiDAR(2D/3D)

里程计(轮编码器)

IMU
输出通常是:

机器人位姿(pose)

地图(栅格/点云)

TF:map -> odom -> base_link

例:仓储 AMR 的常见 SLAM 链

雷达 scan + 里程计 odom + IMU imu
→ SLAM 节点
→ 输出 map 与 pose
→ Nav2 做导航
→ 控制器输出 cmd_vel
→ 底盘驱动执行

踩坑点(非常常见):

里程计时间戳不准、TF 断链

雷达安装角度导致数据畸变

IMU 未做重力方向校准,融合漂移

B. 视觉识别(检测/分割/定位)

视觉链路通常是:
相机驱动 → 图像话题 → 预处理(畸变校正/同步) → 模型推理(检测/分割) → 位姿估计(PnP/深度) → 发布目标位姿

例:产线抓取的“视觉 + 坐标标定”

相机识别出工件在图像坐标中的位置

通过相机标定 + 手眼标定,转换到 base_link 或机械臂基座坐标

MoveIt2 做规划,生成轨迹

执行器执行抓取

C. 物体抓取(MoveIt2 + 控制 + 传感)

抓取不是“规划一次就完事”,实际项目更像:

视觉给粗定位

机械臂接近

力/触觉做最后的对接与插入(比如插接件、装配)

8.4 开发与调试工具
8.4.1 ROS 中调试与测试的“实战套路”

遇到“机器人不动/乱动/偶发问题”,建议按这个顺序排:

第一步:拓扑是否对?

rqt_graph 看节点之间是否连上

有没有发 cmd_vel?有没有订阅它的底盘节点?

第二步:数据是否在跑?频率对不对?

ros2 topic echo 看值是否合理

ros2 topic hz 看频率是否稳定(控制回路很怕抖)

第三步:坐标系是否对?

RViz2 看 TF 树是否完整
典型:map -> odom -> base_link -> laser

第四步:录包复现

ros2 bag record 把关键话题录下来

线下回放定位问题:是感知错、规划错、还是控制错

第五步:QoS 与网络
ROS 2 在不同网络、不同 QoS 下表现差异很大。多机通信时尤其要注意 QoS 不匹配会“看得到话题但收不到数据”。

8.4.2 模拟环境:如何使用 Gazebo 做机器人模拟(你该怎么选)

旧教程常见 Gazebo Classic(Gazebo 11),但它已在 2025 年后进入 EOL 状态,官方也强调迁移到新 Gazebo(Gazebo Sim)。

仿真里你通常会做三件事:

放入机器人模型(URDF/SDF)

接上传感器插件(雷达/相机/IMU)

接上控制接口(差速、四轮、机械臂关节)

强烈建议新手的训练路径

先只仿真底盘:cmd_vel → 机器人移动

再加雷达:能在 RViz2 看到 scan

再跑 SLAM:能出地图

最后上 Nav2:能点目标导航

每一步都能闭环验证,不要一口气全装上。

8.5 机器人硬件与 ROS 的集成
8.5.1 把硬件连上 ROS:常见架构(最清晰的分层)

建议你按“分层”设计,后期维护会轻松很多:

硬件层:电机、驱动器、编码器、IMU、雷达、相机

驱动层(ROS Driver):把硬件数据变成 ROS 消息/话题

中间层:滤波、融合(EKF)、TF、状态机

能力层:SLAM、定位、规划、抓取

应用层:任务逻辑、调度、人机交互、云端

这样做的好处:换硬件时通常只改“驱动层 + 少量参数”。

8.5.2 实际操作:控制机器人运动与任务执行(给你两个可落地例子)
例 1:移动底盘从“能跑”到“能导航”

目标:你在 RViz2 里点一个目标点,机器人自己走过去。

你需要把链路打通:

底盘驱动节点:订阅 cmd_vel,发布 odom

传感器驱动:发布 scan、imu

TF:odom -> base_link(来自里程计),base_link -> laser(静态标定)

融合:用 EKF 融合 odom + imu(让姿态更稳)

SLAM/定位:出 map 与 map->odom

Nav2:接收目标点,输出 cmd_vel

常见问题与快速定位:

不动:先看 cmd_vel 是否有、底盘是否订阅到

原地打转:TF 方向错(雷达/底盘坐标轴反了非常常见)

地图漂:里程计/IMU 时间戳、参数、安装角度问题

例 2:机械臂执行“识别-抓取-放置”

目标:相机识别工件,机械臂抓起来放到指定区域。

链路如下:

相机驱动发布图像

视觉节点输出目标位姿(在相机坐标系)

标定节点提供 camera -> base 的变换

MoveIt2 规划:从当前姿态到抓取姿态,再到放置姿态

控制执行:ros2_control 下发关节轨迹到驱动器

夹爪控制:service/action 控制开合

可选:力矩传感器做接触检测(插装/压装更可靠)

如果你希望“更像能直接上手的课”,我也可以把这一课补成一个“完整小项目模板”版本:

目录结构(src 放哪些包)

每个包负责什么

关键话题/TF/参数清单

最小可运行 demo(先仿真、再真机)
下载资料前请先绑定手机号码