这篇文章想解决的是:如果你正在做人形机器人,怎么把“能看见”真正做成“能进入动作闭环的视觉系统”。它适合已经开始搭原型、正在为相机位置、标定漂移、延迟、手眼坐标和调试链路发愁的人。最关键的工程判断是,视觉系统的第一目标不是把模型分数刷高,而是让感知结果在正确的时间、正确的坐标系里,以可验证的方式进入抓取、对齐、避障和人工接管流程。
这篇适合谁
- 已经有人形机器人或双臂移动平台原型,准备把视觉接进抓取、导航或交互闭环的人
- 正处在“相机能出图,但动作老是偏一点、慢半拍、偶发失效”的阶段
- 想先搭一套能持续迭代的视觉工程底座,而不是只做一次 demo 的团队
先纠正几个很常见的误区
- 误区 1:先把检测模型做强,系统自然会变稳。
真实项目里更常见的失败不是“识别完全错了”,而是时间戳不对、坐标不对、目标虽然看到了但已经错过抓取窗口。 - 误区 2:相机位置越像人眼越好。
对人形机器人,视角不是审美问题,而是任务问题。头部视角利于全局理解,胸前视角更稳,腕部视角利于末端对位。没有哪个位置天然最好,只有哪种任务最需要。 - 误区 3:标定做过一次就结束了。
只要你有拆装、震动、摔倒、热漂移或维护动作,外参和手眼关系都可能变。标定必须进入运维和验收流程,不是一次性仪式。 - 误区 4:视觉延迟只影响“体验”,不影响控制。
对站立、抓取、避障和人与机器人近距离协作,几十毫秒的陈旧感知就足够把末端位姿、接触判断和风险区判定全部带偏。
关键实现判断
如果你只能记住一件事,那就是:先定义任务真正需要什么视觉结果,再反推相机布局、标定流程、同步方式和模型栈。不要反过来从“我手里有什么相机和模型”出发。
我更推荐把人形机器人视觉拆成 5 层:
- 采集层:相机、深度、曝光、帧率、时间戳、硬件同步
- 几何层:内参、外参、手眼、机体坐标系、位姿链路
- 感知层:检测、分割、关键点、目标姿态、场景语义
- 任务接口层:把“看见了什么”转成抓取位姿、落脚禁区、接近减速区、人工确认提示
- 验证与回放层:可视化、日志、时间对齐、失败样本桶、离线复盘
这 5 层里,最容易被低估的是几何层和验证层。没有这两层,前面再强的模型也会变成一堆不稳定的屏幕效果。
分步实践指南
第 1 步,先把任务拆成视觉可交付结果
别先讨论模型,先写接口。你到底要让视觉输出什么?常见是这几类:
- 抓取前的目标 6D 位姿和可抓取面
- 行走或移动中的可通行区域、危险区域和动态障碍
- 人与机器人协作时的人体位置、接近方向和安全触发区
- 装配、插接、按键、开门这类近场动作的精定位结果
每一类输出都要附带 3 个字段:坐标系、时间戳、置信度。没有这 3 个字段,后面的控制和监督逻辑基本没法做稳。
第 2 步,按任务放相机,而不是按习惯放相机
对人形机器人,常见布局可以这样取舍:
- 头部双目或 RGB-D:适合环境理解、通行空间、人体与障碍物感知,但头部运动会把图像稳定性和外参维护难度一起带上来。
- 胸前相机:更适合做“机器人身体坐标系下的稳定观察”,常用于站立操作、搬运前对齐和工作区监控。
- 腕部相机:最适合末端对位、近场抓取和插接,但遮挡、抖动、照明变化会更严重。
- 顶置或外部相机:适合安全区、工位级监督和区域语义,不适合直接替代手边精操作视角。
如果你准备上多相机,不要只看视野覆盖,还要看同步、布线、供电、发热和计算带宽。RealSense 关于多深度相机配置的文档里,一个很值得借鉴的判断就是:多相机系统不是“多几路视频流”这么简单,而是要把硬件同步、主从关系和带宽规划一起考虑,否则现场里最先坏掉的往往不是模型,而是时间一致性。
第 3 步,先把内参、外参、手眼三件事做成固定流程
内参没校好,边缘畸变和尺度误差会直接污染后续估计。ROS 2 里的 camera_calibration 工作流之所以一直有价值,不是因为它花哨,而是因为它把棋盘格尺寸、覆盖范围、采样姿态和 CameraInfo 发布这套最小闭环做得很明确。对原型阶段,我建议你把它变成每次相机更换、镜头更换或安装件调整后的固定步骤。
外参和手眼不要混在一起。你至少要单独维护:
- 相机相对机体主坐标系的位置
- 腕部相机相对末端执行器的手眼关系
- 世界坐标、机器人基座、任务夹具之间的场地坐标关系
MoveIt 的 hand-eye calibration 教程有个很实用的工程提醒:做 eye-in-hand 标定前,必须先保证相机内参和坐标框架是可信的,而且要采够多个姿态样本,别只拿两三个姿态就想把误差压下去。这个原则在人形机器人上更重要,因为手臂和躯干一起动时,几何误差更容易被放大。
第 4 步,把延迟预算写出来,不要只凭感觉
我建议每条视觉链路都明确一份时延账单:
- 曝光与传感器输出耗时
- 驱动和中间件缓存耗时
- 预处理与推理耗时
- 几何转换与任务接口耗时
- 控制器真正消费这条结果的时刻
如果一条末端抓取链路总延迟已经接近机械臂从预抓位移动到目标位的时间尺度,那你就不该继续给它塞更重的模型,而应该先减小缓存、降低分辨率、缩短发布链路,或者把视觉结果改成“低频重规划 + 高频局部伺服”的双层结构。
Isaac ROS Nvblox 的一个好启发是,它把深度图、颜色图和位姿当成一个完整输入组合来做实时 3D 重建和 costmap 输出。这提醒你,视觉链路的价值不只是给出一张检测框,而是给任务层提供可直接消费的几何结果。如果你的控制或规划真正需要的是占据、距离场或局部几何重建,那就别把系统只停留在 2D 检测框上。
第 5 步,把“感知正确”与“动作可用”分开验收
很多团队只做模型精度评估,不做任务可用性评估。更实用的验收应该至少分两层:
- 感知层验收:识别率、姿态误差、深度噪声、光照变化、遮挡鲁棒性
- 动作层验收:抓取偏差是否在末端容差内,危险区触发是否早于控制制动距离,接近动作是否会因帧丢失而误判
也就是说,别问“模型 AP 够不够高”,要问“这份结果够不够支持当前动作”。这两个问题不是一回事。
第 6 步,把回放和失败桶做成日常工具
视觉系统的 bug 很少能靠现场盯屏完全定位。你需要至少保存:
- 原始图像或抽帧图像
- 关键 topic 的时间戳
- 当时机器人姿态和末端位姿
- 视觉输出结果和下游动作决策
- 失败标签,例如“标定漂移”“反光误检”“腕部遮挡”“推理超时”
如果没有失败桶,团队最后一定会把所有问题都笼统归为“视觉不稳”,这几乎等于什么都没学到。
可以直接借鉴的外部工程做法
- ROS 2 camera_calibration / image pipeline:适合作为内参与基础发布链路的标准化起点,尤其适合建立可重复的相机更换验收流程。
- MoveIt Hand-Eye Calibration:适合作为腕部相机或基座固定相机的手眼标定参考,重点不是工具本身,而是“先保内参,再采多姿态,再校手眼”的顺序。
- Intel RealSense 多相机配置文档:很适合拿来提醒自己,多深度相机系统会被同步、主从配置、USB 带宽和时间一致性反噬,不是简单叠设备。
- Isaac ROS Nvblox:适合作为“深度 + 位姿 + 3D 重建 + 可导航几何输出”这一类链路的工程参照,尤其适合把感知结果直接转成规划与避障可消费的数据结构。
最容易翻车的地方
- 为了“像人”把主相机装得太高,结果近场操作永远缺视角
- 只做静态标定,不做摔倒后、维护后、热机后的复核
- 多相机都能出图,但时间戳并不在一个可靠时基上
- 把腕部相机当万能解,忽略了遮挡和照明
- 拿检测框直接驱动动作,没有做几何约束和置信度过滤
- 出现误抓后只去调模型,没有先检查坐标链和延迟链
怎么验证你真的搭对了
- 静态几何验证:在多个已知位置放标定板或已知尺寸工件,检查视觉估计和真实位置误差,分别记录中心区和边缘区。
- 动态时间验证:让手臂或头部做固定轨迹运动,检查视觉输出时间戳与机器人状态时间线是否一致,确认不是“看到了上一帧的世界”。
- 任务级验证:用至少 20 到 50 次重复抓取或对位测试,记录成功率、偏差方向、失败类别,而不是只记最终平均成功率。
- 退化验证:主动制造背光、反光、部分遮挡、网络拥塞、单路相机掉帧,检查系统是否会降级、请求人工确认或切到更保守模式。
- 维护后复测:每次拆装相机、换支架、跌倒后、搬运后,都重复最小验收集,不允许凭经验默认“应该还准”。
如果这几类测试都通过,你得到的才不是一个演示版视觉模块,而是一套能长期迭代的人形机器人视觉底座。
下一步怎么做
如果你现在还没有视觉系统,我建议按这个顺序推进:
- 先选 1 个最小任务,例如桌面抓取、门把手定位或近场避障
- 只上最少数量的相机,先把时间戳、内参、外参和回放做稳
- 让视觉输出直接喂给一个真实动作,不要停留在 RViz 里
- 从第一天开始记录失败桶,别等系统复杂了再补
- 任务稳定后,再扩展第二视角、第二模型或 3D 重建链路
这样做会慢一点,但它更像工程,不像表演。