拓冰建站拓冰建站
首页 / 资讯中心 / 正文

从无人机到地面机器人:视觉避障与坐标转换实战指南

实际做居家地面机器人时最容易被低估的往往是感知能力。大疆无人机能把视觉避障、路径规划和图传链路做得足够稳定核心原因不是单一硬件堆料而是感知、坐标变换、决策、通信已经形成了一套成熟的工程范式。ROMO2 这个示例项目要做的就是把这套范式从天空搬到地面用无人机感知技术栈做一个居家省心伙伴机器人。读完本文你会得到一套可复用的地面机器人感知落地路线从视觉避障、坐标转换、导航控制到 MAVLink 最小地面站和仿真验证都能按同一套思路推进。下面所有代码和配置都服务于一个最小可运行的原型不要求你一开始就搭建完整产品。先把感知链路跑通再逐步加入导航、数据回传和生产级保障。1. 为什么无人机感知技术能直接搬到地面机器人1.1 无人机感知技术到底解决了什么问题无人机感知技术解决的核心问题不是“识别出画面里有什么”而是“机器人如何知道自己在哪、前方有没有障碍、下一步能不能走”。为了回答这三个问题无人机通常会配备视觉相机、IMU、激光雷达、超声或 GPS/RTK 等传感器并通过一套实时计算链路输出位置、姿态和障碍信息。飞行控制器再根据这些信息决定是前进、悬停还是绕行。地面机器人面对的问题几乎一样只是运动维度更少。它不需要在三维空间里维持姿态平衡但仍然需要知道自己在地图上的位置需要检测桌腿、台阶、宠物、人体等障碍需要在窄通道里判断能否通过。正因为问题结构相同无人机感知栈里的坐标变换、目标检测、路径规划和数据链路都可以迁移到 ROMO2 这类地面设备上。1.2 从天空到地面哪些可以直接复用哪些必须重做迁移不是照抄。无人机和地面机器人在运动模型、定位前提、风险形态上都有明显差异直接复制会带来很多隐蔽问题。对比项典型无人机居家地面机器人 ROMO2运动模型四旋翼六自由度可悬停、俯仰、横滚两轮差速或四轮全向只有平面三自由度定位手段GPS/RTK 常见视觉和激光辅助室内无 GPS需要视觉里程计、IMU、激光或二维码主要风险炸机、掉高、螺旋桨伤人碰撞、跌落楼梯、撞到宠物或小孩感知重点障碍物、地面高度、禁飞区障碍物、地面边界、台阶、狭窄通道数据链路数传加图传距离远但带宽受限室内 Wi-Fi 或以太网距离近但墙体遮挡多从上表能看出感知算法本身可以复用但运动控制、定位融合和通信策略必须按地面场景重新设计。这也是 ROMO2 项目最容易走错的地方很多开发者把无人机用的全局路径规划直接塞给两轮差速机器人结果因为忽略最小转弯半径和动力学约束机器人在原地反复打转。1.3 ROMO2 的总体架构ROMO2 在这里是一个示例项目代号用来承载“把无人机感知技术落地到居家地面机器人”这条技术主线。它的总体架构可以拆成四层感知层负责采集图像、深度或激光数据输出障碍物位置和可通行区域。决策层根据感知结果维护一个状态机决定前进、停止、绕障或返回。控制层把决策翻译成电机速度指令对应无人机的动力分配。数据链路层通过 MAVLink 协议把机器人的心跳、位置和感知状态上报给地面站或后端控制台。这四个层次正好对应无人机飞控系统中“感知、规划、控制、通信”的经典划分。后续章节按这个顺序展开。2. 感知层落地先复刻视觉避障的最小闭环2.1 感知选型先定相机类型和参数视觉避障的传感器选择要看场景。无人机常用双目视觉或激光雷达因为飞行高度变化大、光线复杂居家地面机器人则更常用深度相机比如 RealSense 系列或奥比中光系列原因有两个一是室内距离短深度相机在 0.3 米到 5 米范围内表现稳定二是深度相机可以直接输出每个像素的距离不需要像双目那样做密集匹配算力消耗更低。选型时重点关注几个参数参数含义推荐值或参考方向感知距离相机能稳定测距的范围居家场景建议 0.3 到 5 米水平视场角水平方向能看到多宽90 到 120 度更适合避障帧率每秒输出多少帧图像或深度图避障链路最好不低于 15 FPS算力要求算法对 CPU/GPU 的占用先跑最小 Demo再量化到目标平台需要说明的是原始材料没有给出版本号落地前要先确认相机驱动、操作系统和推理框架之间的兼容性。不要假设新相机一定能被旧驱动识别。2.2 坐标转换是感知落地第一道坎无人机感知里最容易出错、也最需要提前设计好的一环就是坐标转换。相机检测到一个障碍物时得到的是“相机坐标系下的 xyz”但机器人控制器需要的是“机器人坐标系下的左右前后距离”导航模块则需要“地图坐标系下的障碍位置”。中间至少经过两次变换相机到机器人本体机器人本体到世界或地图。FAST-LIO 这类激光雷达惯性里程计在无人机上很常用它自带的坐标转换是面向机载 LiDAR 坐标系的。如果直接把这套转换搬到地面机器人上一定要重新确认雷达、相机、机体之间的外参是否一致。不同车型的安装位置、俯仰角、高度都不同换算结果会出现系统偏差严重时机器人会判断错障碍的方位。下面是一个最小坐标转换示例用于说明三个坐标系之间的关系。import numpy as np # 假设相机安装在机器人前方 0.05 米处高度 0.15 米 # t_cam_body 表示相机中心相对机器人中心的位置单位米 t_cam_body np.array([0.05, 0.0, 0.15]) # 相机检测到的障碍点在相机坐标系下的坐标 p_cam np.array([0.8, -0.1, 0.0]) # 转换到机器人本体坐标系 p_body t_cam_body p_cam print(body frame:, p_body) # 如果机器人已经通过视觉里程计/IMU 得到自己在地图系中的位姿 # 设 R_body_world 为旋转矩阵t_body_world 为平移向量 # p_world R_body_world p_body t_body_world这个例子没有引入旋转矩阵适合用来理解平移部分。实际项目中相机安装俯仰角、左右偏摆角都会造成旋转偏差必须通过标定得到外参矩阵不能只做平移近似。2.3 一个最小视觉避障模块的 Python 实现把感知链路落到代码上最直接的闭环是读取图像检测前方是否存在障碍输出一个布尔量。下面这段代码使用 YOLOv8n 做目标检测用检测框面积占整帧比例来判断障碍是否已经近到需要停车。import cv2 from ultralytics import YOLO model YOLO(yolov8n.pt) cap cv2.VideoCapture(0) # front_obstacle 是决策层的输入 front_obstacle False while True: ret, frame cap.read() if not ret: continue results model(frame, verboseFalse, conf0.5) for r in results: for box in r.boxes: x1, y1, x2, y2 map(int, box.xyxy[0]) area_ratio (x2 - x1) * (y2 - y1) / (frame.shape[0] * frame.shape[1]) if area_ratio 0.25: front_obstacle True break if front_obstacle: break # 这里只做演示实际项目中要把 front_obstacle 传给控制器线程 cv2.putText(frame, fobstacle{front_obstacle}, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2) cv2.imshow(view, frame) if cv2.waitKey(1) 0xFF ord(q): break cap.release() cv2.destroyAllWindows()这段代码的目标是打通“采集 - 推理 - 输出状态”的链路不是生产级实现。生产环境里要关注三点一是推理线程和控制线程要分离不能因为推理慢让电机控制卡住二是置信度阈值和面积阈值需要根据房间大小和相机角度标定三是帧率低时要有超时保护比如超过 300 毫秒没有新感知结果就直接停车而不是继续前进。2.4 训练数据不能直接用无人机航拍图很多开发者手里有无人机低空航拍数据集比如俯拍车辆、屋顶、树冠的图像于是想直接用来训练居家机器人模型。这样做的识别效果通常不好因为居家机器人的相机视角接近 0.5 到 1.2 米高度看到的物体是侧视和斜下视角与航拍俯视完全不同。推荐做法分两步用小规模居家场景数据微调比如在客厅、厨房、走廊收集 2000 到 5000 张图像标注人、宠物、桌腿、台阶、沙发等类别。使用公开的低角度室内数据集补充场景多样性但要做领域差异评估不能直接上线。训练好的模型要单独统计每类的平均置信度和漏检率。避障场景下漏检比误检代价更高因此宁可多一些误报也不要在宠物静止时直接碾过去。3. 决策与控制把无人机路径规划改成地面导航3.1 先建模地面机器人的运动约束无人机的路径规划要考虑三维空间、悬停能力和姿态变化两轮差速地面机器人只有线速度 v 和角速度 w 两个控制量还必须考虑最小转弯半径、加速度限制和道路宽度。把无人机 3D 路径规划算法直接跑在地面车上会出现两类问题一是规划出的路径由空间曲线组成地面车无法执行二是没有考虑窄通道规划出的路径穿过沙发和茶几之间的缺口但车体宽度过不去。设计控制层前先用运动模型描述机器人。两轮差速机器人的常见运动学关系是v (v_right v_left) / 2w (v_right - v_left) / wheel_base这里 v_right 和 v_left 是左右轮线速度wheel_base 是左右轮间距。控制目标就是合理输出 v 和 w让机器人沿期望路径前进。3.2 从无人机 Offboard 到地面控制器的状态机PX4 或 ArduPilot 无人机的 Offboard 模式允许外部程序接管控制权地面站的指令会被飞控执行。地面机器人没有真正的 Offboard 模式但可以借鉴同样的思想感知决策模块生成目标运动量底层驱动只负责执行。这比把避障逻辑直接写在电机驱动里更清晰。下面是一个简单的状态机包含 FORWARD、STOP、TURN 三个状态。class ObstacleAvoidance: def __init__(self): self.state FORWARD self.max_speed 0.3 # m/s居家场景不要太高 def update(self, obstacle_left, obstacle_front, obstacle_right): if self.state FORWARD: if obstacle_front: self.state STOP else: return 0.2, 0.0 # v, w elif self.state STOP: if obstacle_front and obstacle_left: self.state TURN elif obstacle_front: self.state TURN else: self.state FORWARD return 0.0, 0.0 elif self.state TURN: # 左边有空隙就左转否则右转 direction -1 if obstacle_left else 1 if not obstacle_front: self.state FORWARD return 0.05, direction * 0.6 return 0.2, 0.0这个状态机的优点是简单、可观察、易调试。实际生产项目里建议把状态和时间戳同时打日志否则很难判断机器人是在避障还是因为感知丢失而被动停住。3.3 树莓派上可跑的避障控制器树莓派在无人机悬停项目里经常被用作机载计算机在地面机器人里同样适合做入门控制器。资源有限时不要直接跑 YOLO 全模型建议先用深度相机阈值或单线激光做避障深度学习模型只做目标类别识别。一个可行的树莓派方案感知线程以 10 到 20 毫秒周期读取深度图取图像中部区域的最小深度值。如果最小深度小于 0.4 米输出 obstacle_frontTrue。控制线程以 50 毫秒周期读取感知状态调用状态机计算 v 和 w。电机驱动通过 GPIO PWM 接收速度指令。# 伪代码实际项目要结合具体电机驱动和深度相机 SDK depth depth_camera.read() region depth[int(rows * 0.3):int(rows * 0.7), int(cols * 0.3):int(cols * 0.7)] min_depth region.min() obstacle_front min_depth 0.4需要强调树莓派上跑算法前要测量实际推理周期。如果深度图处理超过 200 毫秒避障已经失去意义因为机器人按 0.3 m/s 行驶200 毫秒已经走了 0.06 米加上刹车距离很容易撞上障碍。3.4 为什么不能把无人机 PID 参数直接复制下来无人机的 PID 控制通常包含角速度和姿态环频率较高参数针对质量轻、响应快的机体调校。地面机器人质量大、惯量大同时存在轮胎打滑和地面摩擦变化直接把 PID 参数复制过来会出现震荡或响应迟缓。建议步骤是从零调参只给线速度观察机器人起步和停车是否平滑。再给角速度观察转向是否出现超调。逐步加入负载变化测试比如拖拽少量物品时速度是否保持稳定。调参过程中记录 P、I、D 三个参数每次变化的方向和现象形成自己的参数记录表。不要凭感觉一次同时改多个参数。4. 数据链路与地面站让机器人把感知结果说出来4.1 MAVLink 是无人机和地面机器人共同的语言MAVLink 是无人机领域最常见的通信协议用于飞控与地面站、飞控与机载计算机之间的消息交换。地面机器人虽然不是飞行器也可以复用它原因是 MAVLink 已经内置了心跳、系统状态、位置姿态、电池电压等通用消息地面站生态也很成熟。复用 MAVLink 有几个实际好处心跳消息可以快速判断设备是否在线。SYS_STATUS 可以上报电池、传感器健康度。LOCAL_POSITION_NED 可以上报机器人在局部坐标系中的位置。自定义 MAVLink 消息可以传输感知状态比如 obstacle_front、当前状态机状态等。需要注意MAVLink 只是消息协议不负责传输层。实际数据可以走 UDP、串口、TCP 或 Wi-Fi 链路。4.2 用 pymavlink 写一个最小地面站下面用 pymavlink 实现一个最小地面站接收机器人的心跳、位置和感知状态。from pymavlink import mavutil # 连接本机 14550 端口的 UDP 链路 conn mavutil.mavlink_connection(udp:127.0.0.1:14550) # 等待心跳确认链路正常 conn.wait_heartbeat() print(heartbeat from system, conn.target_system, conn.target_component) while True: msg conn.recv_match(type[HEARTBEAT, LOCAL_POSITION_NED, SYS_STATUS], blockingTrue) mtype msg.get_type() if mtype LOCAL_POSITION_NED: print(pos x%.2f y%.2f z%.2f % (msg.x, msg.y, msg.z)) elif mtype SYS_STATUS: print(battery voltage%.2f % (msg.voltage_battery / 1000.0)) elif mtype HEARTBEAT: print(heartbeat ok)这段代码可以用于验证链路连通性。实际项目中还要加入条件判断如果连续 3 秒没有收到任何消息就要触发控制端告警不能只依赖地面站界面。4.3 图传数据怎么从机载端回到算力平台无人机图传通常走专用无线链路把摄像头画面从机载端传到地面端。居家地面机器人环境不同帧率要求也不同更常见的是走 Wi-Fi 或以太网把图像或推理结果送回算力平台。有两种典型方案机载端只上传感知结果。机器人本地完成避障只把障碍类型、坐标、状态机状态上传到平台。优点是带宽占用低、实时性好适合家用路由器环境。机载端上传压缩视频流。适合远程查看场景但会增加网络延迟和算力消耗。推荐以第一种为主第二种按需开启。居家场景中机器人最核心的任务是安全不能因为远程视频传输占用了网络带宽导致避障控制指令延迟。4.4 居家场景的通信选型和实时性取舍在家居环境下Wi-Fi 信号会受墙体、家电和人体干扰不能简单认为“局域网延迟很低”。决策前先测量三类指标指标建议控制指令延迟一般要小于 100 毫秒越短越好视频传输带宽720p 至少 2 Mbps1080p 至少 4 Mbps丢包率超过 5% 时应触发降速或停车策略如果室内 Wi-Fi 不稳定可以考虑用串口连接主控与传感器只把 WiFi 用于地面站监控。这样即使网络波动机器人自身避障仍然能工作。5. 从仿真到实机先验证逻辑再上硬件5.1 为什么先跑仿真而不是直接装轮子无人机项目里炸机成本高所以大家习惯先用 PX4 仿真或 Gazebo 跑通逻辑再上真机。地面机器人虽然不会炸机但同样的原则仍然适用一是减少反复拆装硬件的时间二是可以快速测试极端场景比如突然出现障碍、低电量、传感器断流三是方便在 CI 环境里跑回归测试。仿真不能完全替代实机但能把逻辑错误提前暴露。常见的逻辑错误比如状态机跳转条件写反、坐标转换用错、通信超时处理缺失在仿真里都可以快速复现。5.2 基于 Gazebo 的最小仿真框架如果本地已经安装 ROS 2 和 Gazebo可以搭建一个极简仿真环境一个两轮差速小车模型一个安装在前方的深度相机以及一个动态障碍物。下面是一个简化的机器人描述片段用来示意结构!-- robot.urdf -- robot nameromo2_sim link namebase_link/ link namefront_depth_camera/ joint namecamera_joint typefixed parent linkbase_link/ child linkfront_depth_camera/ origin xyz0.1 0 0.1 rpy0 0 0/ /joint gazebo referencefront_depth_camera sensor typedepth namecamera update_rate15/update_rate camera horizontal_fov1.2/horizontal_fov image width640/width height480/height /image /camera /sensor /gazebo /robot仿真时建议设置两个固定场景空旷客厅和拥挤走廊。前者验证机器人是否能在无障碍时保持直线前进后者验证避障状态机是否能在窄通道里稳定绕行。5.3 在仿真里验证哪些指标仿真验证不应该只关心“程序能不能跑起来”要针对感知和控制链路定义指标指标说明建议目标避障成功率连续运行 20 次是否都未碰撞至少 95%感知响应延迟从感知线程输出到控制线程执行的时间小于 100 毫秒超时停车可靠性人为停止感知数据后机器人是否停车100% 停车驻停距离机器人从检测到障碍到完全停住的距离小于 0.2 米这些指标先要在仿真里达标再转入实机。实机阶段重新测量并记录数据不要直接沿用仿真指标。6. 常见问题排查感知、坐标、通信、功耗四条链路6.1 机器人不动或者乱动先从感知帧率查现象机器人明明看到障碍物却没有停车或者没障碍时频繁停车。排查顺序打印感知线程输出时间戳确认帧率是否稳定。检查推理结果是否进入控制线程。检查面积阈值或深度阈值是否设置得过保守或过激进。检查是否在控制线程里做了阻塞调用比如 IO 或网络请求。最常见的原因是感知线程和控制线程之间没有共享最新状态导致控制线程读到了旧数据。推荐方式是用带锁的共享变量或消息队列传递最新状态不要直接读一个被长时间更新的数组。6.2 坐标转换出错时的典型表现现象机器人检测到障碍在正前方但控制层认为障碍在侧面于是机器人原地旋转或绕圈。排查步骤打印原始检测坐标、转换后坐标和控制层读取坐标。检查相机外参符号正负方向最容易出错。检查是否把机体坐标系和世界坐标系搞反。如果使用 FAST-LIO 输出的位姿先确认它使用的是哪种坐标系约定再和 MAVLink 消息对照。这个问题的排查关键是逐步打印而不是直接跳到最后一步修改矩阵。把每一步转换后的坐标可视化能快速定位哪一层出错。6.3 地面站总是失联时的检查顺序现象pymavlink 地面站运行后一直收不到数据或者运行几分钟后断开。检查顺序如下机器人端是否持续发送 HEARTBEAT。UDP 端口和 IP 是否一致。路由器是否启用了客户端隔离。发送端和接收端是否都正确处理了断线重连。防火墙是否限制了端口。如果接收端超过 3 秒没有收到 HEARTBEAT应该主动在日志里输出告警并触发机器人减速或停车。不能等到用户发现界面卡住才处理。6.4 居家场景跑不动深度学习模型的替代方案现象树莓派或低算力主控跑 YOLO 时帧率只有 2 到 3 FPS避障基本失效。替代方案先用深度相机阈值检测障碍不依赖深度学习。在机载端只运行轻量分类模型比如 MobileNet 系列。把高算力检测任务放到后端只在需要时上传单帧图像做确认。使用模型压缩、量化或 TensorRT 加速但要验证压缩后的精度损失。避障安全应该优先保障距离阈值逻辑深度学习模型可以用于“这个障碍物是人还是沙发”这一类慢速语义判断而不是用于紧急停车。6.5 一份可以直接打印的排错清单表问题现象常见原因检查方式处理建议感知到障碍但不停车感知结果未传给控制线程打印两个线程的时间戳和共享状态用消息队列共享最新状态无障时频繁停车深度阈值过远或检测框面积阈值过低查看深度图最小值和检测框占比重新标定阈值机器人原地转圈坐标转换错误或运动学正负号错误打印各坐标系下障碍坐标逐层校对坐标变换和轮速符号地面站一直无心跳端口、IP 或防火墙问题用 tcpdump 抓包确认消息是否到达统一端口配置并加断线重连帧率过低无法避障模型过大或主控算力不足测量推理耗时改用深度阈值或轻量模型电池掉电太快控制周期过短、频繁启停或电机选型不当记录电流和运行时长优化控制频率并调整电机型号7. 从学习 Demo 到居家省心伙伴还差哪些生产级设计7.1 学习环境与生产环境的差异清单学习环境的目标是快速看到效果生产环境的目标是安全、稳定、可运维。两者的差异往往比想象中大。关注点学习 Demo生产级 ROMO2配置代码里写死参数外部配置文件或云端下发日志print 输出结构化日志按级别和模块分类监控人工观察心跳、电量、传感器健康度自动上报异常处理程序报错退出超时停车、断线重连、传感器失效保护回滚方案重刷代码固件分区、配置备份、远程回滚数据安全不上传明确哪些数据可上传、如何脱敏如果 ROMO2 要长期在家运行至少要把“传感器失效保护”和“远程日志”补齐。否则出现问题后你只能靠用户描述去猜现场状态。7.2 电机选型不能照搬无人机逻辑无人机电机选型主要看推重比、KV 值和螺旋桨匹配地面机器人则看扭矩、转速、轮径和减速比。很多新手按无人机习惯找高 KV 电机结果装到地面车上转速过快、扭矩不足连一个小坡都爬不上去。地面机器人选型可以参考下面几个要素要素说明整车质量预计包括电池、主控、相机、电机和结构件轮径和减速比决定最大线速度和爬坡能力连续输出扭矩决定是否能推动负载启动电流影响电池续航和主控供电稳定性建议先用估算表格计算总质量再按实际路面测试选择电机。不要只看额定功率要关注持续工况下的温升。7.3 居家场景的安全和隐私设计居家机器人和无人机不同它离人更近还可能在无人时持续采集图像。安全设计至少包括三方面运行安全限制最大线速度建议不超过 0.5 m/s检测到传感器断流后立即停车机构上预留物理急停按钮。隐私设计图像数据默认只在本地处理需要上传时先脱敏对非必要的人脸、家庭环境信息做模糊或裁剪。权限控制控制指令接口要有身份校验不能允许同一 Wi-Fi 下的任意设备直接下发命令。这些设计不需要等到产品阶段才做。在 ROMO2 原型阶段就加上“传感器断流停车”和“图像本地处理”两条规则后续演进会省很多事。7.4 下一阶段可以扩展的方向ROMO2 走完“感知 - 决策 - 控制 - 通信 - 仿真 - 排错”这条闭环后可以根据实际需要选择扩展方向接入大疆企业开发者平台把机器人数据与无人值守、巡检业务打通但这部分需要按官方开发者流程注册并申请相应权限。加入语音交互让用户通过自然语言指令控制机器人到指定位置。增加云端地图与多机协同实现多台地面机器人共享地图和任务。结合配电网巡检、仓储盘点等垂直应用把避障能力复用到专业场景。扩展前要控制范围一次只加一个能力并重新跑一次仿真和实机测试。否则感知、通信、控制三条链路同时修改问题边界会变得很难定位。真正值得记住的技术判断是感知不是孤立模块而是一条从传感器、坐标转换、状态机、控制器到地面站的完整数据链路。ROMO2 这类居家地面机器人能稳定工作靠的不是某一个模型表现好而是整条链路每一步都可观测、可验证、可回退。如果你刚入门建议先不追求复杂算法把视觉避障、停障、MAVLink 心跳这三件事在真实设备上跑通再逐步扩展导航和无人值守能力。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门