“事发时是人驾”要能证明:运行数据得先按这套留存

一、”结论可复核”是一项设计要求,不是事后补救
针对一起车辆碰撞起火的网传说法,厂商公开声明事发时车辆处于人驾状态。事故本身的责任归属、人员伤亡与财产损失不是本篇要碰的内容,那些要靠正式调查;我们只取其中一件纯工程的事:一句关于”那几秒钟发生了什么”的结论,要拿什么数据支撑。
这件事在软件行业同样每天发生,只是换了名字:一次线上故障之后,”当时是人工操作还是自动执行”要能回答;一次工单纠纷之后,”提交时的表单内容是什么”要能还原。结论能不能立住,取决于当时留没留,而不是取决于谁说得更有底气。所以它是一项设计要求:先定义将来要回答的问题,再决定现在留什么。反过来做,留了一堆全量数据却答不上那几个问题,是这类项目最常见的失败形态。
二、核心交付物:问题、字段、频率、保留期四列对齐
一个可复核集合应当从问题开始倒推。下面这张表是我们认为的最小可用形式,它把”将来要回答的话”直接钉到”现在要写的字段”上,缺任何一列,方案就落不了地。
| 要回答的问题 | 需要的字段 | 采样频率 | 保留期分档 |
|---|---|---|---|
| 那一刻处于什么模式 | 模式状态、模式切换事件、切换触发方(用户操作/系统请求/外部指令)、切换失败原因 | 状态变化即时记录,另加固定周期快照兜底 | 事件包按争议期保留,快照按短期滚动 |
| 人有没有在操作、操作了什么 | 方向盘与踏板输入量、安全带与在场信号、输入的生效与被抑制情况 | 高频通道,与模式状态同一时间基准 | 事件包内全量,事件包外不留 |
| 系统想要什么、实际执行了什么 | 系统下发的目标请求、执行机构返回值、请求与执行的差值与差值持续时长 | 与车辆控制周期同频,不按秒聚合 | 事件包保留,聚合值另行归档 |
| 有没有告警、告警为什么没起作用 | 告警标识、触发与解除时间、抑制原因、抑制方、是否被人为关闭 | 事件驱动,无周期 | 事件包与配置变更史一并保留 |
| 动力侧在那几秒是什么状态 | 关键量的原始采样窗口、异常终止码、上电与断载时序 | 固定高频,窗口独立于其他通道 | 原始窗口短,摘要长 |
| 谁在什么时候看过这些数据 | 读取者身份、用途声明、导出记录 | 访问即记录 | 与事件包同生命周期,不得早删 |
保留期的具体长度这里不给数字,因为它不是工程师单方面能定的:它要和整车生命周期、争议处理周期、合规要求一起谈完再固化成配置。这张表的价值在于逼着所有人把”留多久”这一列填出来,一旦留白,实际执行就变成”技术上能留就一直留”。
三、最小可复核集合的五块内容与必须裁剪的部分
上表的字段分五块落,缺一块就有一个问题答不上:模式切换(含触发方)、驾驶员操作输入、系统请求与执行差异、告警与抑制原因、动力关键量的采样窗口。第三块最容易被省掉,因为看起来冗余:系统发了一个请求,执行机构返回了结果,只留”最终状态”似乎也够。不够。请求与执行之间的差值才是最有信息量的东西:请求要减速而实际没减、要转向而角度没跟上,这类差值直接对应”是谁在决定车辆行为”。只留结果,这条就永远丢了。
第四块同理:告警存在但没起作用,原因必须可枚举(被抑制、被静音、条件未满足、时间未到),不能只留”有告警”这一个事实。抑制原因写不出来,将来这句话就没人能替你说。
裁剪同样是设计要求,而且要比留存更早就定下来。车内影像、乘员身份、通话与文本内容、精确行踪轨迹这类信息,要区分”为还原事件所必需”与”顺手也能采到”。后者一律不留,理由是它不但带来合规负担,还会在争议时把讨论带偏到与结论无关的地方。落地上有两条硬规矩:裁剪在写入前完成,而不是上传后再删;哪些字段属于”设计上不采集”,要有一份可查的清单,因为”我们没留”和”我们没采”是两种完全不同的说明。
四、环形缓冲:前后各留多少秒,比全量上云现实
事故还原需要的不是连续全量,而是触发点前后的一小段。车端到云端的链路要面对弱网、断链与流量成本,把全量高频数据实时上云,工程上必然以丢包收尾,而且丢的恰好是关键的那几秒。可行的结构是车端环形缓冲加事件触发落盘:
- 缓冲长度按”最长的因果链”来定,而不是按存储方便。驾驶意图到车辆响应通常在秒级,但一次模式切换的前因后果、一次告警抑制到失效,要往前追得更远,所以缓冲要能覆盖从操作意图到终止的整个过程,并把上电后的一段也纳入。
- 触发后冻结一份副本再落盘,否则环形缓冲会把刚要保住的几秒覆盖掉。这一步是纯工程细节,也是最常见的丢数据原因。
- 触发条件要写成可判定的组合,而不是只挂一个碰撞信号:约束机构动作、动力异常终止、模式切换失败、请求与执行差值超限、告警被抑制,都应当各自能触发一次冻结。单一触发源在关键时刻往往正好失效。
- 事件包要带”缓冲是否完整”的标志位。上电不足一段时长、或者触发过早,那这段就是残缺的,明确写出来比事后被质疑要体面得多。
采样频率的取舍同理:与责任判定直接相关的通道走高频原始值,其余走聚合或事件驱动。不要用秒级聚合去回答一个亚秒级的问题,一旦聚合,”谁先动的手”这类问题就永远答不了。
五、时间对齐:差二百毫秒,两份数据就能互相打脸
这是整件事里最技术性、也最容易翻车的一段。数据不只来自一个时钟:车内多个控制域各有各的本地时钟,网络传输有往返与抖动,上云之后还有一个入库时间。如果一份记录只带一个时间戳,那这份记录在不同来源之间根本没法比。
至少要留四个时间概念,而且每个都要说清它是什么:
- 来源本地单调时间:该域自己的计时起点,精度高但不可跨域比较。
- 同步后的时间基准:由整车的时间同步主源给出,并记录同步状态与估计误差;未同步时这一项要显式标记,不要拿默认值填。
- 车端打包时间:事件被冻结成包的时刻。
- 服务端入库时间:只用于运维排障,绝不能当作事件时间参与判定。
关键是第二个字段要带上误差范围,并且把这个范围连同记录一起留存。判定时”两件事的先后”如果落在误差范围内,那就只能承认先后不可判定,而不是挑一个看起来合理的顺序。差二百毫秒,足以让一份数据说”先切到人驾再撞”,另一份说”先撞再切”,两边都拿得出记录,谁也说服不了谁。跨来源比较时还要固定一条:只在同一个基准下比,跨域比较要通过显式换算,换算过程也要能复算。
上云链路上的时间不能被当作事件时间用,这条要写进接口约定。链路延迟在弱网下可以大到几十秒,用它排序,得出的结论会稳定地错。
六、不可篡改、访问控制与对外说明的映射
留存数据的可信度不只在完整性,还在”没人能悄悄改”。可执行的做法不复杂:
- 事件包写入即计算哈希,按包与按字段两个层级各算一份,字段级用于定位到具体哪一条被动过。
- 哈希与批次号另存一份到写入者没有权限的位置,否则篡改者可以连校验值一起重写,等于没有校验。
- 导出与读取全程留痕:谁、什么时候、为了什么用途、导出了哪个批次。这一份日志的可信度要求要高于数据本身。
- 到期删除要有责任人和执行记录。删与不删都要能证明,”到期未删”是合规问题,”删早了”是证据问题,两种都要有人对结果负责。删除动作本身进日志,包含被删批次的标识与哈希。
最后是最容易被忽略但最能救人的那张表:对外说明与内部字段的映射。法务或公关要说出的每一句话,都要能指到一个具体字段和它的采样口径。
| 对外那句话 | 依据字段 | 口径说明 |
|---|---|---|
| 事发时处于人工驾驶模式 | 模式状态与紧邻的上一条切换事件、切换触发方 | 模式定义与判定阈值要一并给出,否则”人驾”是个口语词 |
| 驾驶员有操作输入 | 输入量通道与生效标记 | 需说明输入被抑制与否,避免与”操作了但没生效”混淆 |
| 相关系统未请求介入 | 系统请求记录与抑制原因 | 要区分”未请求”与”请求了但被抑制”,两句话不能混用 |
| 数据自事发后未被改动 | 包级与字段级哈希、批次号的独立存证 | 需能指出存证位置与校验方式 |
这张表要在设计阶段就写,而不是在需要发声明的时候临时凑。能填出这句话对应哪个字段,才说明这个字段真的被留下来了;填不出,就是留存清单上的一个洞。洹拓评审这类数据留存方案时,把它当作验收件:对外文案改动一处,映射表必须同步改一行,两边不一致就直接卡住发布。这不是形式主义,是因为所有争议最后都会落在”你说的这句话,数据里哪一条支持它”。