我最近把一个叫 TerraBot 的 AI 精度巡检机器人项目,从一张概念图做成了能在地面上稳定跑起来的原型机。做完之后最大的感受是:这类项目真正的难点,并不在于某一个算法有多深,而在于把硬件选型、AI 感知、自主导航、远程通信这些环节串成一条能闭环的链路。这篇文章就把我从零搭建 TerraBot 的完整过程、踩过的坑和最终的调参心得整理出来,给想自己做巡检机器人或者 AI 机器人底子的朋友一个可以直接抄作业的参考。
TerraBot 这个名字拆开看就是 Terra(大地)+ Bot(机器人),定位很明确:一台能在园区、农田、仓库这类地面环境里自主移动,并用 AI 视觉做精度巡检的小型轮式机器人。它解决的典型问题包括:设备表计读数识别、地面异常目标检测、固定路线定时巡查、巡检数据自动归档。适合三类人来参考:一是想入门 ROS2 与机器人实机开发的嵌入式工程师,二是做 AI 视觉落地但缺少移动平台的同学,三是需要在真实场景做巡检方案验证的产品经理或创业团队。
1. TerraBot项目定位与设计思路拆解
1.1 这个项目解决的核心问题
传统固定摄像头巡检存在两个天然缺陷:视角固定,只能看到设备正面;位置固定,无法贴近检测细小缺陷。TerraBot 的出发点就是把摄像头装到能移动的底盘上,让视觉检测点位可以动态调整。但移动本身会引入新的麻烦:定位漂移、颠簸模糊、光照变化、路径规划失败,这些都会直接拉低 AI 识别的准确率。
所以 TerraBot 的核心设计目标不是"能远程看画面",而是"在自主移动过程中,依然能稳定完成精度检测任务"。这就意味着三个子系统必须同时达标:底盘控制要稳,导航定位要准,AI 识别要快且可靠。我在项目规划时给每个子系统都设了硬性指标,底盘速度误差控制在 5% 以内,导航重定位精度在 10 厘米以内,单帧 AI 推理耗时不超过 80 毫秒。这些指标决定了后面的几乎所有选型和调参方向。
1.2 为什么选择"AI精度巡检"这个方向
我最早其实想做一个通用的开源机器人平台,但很快就发现"通用"意味着每个方向都要投入大量精力,对一个个人项目来说根本撑不住。后来换了个思路,把场景收窄到"精度巡检",整个项目的边界立刻清晰了:不需要机械臂,不需要语音交互,不需要复杂的人机协同,核心就三件事——走得到、看得清、认得准。
精度巡检这个方向还有一个好处:需求非常高频且付费意愿强。变电站的指针表读数、工厂车间的跑冒滴漏检测、仓储区域的货物盘点,甚至农田里的病虫害巡查,本质都是"移动+视觉判断"。把 TerraBot 做成这个方向的专用平台,无论是自己用还是后续产品化,都有明确的落地价值。另外,巡检任务的流程相对固定,容易用状态机或行为树来管理,这给软件架构设计省了很大麻烦。
1.3 整体技术架构一览
TerraBot 的技术栈分四层:底层是 ROS2 Humble 作为机器人中间件,负责传感器数据采集、TF 坐标变换和话题通信;第二层是导航模块,基于 Nav2 完成建图与路径规划;第三层是 AI 感知模块,用 YOLOv8 做目标检测,配合 OpenVINO 做推理加速;最上层是应用层,包括巡检任务调度和远程 Web 监控。四个模块通过 ROS2 话题和 Action 通信,互相解耦。
这个架构最大的好处是替换成本低。AI 模型想换,只需要改感知节点的输入输出,不动导航;底盘想从两轮差速换成四轮独立驱动,只需要保证发布同样的 /cmd_vel 话题,导航层完全不用改。我实际开发过程中,至少有三次因为模块解耦做得彻底,才避免了推倒重来的局面。
2. 硬件选型与机械结构搭建
2.1 底盘方案:驱动方式的选型逻辑
TerraBot 用的是四轮独立驱动滑移转向底盘,每个轮子配一个 12V 直流减速电机加编码器。之所以不选常见的两轮差速加万向轮,是因为巡检场景经常要原地掉头,两轮差速在草地上打滑严重,而四轮滑移转向的抓地力和原地旋转能力明显更好。代价是转向时轮胎磨损大,且对电机一致性要求高,这几个点后面都会遇到对应的坑。
电机选的是 30:1 减速比的空心杯电机,单轮最大扭矩约 2.5N·m,满载 8kg 的 TerraBot 在平整路面上最高速度能到 1.2m/s。控制板用的是一块 STM32F407,跑自定义的 PID 速度环,通过串口与主控的 Jetson Orin Nano 通信。这里要重点提醒:务必选带 AB 相编码器的电机,不要用只带霍尔传感器的,AB 相才能同时得到速度和方向信息,闭环控制才有依据。
2.2 传感器组合与坐标系标定
传感器的配置我反复调整过三轮,最终留下三样:主激光雷达、深度相机、九轴 IMU。主雷达是单线 360 度 2D 激光,量程 12 米,扫描频率 10Hz,负责建图和导航避障。深度相机放在机器人正前方,略向下倾斜 15 度,这样近处地面和表计设备都能进入视野。IMU 单独安装尽量靠近机器人几何中心的位置,减小旋转半径带来的加速度计误差。
传感器装好之后,坐标系的标定是第一个大坑。激光雷达必须与底盘中心对齐,深度相机的外参需要标定出相对底盘坐标系的旋转和平移矩阵。我用的方法是 ROS2 里的robot_calibration工具包,配合一个 6x6 的 AprilTag 标定板,采集 50 组数据后自动求解外参。没做严格标定之前,导航地图里的障碍物位置和视觉识别的目标位置会有 15 厘米以上的偏差,做完之后降到了 3 厘米以内。
2.3 机载计算平台的算力权衡
TerraBot 的"大脑"我用的是 Jetson Orin Nano 8GB 版本,没有选择树莓派或者 x86 工控机,原因有三点:算力功耗比高,8GB 显存能同时跑导航和轻量 AI 模型;自带 CUDA 和 TensorRT 生态,模型部署方便;体积小、无风扇散热版本功率只有 10W 左右,非常适合移动平台。但 Orin Nano 比较挑供电质量,我用了一块 4S 锂电池加 DC-DC 降压模块,单独给 Jetson 一路 5V/5A 供电,避免电机启停时电压跌落导致系统重启。
如果你预算有限,退而求其次用树莓派 5 也不是不行,但 AI 推理部分最好改用边缘 TPU 或者 OpenVINO 在 CPU 上跑小模型。实测下来,Orin Nano 上跑 YOLOv8s 量化模型可以到 35ms 一帧,树莓派跑同样模型要 200ms 以上,这个差距在移动巡检场景里是致命的,因为车在动,画面帧率不够就会漏检。
3. AI感知系统的设计与落地
3.1 目标检测模型的选型与训练
TerraBot 的视觉感知主要为两类任务服务:识别设备状态(表计读数、指示灯颜色),发现异常目标(液体泄漏、异物入侵)。这两类任务我都选择了 YOLOv8 系列,原因一是精度和速度平衡好,二是工程生态完善,导出 ONNX 再转 OpenVINO 十分顺手。表计识别用 YOLOv8s 检测表盘和指针,异常目标用 YOLOv8n 以追求更快推理速度。
训练数据是最花时间的部分。我从公开数据集和自采数据两个来源收集了约 1200 张标注图片,自采部分用 TerraBot 在不同光照、不同角度下拍摄,并在标注时把倾斜超过 30 度的表盘也纳入训练,这样模型在运动过程中才能保持鲁棒。训练用官方 ultralytics 库跑了 200 个 epoch,初始学习率 0.01,余弦退火调度,最终 mAP50 在验证集上到 0.91。这里一个实用经验:训练时开启 mosaic 和 mixup 数据增强,可以显著提高模型对背景变化的抵抗力,让模型专注于目标本身。
3.2 表计读数与异常识别实现
检测到表盘之后,读数的具体数值还不能直接拿检测框算,需要单独处理。我先把表盘区域从原图裁剪出来,用颜色分割定位指针的旋转中心,再根据指针直线和水平线的夹角换算成刻度读数。这个方法实现简单,运行速度快,在光线稳定的室内场景准确率能到 95% 以上,但在室外强光下容易受阴影干扰。
一个更稳的方案是用关键点检测模型同时输出表盘中心、指针尖端和刻度零位三个点。这种方案对光照鲁棒性好,但需要额外标注大量关键点数据,我因为时间原因没有在原型机上采用。如果你做的是工业级项目,建议直接上关键点方案。异常目标检测就相对直接,用目标检测框加一个分类置信度阈值,框住目标后传给后端做二次确认,避免单帧误报。
3.3 模型量化与边缘端推理优化
模型在 Orin Nano 上的部署我走了 ONNX 到 TensorRT 的路线。YOLOv8 官方仓库可以直接导出 ONNX,再通过trtexec工具转成 TensorRT 引擎文件。关键参数是 FP16 精度和动态 batch,FP16 能把推理速度提升一倍,而动态 batch 可以灵活适配不同输入帧数,实际检索时更灵活。
转换过程中最常遇到的问题是一些自定义算子(如 Detect 层的后处理)在 TensorRT 里不支持,解决办法是把后处理从模型里拆出来,用 Python 或 C++ 在外部实现。我在第一次转换时死活跑不过,查了一天文档才发现是torch.chunk在导出 ONNX 时的兼容性问题,换成split后就正常了。如果你也卡在这一步,优先检查导出时的算子版本和维度是否写死。
4. 自主导航与路径规划实战
4.1 建图:从激光SLAM到语义地图
TerraBot 的定位建图使用 Nav2 自带的 SLAM Toolbox,在 ROS2 里直接用slam_toolbox节点就能完成 2D 栅格地图构建。建图时要把机器人放到场景的角落,手动遥控它缓慢走一圈,尽量覆盖所有区域并保证激光能扫到环境特征。手持遥控器推车快走会导致里程计累积误差,地图会糊掉,这个环节慢就是快。
建完图后我额外做了一步:把一些关键巡检点位(比如表计设备的位置、充电桩位置)标注成语义点,保存成文件。这样导航时的目标点不再是一堆抽象的坐标数字,而是"表计A""充电桩"这样有意义的标签,任务调度层编写起来会直观很多。这个语义地图让我后来写巡检脚本时省了不少事。
4.2 全局规划与局部避障的参数调优
Nav2 的默认参数能用,但效果只能说"能走",离"稳"还有距离。我花时间调了三组参数,效果提升最明显:一是全局规划器的tolerance参数,默认 0.5 米,容易让机器人停得离目标点很远,我改成 0.15 米后,停靠精度明显提升;二是局部规划器 DWB 的max_vel_x,默认 0.5m/s 对巡检来说太快,我限制到 0.3m/s,转弯时的稳定性好很多;三是代价地图的inflation_radius,默认 0.55 米在窄通道里容易造成路径绕远,适当缩小到 0.4 米能通过更多狭窄空间。
调参最忌讳一次改一堆。我在一次改动里同时调了五个参数,结果完全搞不清楚是哪个改好了哪个改崩了。正确做法是每次只动一个参数,记录下改前改后的导航效果,最好能录下/cmd_vel的话题数据做对比。这个习惯帮我从混乱中救回来很多次。
4.3 定点巡检任务的实现逻辑
定点巡检用行为树来编排最合适。Nav2 原生支持 BehaviorTree.CPP,我写了一个简单的巡检行为树:先NavigateThroughPoses依次走过所有巡检点,到达每个点后短暂停留,触发视觉采集,采集完成后继续下一个点,全部走完回到起点。行为和视觉的衔接是通过 ROS2 Action 完成的,导航完成才发布拍照信号,避免车还没停稳就拍照导致图像模糊。
实际调试时发现一个问题:行为树里如果某个巡检点导航失败,整棵树会卡住。我在失败分支里加入了一个重试节点,失败后先原地旋转 90 度重新定位一次,再重新导航。这个简单策略把巡检完成率从 70% 提到了 90%,算是投入产出比非常高的一次改动。
5. 机载大模型与AI Agent辅助决策
5.1 为什么要把大模型放到机器人本地
一开始我的规划里没有本地大模型这个概念,后来远程监控过程中发现两个痛点:一是巡检画面和识别结果都要回传到服务器再分析,往返延迟大;二是部分场景的网络条件不稳定,断网时机器人就成了一堆废铁。于是决定在机载端部署一个大语言模型,让机器人在本地完成识别结果的理解和初步决策,断网也能独立工作。
本地部署最直接的好处是隐私和响应速度。巡检数据里往往包含公司内部设备信息,照片和日志全部留在机器人上,不会因为传输而产生泄露风险。而像"当前检测到表计读数低于阈值,是否需要重新检测"这类简单判断,本地模型 1 秒内就能给结果,省掉了与云端交互的时间,整个巡检节奏也更快。
5.2 轻量化模型部署配置实践
在 Orin Nano 上直接跑通用大语言模型并不现实,需要选一个足够轻量的方案。我实测过几类模型,最终选了一个 7B 参数量的量化模型,通过 Ollama 部署。Ollama 的优势是安装简单,一条命令就能拉模型启动服务,而且支持 OpenAI 兼容的 API 接口,方便我直接用 Python 调用。
部署时要在/etc/systemd/system/ollama.service里设置环境变量OLLAMA_HOST=0.0.0.0,这样局域网内的其他设备也能访问机器人的模型服务。我把模型上下文长度限制在 2048 tokens,并修改了模型配置文件中的num_ctx和num_predict,控制单次请求的显存占用,Orin Nano 8GB 在空闲时剩余显存只有 2GB 左右,超量请求会直接 OOM 崩溃。这个坑我至少踩了三次,每次都是因为并发请求太多把显存打满,后来在应用层用了一个简单的请求队列才解决。
5.3 用AI Agent自动生成巡检报告
有了本地大模型之后,我把"生成巡检报告"做成了一个小型 AI Agent。巡检完成后,感知模块会把全部识别结果汇总成 JSON,格式包含检测时间、目标类型、置信度、读数和异常状态。AI Agent 读取这份 JSON,结合预设的提示词模板,自动生成一份结构化的巡检报告,内容包括正常项、异常项、建议处理方案等。
关键点在于提示词设计。我一开始用了非常笼统的指令"根据数据生成报告",模型生成的报告信息密度低,很多数据点被遗漏。后来改成明确的模板加约束,比如"每个数据点必须以列表形式呈现""异常项需要给出优先级排序""引用数据时必须带时间戳",报告质量立刻提升了一个档次。AI Agent 真正的价值不是替人思考,而是把结构化数据快速转成可读性高、格式统一的内容,减少人工整理时间。
6. 软件架构与远程监控平台
6.1 通信方案:MQTT与ROS2的配合
机器人本体的各个模块之间用 ROS2 话题通信,这没什么疑问。但 ROS2 的发现协议要求所有节点在同一局域网内,远程监控跨网段时很痛苦。所以 TerraBot 的远程链路选了 MQTT,机器人端用一个桥接节点把 ROS2 话题转换为 MQTT 消息,服务器端订阅对应的 topic。这样部署简单、网络穿透性好,也天然支持多客户端同时订阅。
转换节点的实现思路很直接:机器人上的采集节点发布 Image 和 DetectionResult 话题,桥接节点用 rclpy 订阅,再通过 paho-mqtt 客户端发布到 broker。图像为了省流量,在发布前先压缩成 JPEG 并缩放到 640 宽度。实测 640x480 的 JPEG 图像,在 4G 网络环境下传输延迟在 300ms 左右,完全够远程监控用。
6.2 远程监控与数据可视化
远程端我写了一个轻量 Web 应用,运行在 Jetson 上,通过浏览器直接访问。页面左侧显示实时视频流,右侧显示当前 AI 检测结果列表,底部有一个简易地图控件展示机器人的当前位置和路径。后端用 FastAPI 提供 WebSocket 接口推送视频流和检测数据,前端用 Vue3 写页面,整体代码量不大,但把远程监控的核心需求都覆盖了。
真正花时间的是数据回放功能。我发现只做实时监控不够用,巡检过程中出现问题时,需要回到故障时间点查看当时画面和识别结果。于是给每个巡检任务都生成了回放文件,里面同步记录了时间戳、图像帧、定位坐标和 AI 识别结果,回放时按时间轴同步播放。这个功能在这次开发后半段帮了我大忙,排查问题不需要跑到机器人旁边现场复现了。
7. 常见问题与排查技巧实录
7.1 典型问题速查表
这一个多月调试过程中遇到的问题特别多,我整理了一份高频问题速查表,每个问题的排查思路也都是用真金白银换来的:
| 现象 | 可能原因 | 排查与解决 |
|---|---|---|
| 电机抖动、速度不稳 | PID 参数不合适或编码器接线异常 | 先用rospy单独发布速度指令测试单轮,确认编码器数据有效后再调 PID |
| 建图过程中地图漂移 | 激光雷达安装歪斜导致扫描平面倾斜 | 用水平尺检查雷达安装平面,固定雷达时在底部加 3D 打印的调平垫片 |
| 导航目标点停不准 | 全局规划 tolerance 过大 | 调整tolerance到 0.15 米以内,再检查里程计是否标定 |
| AI 识别漏检 | 推理帧率低或模型过拟合训练场景 | 确认是否开启 TensorRT FP16,增加训练数据的场景多样性 |
| MQTT 推送卡顿 | QoS 设置不匹配或带宽不足 | broker 端和订阅端设置相同的 QoS 等级,图像推送改为 QoS0 |
| Jetson 供电不稳自动重启 | 底盘电机启动瞬间拉低电压 | 用示波器抓电机启动时的电压跌落,增加 DC-DC 输出电容或独立供电 |
7.2 几个印象深刻的排查经历
印象最深的是第一次在室外测试导航的翻车现场。TerraBot 在室内走得好好的,一到室外就开始画龙,走一段就停下来重新规划路径。排查了好久才发现问题根本不是导航算法,而是室外光线太强,激光雷达受太阳光干扰出现大量噪点,代价地图被假障碍物堵死了。解决办法是给雷达加装遮阳罩,同时把雷达的测距模式改成抗强光的等级。这个坑提醒我:机器人永远是在真实物理环境里运行的,算法再漂亮也得过环境这一关。
另一个难忘的问题是大模型本地部署时的显存管理。一开始让 AI Agent 和视觉模型同时跑,跑着跑着 Jetson 就死机。用tegrastats查看发现是某个推理任务申请显存时,另一个任务还在占用,导致内存交换风暴。后来写了一个显存管理模块:视觉推理和大模型推理通过互斥锁保证不同时执行,并且大模型请求结束后立刻释放显存。这样共享计算资源稳定了很多,死机问题再没出现过。
7.3 提升调试效率的4条实操心得
调试这类复合系统,最忌讳在设备前盲调。我给 TerraBot 配了一套远程调试三件套:SSH 终端、RViz2 远程可视化、Web 日志面板。只要机器人通电联网,我就能在电脑前实时查看地图、代价地图、路径规划结果和 AI 识别画面,省去了大量来回奔走的时间。
第二,日志规范非常重要。我统一用了 ROS2 的rclpylogging 接口,每条日志带时间戳和模块名。排查问题时,先按模块名过滤日志,再按时间戳对齐多个模块的事件,大多数问题半小时内能定位。
第三,所有配置参数用一个 YAML 文件统一管理,不要散落在各节点代码里。改参数只动 YAML,不会因为改错代码导致整个工程报废。
第四,也是最重要的:每个功能模块先单独测,测稳了再组合。我见过太多人一开始就把导航、感知、大模型全打通,结果出了问题完全不知道该查哪里。TerraBot 的开发顺序一直是底盘 → 建图 → 导航 → 视觉 → 大模型 → 组合联调,每一步都在前一步稳定之后才继续。慢就是快,这个道理在机器人项目里体现得淋漓尽致。
8. 后续扩展与个人体会
TerraBot 做到现在这个状态,基本验证了"移动+AI视觉+本地大模型"这条技术路线的可行性。接下来我准备做三个方向的扩展:一是换更高精度的工业相机,把表计读数识别做到工业可用级别;二是在行为树里接入更复杂的任务编排,比如异常事件触发绕路复查的决策;三是把报告推送集成到企业微信或钉钉机器人,让巡检结果能第一时间触达相关人员。
复盘整个项目,我最大的一个体会是:做机器人项目,硬件稳定性和软件灵活性同等重要,缺一个都会让另一个变成空中楼阁。你有一个漂亮的算法框架,但底盘的 PID 没调稳,车都走不直,导航就是空谈;反过来,底盘再机械完美,没有一个好的软件架构承接,后期加功能也会让你痛苦到怀疑人生。TerraBot 这个项目真正让我受益的,不是某个单独的算法或模块,而是把"从硬件到 AI 到应用"整条链路都走通了一遍。
如果你也正准备开始自己的第一款机器人项目,我最后的建议是:不要贪多,先把一个场景做到极致。TerraBot 如果一开始就想做全能通用机器人,大概率现在还在画架构图。锁定"精准巡检"这一个点,所有设计围绕它展开,反而让整个系统早早跑了起来。