DrivoR (CVPR 2026 · Apache-2.0) × TD25A 契约 v3
架构下钻:悬停展开 · 点击固定
上排是 DrivoR 原生流水线的 token 收敛;下排六个阶段,左侧为 DrivoR 原样,右侧橙区为 TD25A 的对应决定。所有数字 2026-08-25 对官方仓库源码逐行核对过,与早先版本有出入的地方以本图为准。
压缩发生在第 ② 步:每图 3,936 个 patch 被 16 个 register 吸收后整体丢弃(÷246)。它之前算力全在 ViT,它之后整个决策只在 64 个向量上进行。注意 ④ 的 64 是候选轨迹条数,和 ② 的 64 个 token 是两回事,只是数字撞了。
01 · 输入编码
drivor_features.py::_get_camera_feature · ::_get_lidar_feature即「ViT 输入准备」:把各路数据变成 ViT 能吃的 (C,H,W) 张量——相机只需缩放归一化,点云要五步压成俯视图。相机与激光各有一个独立 ViT;子流程末尾的 patch 严格说已是 ViT 自己的第一层(patch_embed)。注意本层混着三类东西:传感器、自身状态、任务记忆,只有前者算「感知」。
子流程
取末帧→相机 resize + ImageNet 归一化→点云 → BEV 直方图→堆通道→patch_embed
输入
- 相机:4 路 × 单帧(
cameras[-1])= 4 张 1148×672 RGB(六步预处理↗) - 激光:
±35 m 铺 518²——lidar_pc: [] 默认关,论文从未使用 - z 轴:
0.2 m 一刀切 → 2 通道,层内 z 丢弃,值为点密度(处理流程↗) - DrivoR 无地图、无位姿锚点;内外参算了也不用——纯反应式
- 自车状态
11 维 = 位姿 3(x,y,θ)+ 速度 2(vx,vy)+ 加速度 2 + 路线意图 4(one-hot 左/直/右)。位姿记的是「刚才走过的路」,但只取末帧 → 相对自己恒为 (0,0,0)(逐段拆解↗)
输出
- 每图
82×48 = 3,936 patch token - 合计
15,744(4 图,非 16 图)
DrivoR 原样 vs TD25A 决定
DrivoR 原样
输出3,936 patch / 图 · 合计 15,744
TD25A
输入① 传感器输入
雷达:Mid360 → BEV 224² @ 0.05 m(±5.6 m)。3 档占据 + z_min / z_max = 5 通道,直接取 STVL 三维体素(射线清除 + 2 s 衰减白送)。处理流程 →↗
相机:一期 不接。它补的是语义不是几何,而语义要标注数据;一期没有标注,接了只会稀释 token 预算。DrivoR 侧怎么处理 →↗
② 自身状态
位姿 SE(2) = (x, y, yaw)(FAST-LIO:点云匹配 + IMU + 轮速)。不变成 token,只当锚点用,而且两类层用法不同:全局层要裁 + 转(在地图哪一点抠 224²),局部层只需转(costmap / STVL 本来就是 odom 系以车为中心的滚动窗口,不存在裁剪)。同一份位姿还决定 footprint 画到 visits 栅格的哪一格。其余状态量见 04。DrivoR 侧怎么处理 →↗
③ 任务记忆(不是感知,来自 06 回流 ↺)
覆盖染色图:tanh(0.2·visits) 软覆盖 + frontier + 静态图,3 个通道,复用 td25a_e2e_coverage 管线。它由 06 的几何记账写出、01 再读回来,是闭环状态不是传感器。格式与接法 →↗
三类空间完全对齐(同一个 224² 栅格),所以并成一张 8 通道图走一条支路,不拆。
原契约里的第四个通道「实时占据」已砍:它取自 local costmap、带 inflation_radius: 0.55(= 11 格)的膨胀,会把桌腿间隙抹平——正是高度分档想暴露的东西。膨胀是规划器的概念不是感知的概念,留给 06 的安全否决层用。 输出14×14 = 196 patch(8 通道 · DINOv3 patch-16)
为什么并成一条支路不拆两条:要判的是「这格没扫过 且 这格能钻」——一个逐格的与运算。同一张图上卷积核第一层就同时看到两者;拆开就得从两组各 16 个全局摘要里反推逐格对应,246 倍压缩之后「哪一格」已经没了,做不到。
位姿一飘,两个通道会打架。覆盖染色画在 map 系、局部层在 odom 系,map→odom 漂移会让「已扫区」和「看到的障碍」错位——网络会看到墙压在已扫格子上。这就是 04 要加「定位置信度」的具体失效形式。
实测发现:顶档若定义成「> 1.01 m」,室内天花板会点亮 83% 的格子,通道等于失效;封顶到 2.0 m 后只剩 19%。纸上推的时候看不出来。完整拆解 →↗
复用 DrivoR 原样TD25A 需修改一期砍掉TD25A 新增来源:valeoai/DrivoR@main(2026-08-25 逐行核对)· nav2_params.yaml · td25a_e2e_coverage
状态:设计契约 v2,非已实现功能。
本文的主体是页面顶部那张交互下钻图。悬停任一阶段展开子流程、
输入输出,以及 DrivoR 原样与 TD25A 决定的左右对比。
下面的文字只补图上放不下的结论。
图之外的三条结论
① 职责拆分。 避障归策略,跟踪归跟踪器,否决归安全层。原先的 MPPI
同时干三件事,现在降级为纯跟踪器(砍 obstacle / path critic),
避免与策略两个决策者打架。
② 覆盖染色图不是新造的。 td25a_e2e_coverage 包里的
visits 计数 → tanh(0.2·visits) 软化 → 覆盖前沿三层管线已在
4F / 9F 真实地图跑通,输入侧直接复用;该包同时留作评测床雏形和
论文里现成的 learning baseline,不删。
③ 两处待拍板。 轨迹词表 A(换 (ds,dθ),16 token)还是
B(加第三头 (dx,dy,dθ),24 token)——后端救得回倒车、救不回原地旋转,
而 53 次硬停全部在折返 cusp;BEV 多尺度一期砍还是留。
其余契约项均已冻结在图内。
参考
- Kirby, Boulch, Xu et al. Driving on Registers. CVPR 2026. arXiv:2601.05083
- 本机源码:
valeoai/DrivoR → navsim/agents/drivoR/(约 2200 行)
- TD25A 侧:
turn_on_td25a_robot/config/nav2_params.yaml ·
td25a_e2e_coverage/observation.py