从连接小车到系统化排错:ROS 2 机器人的第一套方法
从远程连接、日志分级到 ROS 2 节点与话题状态检查,建立一套可复用的机器人系统排错方法。
1. 记录目的
这不是一份单纯的命令清单,而是我开始接触 ROS 机器人系统后的第一阶段学习记录。
这一阶段的主要目标有三个:
- 学会稳定连接和管理小车上的主机。
- 学会从后台日志和运行状态中判断问题,而不是只看界面现象。
- 建立“先确认事实,再判断影响,最后决定是否修复”的排错习惯。
小车采用 Yahboom ROSMASTER-M3Pro 平台,系统运行 Ubuntu22.04、ROS 2 Humble,并连接相机、雷达、底盘和手柄等设备。
博主目前采用的方法是让小车和电脑在同一局域网下进行开发,测试和调整,主要使用的工具是 finalshell 和 win 自带的桌面连接工具(win+r,输入 mstsc 进行连接),这里博主不采用 VNC 的目的呢,一方面是 VNC 的效果存在较高延迟,其二呢命令的输入无法直接从 win 直接 ctrl c/v 到 Linux 系统里面,需要手打启动对应程序,效率太慢。
2. 最初的认识:小车不是一个单独程序
刚开始时,我更容易把小车理解成一个可以直接输入命令的整体。但实际运行后发现,它是由多个层次组成的系统:
硬件设备
-> Linux 驱动和设备节点
-> ROS 2 话题、节点和服务
-> 厂商功能程序
-> 启动脚本和用户操作
例如,相机画面没有出现,不一定只是“相机程序没有启动”,还可能是设备被其他程序占用(特别是 "xx agent")、ROS 话题没有出帧、图像格式不匹配,或者显示程序没有连接到正确的话题(报 error)。
同样,车辆无法运动,也不能简单判断为“底盘坏了”。还需要检查手柄状态、ROS 节点是否存在、安全节点是否拦截(安全节点拦截的情况下是不会给提示,而是直接断连的,这时候可以让 AI 去后台抓日志查看报错类型和进程)。
这让我第一次意识到:机器人排错必须沿着数据链路逐层确认,在完全确认前,不要反复重启 finalshell 命令终端,防止在程序未正常关闭前被直接 "×" 掉导致 cpu 负载过高。
3. 连接 Jetson:从远程登录开始
最先掌握的是通过 SSH 或 FinalShell 连接 Jetson。连接时需要确认:
- 小车已经上电;
- 电脑和小车处于同一网络;
- 使用当前有效
IP地址(去Internet Connect去查看); - 用户名和认证信息正确,非必要不
root; - SSH 服务确实在监听;
- 网络变化后及时重新确认地址。
在实际使用中,小车 IP 会因为更换热点或网络环境变化而改变。因此,连接失败不能直接归结为密码错误,应按顺序检查网络连通性、端口状态和认证过程。
连接成功后,第一件事不是立即启动功能,而是确认系统基本信息,包括:
- Ubuntu 版本;
ROS发行版;ROS_DOMAIN_ID;- 当前运行的关键节点;
- 相机和雷达话题是否存在。
4. 第一次查看日志:区分现象和原因
查看后台日志后,我发现日志中同时存在不同等级的信息。后来逐渐形成了以下分类方法:
Warning
Warning 表示系统发现了值得注意的异常,但不一定已经影响核心功能。它需要记录和观察,不能和 Error 简单等同。
Error
Error 表示某个功能、节点或数据链路已经出现明确故障。需要进一步确认它是否会导致功能不可用、数据错误或安全风险。
内核硬件错误
内核硬件错误可能与驱动、供电、设备通信或硬件本身有关。它的影响范围需要结合重复次数、关联设备和实际功能表现判断。
这次排查中,我选择暂不处理暂时没有影响当前任务的 Warning 和内核硬件错误,优先关注会直接阻止目标功能运行的 Error。这是一次重要的取舍:修复工作应该按照风险和任务影响排序,而不是看到所有红色日志就同时修改。
5. 从日志走向 ROS 状态检查
只看日志仍然不够,因为日志说明的是程序“报告了什么”,而 ROS 状态可以说明系统“现在实际处于什么状态”。
排查一个功能时,逐渐采用下面的顺序:
确认节点是否存在
-> 确认话题是否存在
-> 确认话题是否持续发布
-> 确认消息内容是否有效
-> 确认上下游节点是否连接
-> 确认最终输出是否被安全层或其他节点拦截
以底盘运动为例,不能只看启动脚本是否执行成功,还要确认:
/cmd_vel是否有发布者;- 发布的线速度和角速度是否为零或未达到移动阈值;
- 手柄是否处于接管状态;
- 安全看门狗是否允许转发←转向拦截时多半和安全协议有关;
- 雷达、相机和控制状态是否正常。
以相机为例,需要确认的不只是窗口,而是相机话题是否持续有图像帧,以及图像分辨率、编码和时间戳是否符合节点要求。
6. 这阶段遇到的典型误区
误区一:命令没有报错,就认为功能正常
启动命令成功只代表进程可能被拉起,不代表设备出帧、话题连通或底盘能够执行动作。也有可能是代码未补全导致在启动失败时也会输出 Successfully。当代码出现问题的时候记得及时 review,特别是 AI 给你写的开机自启动代码,一定要亲自多 review 几次,有条件的话去单开一个服务器做测试环境进行仿真,防止损坏仪器。
误区二:看到 Error 就马上修改源码
错误可能来自配置不匹配、设备暂时未就绪、话题名称错误、节点重复启动或安全逻辑主动阻止。先确认根因,能够避免把厂商源码改坏,在使用 AI 改动之前,尽量提前做好 git 备份或可回滚操作。
误区三:忽略网络环境变化
换热点后 IP 地址变化,会导致 FinalShell、SSH 和 ROS 跨主机通信同时失败。此时应先恢复网络和连接,再判断应用层问题。
误区四:只验证“能启动”,不验证“能退出”
机器人功能必须同时验证启动、暂停、失线、手柄接管、异常退出和系统关机。尤其是底盘控制,退出时残留非零速度比启动失败更危险,特别是要防止循环的操作,如果一直有命令输出而主机未响应,请及时注意 CPU 的占比情况。
7. 形成的排错模板
以后遇到类似问题,可以使用以下模板:
### 问题名称
#### 现象
用户看到了什么,功能表现是什么。
#### 运行状态
节点、话题、传感器和控制输出分别是什么状态。
#### 日志证据
记录关键 Error、Warning、时间和涉及的节点。
#### 根因判断
区分已确认事实、合理推测和仍未知的部分。
#### 影响评估
说明是否影响功能、数据准确性或人身设备安全。
#### 处理决定
说明为什么修复、暂缓修复或继续观察。
#### 验证结果
记录修复后进行的测试和实际结果。
8. 第一阶段的学习收获
这一阶段最重要的收获,不是记住了某一条 SSH 命令,而是建立了系统化的思考顺序:
- 先确认设备、网络和运行环境。
- 再确认节点、话题和消息数据。
- 根据日志和状态信息定位故障层级。
- 按功能影响和安全风险排序处理问题。
- 修改后进行可重复验证,并检查退出路径。
这套方法后来直接影响了地砖缝(标记)巡线功能的设计:巡线节点必须默认停车,标定无效时禁止运动,雷达或手柄异常时立即停止,退出时持续发布零速度。
9. 阶段结论
通过最初的连接、日志和状态排查,我开始把小车看作一个由硬件、操作系统、ROS 2、厂商程序和安全控制共同组成的系统。
后续学习不再只是“输入什么命令可以让小车动起来”,而是进一步追问:
- 它为什么能动;
- 它依据什么数据做判断;
- 哪个节点真正发布了控制命令;
- 异常时谁负责停车;
- 修改后如何证明没有破坏原有功能。
这标志着学习重点从设备使用,开始转向机器人 agent 系统的 subagent 原理理解阶段。
