做机器人学习的人都知道,画面好拿,真值难凑。深度、分割、检测框要和图像逐像素对齐,差一点,训练出来的策略就偏一点。Turing Sim 的相机传感器这次把这件事压进了一次渲染里。

打开网易新闻 查看精彩图片

此前这条传感器线已经走完了 IMU 和 LiDAR,轮到相机时,需求不只是出图。机器人学习要用的深度、分割和检测框,必须和画面严格对齐。渲染侧走的是 Hydra,后端可以是 Storm(光栅化)或 Turing RT(光线追踪),但两者都没有把深度和 ID 缓冲交给 Python。

难点有两层:一次渲染要吐出全部输出,且所有输出描述同一组像素,精度还得可检验;同时要能在编辑器里跑,不能把视口画质拖下水。

相机就是 USD 相机

相机传感器被定义成一个标准的 UsdGeom.Camera,挂上 turingSensor:type = "camera"。预设按视场角和画面宽高比来设置镜头,不另造一套相机抽象。

读回 AOV 靠一个小型原生模块,它读取 Hydra 的颜色、深度、primId 和 instanceId 缓冲,再把 ID 解码成场景路径,实例代理也包含在内。Storm 和 Turing RT 都适用。

为什么相机要单独开进程

整数 ID 必须在关闭多重采样的情况下渲染,而 Hydra 每个进程只读一次这个设置。于是相机被放进自己的 worker 进程渲染,编辑器视口照样保留抗锯齿,两边互不干扰。

过程中还踩到一个坑:Storm 的视空间法线缓冲会把负分量截掉。法线因此改为由深度重建,绕开这个截断。

从缓冲到真值的转换规则也定得很细:RGB 按奇数倍超采样取平均,真值取每个像素的中心采样;深度换算成沿光轴的米数;物体取最近的带标签 prim,没有标签就取所属刚体。输出包括紧框和投影框两种 2D 框、有向 3D 框,以及 OpenCV 内参和相机位姿。

精度和开销都摆出来了

对 4 米外的一面墙,只要墙出现在画面里,深度误差都在 2 mm 以内,反投影回去的点也落在墙面 2 mm 以内。Storm 和 Turing RT 的分割掩码逐像素一致,深度中位差 0.01 mm。

性能方面,带全部输出的 640×480 一帧要 36 ms;开 3×3 抗锯齿要 73 ms。预设的帧率就是按这些实测值定的,不是拍脑袋写的。

截图里能看到编辑器中的相机预览在 UR10 工作站上切换各种输出,每个 UR10 连杆、工作台和方块各有一种颜色。后续一个 commit 修好了机器人连杆上框标签互相重叠的问题。

编辑器里的帧是尽力而为;按精确帧率采集属于合成数据流程,那是下一步。