尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

智能驾驶预测服务接口:行为与轨迹预测的工程实践

智能驾驶预测服务接口:行为与轨迹预测的工程实践 简介智能驾驶功能软件平台设计规范系列文档聚焦功能软件层标准化本部分为第3分册专门定义预测功能服务接口面向自动驾驶系统设计、算法开发与集成测试人员用于规范行为预测、轨迹预测等核心算法模块与决策规划模块之间的数据交互与接口逻辑。资源包内为单个PDF文档大小约909KB内容精炼、目录完整。文档基于传感器抽象与感知融合结果对不同交通参与者的未来行为及轨迹给出统一预测接口与数据结构包含标准元数据头、行为预测数据、轨迹预测数据、单个交通参与者轨迹预测数据及轨迹点信息等详细定义并在附录中提供接口描述与结构说明便于开发人员直接对照实现或扩展。适用对象明确目标是支撑GB/T定义的2级及以上智能驾驶系统的模块化拼插式开发。目前已有126人浏览学习适合从事功能软件平台搭建、预测算法工程化或接口适配的研发工程师参考。1. 预测服务接口把不确定性拆成两级契约预测功能在智能驾驶软件平台里是存在感最低、但信息量最大的一层。感知告诉你前车是一辆轿车决策告诉你该不该变道而预测要回答另一个问题这辆车接下来是直行、减速还是突然打方向盘。拿到这份《智能驾驶功能软件平台设计规范》第三部分时逐行读完才发现它把不确定性拆成了两个可消费的接口行为预测给离散意图和概率轨迹预测给多假设的连续路径。这套接口由国汽智联联合华为、一汽、东风、长安等十余家单位共同定义核心价值是让主机厂可以拼插式组合不同算法厂商的预测组件。做功能软件集成、预测算法部署或决策规划对接的工程师都能从中找到需要的那段契约。2. 行为预测与轨迹预测两个接口的边界怎么切2.1 为什么拆成两个服务接口规范第 5 章把预测功能拆成行为预测服务和轨迹预测服务两个独立接口这个拆分不是随手画的背后是语义层次、时间尺度、下游消费方式三方面的差异。行为预测输出的是离散标签左转、右转、变道、横穿、减速。它回答的是意图问题适合用来过滤场景——比如判断路口行人是否要横穿或者旁车道车辆是否有并线意图。轨迹预测输出的是连续时空序列每个目标未来 n 秒内的一组轨迹点。它回答的是路径问题下游决策规划拿它做时空冲突检测看自车规划轨迹会不会和别人未来的轨迹相交。维度行为预测服务接口轨迹预测服务接口输出粒度离散行为标签 概率%连续轨迹点序列多假设各带概率时间尺度0~10s 的意图判断未来 5~8s 的轨迹规范上限 10s下游用法场景意图过滤、风险评估时空冲突检测、安全距离校验典型模型意图分类、交互博弈模型轨迹采样、生成式预测、概率栅格升级影响枚举扩展影响字典和映射轨迹点数、采样频率影响带宽和延迟还有一个工程层面的原因行为预测和轨迹预测在算法侧经常是两个独立模型迭代节奏不一样。接口拆开之后行为模型升级不需要动轨迹数据结构轨迹模型换了采样方式也不会影响行为枚举。对平台方来说这是给不同算法厂商留的拼插接口。2.2 依赖关系与数据流向规范 4.1 节明确列出了预测功能的依赖信息感知融合功能服务接口、高精度地图、自车定位服务接口、自车状态服务接口、V2X。实际数据流向是感知融合先给出跟踪目标列表含目标编号、类别、状态预测模块再叠加高精度地图的车道拓扑和自车定位姿态推断目标处于哪个车道、有没有路口最后输出行为和轨迹。V2X 在这个依赖列表里比较特殊。它提供超视距信息比如信号灯相位、远车意图广播能显著提升预测置信度尤其在遮挡场景。但 V2X 渗透率不足时接口要容忍这个输入缺失预测模块得有降级策略——拿不到 V2X 就只用感知和地图信息输出一样的接口结构只是概率置信度适当调低。2.3 从枚举设计看场景意图行为预测的枚举定义规范 6.2 节值得细看。C_前缀代表车辆行为P_前缀代表行人行为区分得很清楚。车辆行为里变道、转向、匀速、加减速分得很细加减速还分了慢加速、高加速、慢减速、高减速四档。这个分档粒度不是拍脑袋而是给决策规划不同反应时间窗口的语义信号——高减速意味着冲突风险上升决策要准备紧急规避慢加速则只是常规的交通流调整。行人行为枚举只有等待、横穿、接近、离开四类外加 UNKNOWN。做行人预测的都知道行人轨迹比车辆更难建模因为自由度大、意图切换快。规范没有硬编码奔跑跳跃这类细粒度行为说明设计者有意识保留了一个收敛的枚举集合把更精细的语义留给轨迹预测去表达。值得注意的是正文枚举里没有 U_TURN但附录 proto 里出现了这个不一致在第 3 章展开讲。3. 逐字段拆解包头、行为枚举与多假设轨迹3.1 标准元数据头每个字段都是排查线索规范 6.1 节定义的标准元数据头是所有预测服务消息的公共包头六个字段在工程上各有用途排查现场问题的时候缺一不可。字段类型工程用途ModuleIDInteger标识算法组件来源多厂商混跑时定位是哪个节点的输出VersionIDMajor/Minor/Patch结构体接口兼容性判断枚举扩展时应升 MinorSequenceNumUint64检测丢帧、乱序统计预测链路延迟TimeStampS Ns结构体秒 纳秒的精度设计满足多传感器时间同步Frame枚举VCS 车体系 / WGS84 / UTM消费端按此做坐标变换Status枚举GOOD / MED / FAILURE故障时下游必须降级Status 字段在集成调试时特别容易忽略。规范定义了 MED 和 FAILURE 两个非正常状态但没有细化什么情况算 MED。实际落地时我一般建议预测模块自检跟踪目标数量、模型推理耗时、输入数据新鲜度任一项超标就置 MED模型彻底跑飞才置 FAILURE。下游拿到 FAILURE 应该直接丢弃本帧而不是拿旧数据兜底。3.2 行为预测数据字段行为预测数据BehaviorPredictionMeta有四个字段ObjectsID、BehaviorPredictionType、BehaviorProbability、Period。ObjectsID 的语义是同目标检测和跟踪服务接口中目标编号这句话是跨模块契约的关键。感知融合模块维护全局目标 ID预测模块只能引用不能重新编号。集成时最常见的坑就是预测模块内部维护了自己的 track 列表ID 对不上感知模块导致决策规划无法把预测结果关联回真实目标。BehaviorProbability 取值范围 0~100单位是 %。这里有个隐含约定同一目标所有行为的概率之和应该等于 100或者至少小于等于 100。如果模型输出的多个行为概率归一化没做好下游按最大概率判断意图时会得到不稳定结果。Period 表示这个预测的有效时长范围 0~10 秒。超过 Period 之后这个行为预测默认失效不能继续参与下游场景判断。3.3 轨迹预测数据的嵌套结构轨迹预测数据是整套规范里嵌套最深的结构展开来是四层TrajectoryPredictionMeta目标级元数据 └── ValidTrajs[]多假设轨迹数组 └── TrajectoryP单条轨迹 └── ObjectTrajectory[]轨迹点数组 └── ObjectTrajectoryPoint轨迹点 ├── ObjectPointx, y 位置 ├── ObjectHeading航向 └── TimeStamp时间戳这个嵌套结构表达了一个核心思想轨迹预测不是给一条线而是给一组假设每个假设带概率。比如路口左转场景目标车可能直行也可能左转规范允许输出两条轨迹TrajProbability 分别给 0.3 和 0.7。这比单条确定性轨迹对下游更有价值决策规划可以按概率做风险加权评估。ValidTrajs 数组个数规范没有给上限工程上建议控制 3~5 条。超过 5 条之后概率被稀释每条轨迹的区分度下降而且带宽浪费严重——一条 8 秒轨迹、每 100ms 一个点就是 80 个轨迹点5 条就是 400 个点。轨迹点的时间戳单位是秒规范没规定采样间隔常见做法是 100ms 或 200ms。采样间隔选择要和下游规划周期对齐如果决策规划是 50ms 周期100ms 的轨迹点之间要靠线性插值补中间位置。3.4 枚举编号的版本陷阱这个坑值得单独拿出来讲。规范正文表 46.2 节的枚举编号是9: C_SLOW_DECELERATION 10: C_HIGH_DECELERATION 11: C_TURN_LEFT 12: C_TURN_RIGHT但附录 A proto 描述里写的是C_HIGH_DECELERATION 10; C_U_TURN 10; C_TURN_LEFT 11; C_TURN_RIGHT 12;C_U_TURN和C_HIGH_DECELERATION在 proto 枚举里撞了同一个编号 10。如果直接拿附录的代码去编译protoc 会直接报错C_U_TURN uses the same enum value as C_HIGH_DECELERATION。这意味着要么附录的 C_U_TURN 是后续版本想加入但还没分配编号的字段要么是文档笔误。处理建议只有一个以正文表 4 为基准冻结编号。枚举值一旦上了线在 protobuf wire format 里是以整数形式传输的老设备反序列化时解析到未知枚举值行为是未定义的。跨厂商联调前必须统一一份枚举映射表把 U_TURN 要么映射到预留值要么明确本轮版本不启用。我见过不止一次因为枚举编号不一致上游发的C_TURN_LEFT11被下游解析成C_U_TURN决策规划直接误判意图的事故。4. 从 proto 定义到可编译工程接口落地的第一步4.1 从规范到 proto 要处理的五个问题附录 A 给了完整的 proto 描述但照抄编译不过。除了 3.4 节的枚举冲突还有几个问题emum拼写错误、Message大小写不统一、VersionID vid字段名不规范、required uint32 ModuleID在 proto2 语义下存在过期兼容风险。这些细节不处理跨团队协作时每个人都会重新踩一遍。另一个选择是字段命名风格。规范正文用驼峰ObjectsID、TimeStampproto 社区惯例是 snake_case。protobuf 编译器允许任何合法标识符但建议统一 snake_case这样不同语言生成的代码风格一致——Python 生成的字段名就是下划线风格C 里也更容易映射。4.2 一份可编译的 common.proto把枚举定义放到 common.proto 里统一管理行为服务和轨迹服务都引用它避免两处维护。下面是修正后的完整 common.protosyntax proto2; message Header { required uint32 module_id 1; message VersionID { required uint32 major 1; required uint32 minor 2; required uint32 patch 3; } required VersionID version 2; required uint64 sequence_num 3; message TimeStamp { required uint64 time_stamp_s 1; required uint64 time_stamp_ns 2; } required TimeStamp time_stamp 4; enum FrameType { NA 0; VCS 1; WGS84 2; UTM 3; } required FrameType frame 5; enum Status { GOOD 0; MED 1; FAILURE 2; } required Status status 6; } enum BehaviorPredictionType { UNKNOWN 0; STOP 1; STATIONARY 2; MOVING 3; C_CHANGE_LANE_LEFT 4; C_CHANGE_LANE_RIGHT 5; C_CONSTANT_SPEED 6; C_SLOW_ACCELERATION 7; C_HIGH_ACCELERATION 8; C_SLOW_DECELERATION 9; C_HIGH_DECELERATION 10; C_TURN_LEFT 11; C_TURN_RIGHT 12; P_WAITING 13; P_ACROSSING 14; P_APPROACH 15; P_DEPART 16; }参数说明module_id对应算法组件编号sequence_num做丢帧检测time_stamp_s和time_stamp_ns组合成高精度时间戳frame枚举告诉消费端坐标参考系。枚举统一放在 common 里行为服务和轨迹服务都能引用避免两边各维护一份同义枚举。4.3 行为与轨迹服务定义及编译行为预测服务对应的 protosyntax proto2; import common.proto; message BehaviorPredictionMeta { required uint32 objects_id 1; required BehaviorPredictionType type 2; required double behavior_probability 3; // 单位 % required double period 4; // 单位 s } message BehaviorPredictionsService { required Header head 1; repeated BehaviorPredictionMeta behavior_predictions 2; }轨迹预测服务对应syntax proto2; import common.proto; message Point2D { required double x 1; required double y 2; } message ObjectTrajectoryPoint { required Point2D object_point 1; required double object_heading 2; // 单位 degree, 取值 [0, 360) required double time_stamp 3; // 相对轨迹起始时刻偏移, 单位 s } message TrajectoryP { required double traj_probability 1; // 单位 % repeated ObjectTrajectoryPoint object_trajectory 2; } message TrajectoryPredictionMeta { required uint32 objects_id 1; required double time_start 2; // 轨迹起始时刻 required double period 3; // 预测时长, [0, 10] optional BehaviorPredictionType type 4; repeated TrajectoryP valid_trajs 5; } message TrajectoryPredictionsService { required Header head 1; repeated TrajectoryPredictionMeta traj_predicts 2; }编译命令protoc -I. --python_out./gen common.proto behavior_prediction.proto trajectory_prediction.proto说明-I.指定 include 路径为当前目录这样import common.proto才能解析。--python_out生成*_pb2.pyC 工程用--cpp_outJava 用--java_out。注意object_heading的取值是度数且范围 0~360和常见的弧度制 [-π, π] 不同消费端做角度运算前必须先统一单位。4.4 用 Python 快速验证一条预测消息生成代码之后第一步不是接真数据而是手工构造一条消息验证序列化链路。下面这个脚本构造了一条包含单个目标、两条候选轨迹的轨迹预测消息import common_pb2 import trajectory_prediction_pb2 as tp svc tp.TrajectoryPredictionsService() svc.head.module_id 3 svc.head.version.major 1 svc.head.sequence_num 1024 svc.head.time_stamp.time_stamp_s 1700000000 svc.head.time_stamp.time_stamp_ns 0 svc.head.frame common_pb2.VCS svc.head.status common_pb2.GOOD meta svc.traj_predicts.add() meta.objects_id 42 meta.time_start 0.0 meta.period 8.0 meta.type common_pb2.C_CHANGE_LANE_LEFT traj meta.valid_trajs.add() traj.traj_probability 0.7 p traj.object_trajectory.add() p.object_point.x 1.5 p.object_point.y -0.3 p.object_heading 90.0 p.time_stamp 0.1 buf svc.SerializeToString() print(serialized bytes:, len(buf))字段说明time_start0.0表示从当前时刻开始预测轨迹点time_stamp0.1表示这是 100ms 后的位置。traj_probability0.7表示这条轨迹在当前目标所有候选轨迹中占 70% 的置信度。序列化后的字节数可以作为带宽预算的参考——比如一帧 100 个目标、每个 3 条轨迹、每条 80 个点序列化后通常在几十 KB 量级。反序列化同理recv tp.TrajectoryPredictionsService() recv.ParseFromString(buf) for meta in recv.traj_predicts: best max(meta.valid_trajs, keylambda t: t.traj_probability) last_pt best.object_trajectory[-1] print(ftarget {meta.objects_id}: best traj {best.traj_probability}%, flast point ({last_pt.object_point.x:.2f}, {last_pt.object_point.y:.2f}))这个消费端逻辑概括了决策规划最常用的查询模式按目标遍历取概率最高的轨迹作为主预测再做冲突检测。多假设里概率较低的那些轨迹也不能扔它们代表的是低概率高风险场景安全模块往往重点看这些。5. 编排与排错让预测输出在系统里跑起来5.1 模块编排与触发时序预测模块在功能软件层里的位置是承上启下上游吃感知融合的目标列表、定位模块的自车姿态、高精度地图的车道拓扑下游把行为意图和轨迹喂给决策规划。触发时序上建议以感知融合的输出节拍为主时钟感知一帧到位就立刻触发预测计算预测结果攒齐一批目标后再统一发布避免逐目标发布带来的抖动。决策规划消费预测输出的时机也得对齐。如果决策规划是 20Hz 周期预测只有 10Hz每个决策周期内要缓存最近一次预测结果并用 Period 字段判断陈旧度。Period 剩余时间不足一个决策周期时这个预测不可信决策规划应转入保守策略。5.2 帧率、缓存与数据过期预测链路丢帧排查我一般先看两个指标预测输出的 SequenceNum 是否连续以及感知输入到预测输出的端到端延迟。延迟超过 100ms 就要检查是不是轨迹数量过多导致序列化耗时太长或者模型推理没有做 GPU 并行。数据过期是另一个隐蔽问题。规范中 TimeStamp 带秒和纳秒但轨迹点内部的时间戳是 Float 秒。如果轨迹点的时间戳是相对时间偏移下游做碰撞检测时要先加上 Header 里的绝对时间才能和自车规划轨迹的时间轴对齐。常见的错误是直接把两个时间戳相减导致 8 秒预测轨迹全部错位。时间基准不统一的问题在集成测试阶段很难发现因为大多数场景下规划轨迹只有 3~5 秒误差累计不够大但到了紧急制动场景就会暴露出时序错乱。5.3 坐标系与角度制对齐Header 的 Frame 字段有三个可选值VCS车体坐标系、WGS84经纬度、UTM通用横轴墨卡托。规范里轨迹点 ObjectPoint 明确说是在车体坐标系下也就是 Frame 应为 VCS。但实际联调时定位模块给的往往是 UTM 坐标感知目标经常在自车坐标系下描述。如果预测模块内部做了坐标系变换输出时忘了把 Frame 字段从 UTM 改回 VCS下游按车体系解析就会得到偏移几十米的轨迹。角度制同样要统一。ObjectHeading 单位是 degree范围 0~360但很多规划算法内部用弧度。转换逻辑建议收敛在一个公共 util 里所有模块共用不要在各自代码里各自转一遍。5.4 两层概率语义的边界行为概率和轨迹概率是两个维度的量不能混用。行为概率描述的是目标会不会左转轨迹概率描述的是已知目标左转的前提下这条路径的可能性。如果模型没有显式建模条件依赖将两者相乘再和其他目标的概率做比较是逻辑错误。规范围绕这个设计了冗余字段轨迹接口里的type是可选的目的就是让下游直接读到行为标签不需要自己去和轨迹概率做关联推理。消费端合理做法是先用行为概率做意图过滤筛选出开启碰撞风险的目标再在这些目标上用轨迹概率做时空采样评估自车轨迹和每条候选轨迹的重叠程度。两个概率各管一段互不替代。5.5 上线前必过的三个冒烟用例用表格形式列出必测场景每个场景验证接口的特定能力。用例输入说明期望输出高速巡航前车减速自车 100km/h 巡航前车 200m 处开始制动行为枚举为 C_SLOW_DECELERATION 或 C_HIGH_DECELERATION轨迹沿本车道减速至停车路口对向车左转无信号灯路口对向车辆打左转灯驶入路口行为为 C_TURN_LEFT 或 C_CHANGE_LANE_LEFT轨迹出现分叉直行轨迹概率递减行人横穿行人从路侧步入车道目标类别为行人行为为 P_ACROSSING轨迹方向横穿自车路径与自车规划轨迹有交点这三个用例分别验证了纵向减速意图识别、多假设轨迹分叉输出、行人行为枚举映射。其中第二个用例还顺带检验了概率归一化——如果两条轨迹概率加起来不等于 100说明模型归一化层有问题需要回到算法侧修。跑通这三个用例预测接口的数据结构、坐标系、概率语义基本就算对齐了可以往更复杂的交互场景推进。本文还有配套的精品资源点击获取
返回列表