简介:面向自动驾驶安全评价的《智能驾驶行为安全评价方法》白皮书,由华为、清华、中汽院智能网联等多家单位联合编写,系统阐释“合理可预见且可避免”的核心安全理念,适合自动驾驶研发、测试验证及安全管理岗位的工程师、研究人员和高校师生阅读。资源共1个PDF文件,大小10.5MB,内容涵盖智能驾驶安全概念综述、行为安全概念详解、场景枚举与参数化方法、封闭道路低速场景实践等章节,逐层拆解功能安全、预期功能安全、行为安全、ODD合理性及人机交互等评价维度。书中对行为安全的“合理可预见性”和“可避免性”展开分层论述,并结合场景覆盖度定义与自然驾驶数据提取方法给出可落地的实践路径。已有132人学习下载,对于正在构建自动驾驶安全评价体系、开展行为安全研究或制定测试验证方案的人员,可直接梳理出理论框架与实施参照。
1. 智能驾驶行为安全评价:为什么说会开不等于安全
智能驾驶行为安全评价,说白了是回答一个具体问题:一辆车在自动驾驶模式下,每次变道、加速、刹车,到底有没有超出安全边界。我接触这个方向是从一个主动安全验收项目开始的,当时人工看测试回放,一小时数据要标两小时,后来换成行为安全评价方法,才把评价周期压到分钟级。所谓行为安全,不能只看撞没撞,更要看那些“没撞但随时可能出事”的驾驶行为,比如贴前车屁股变道、匝道汇入时反复犹豫、感知置信度低还强行通过路口。这套方法的核心是三件事:搭一套能复现的指标体系,在限定ODD内切出有效评价窗口,再用算法把驾驶行为量化成安全分数。适合正在做自动驾驶路测评价、主动安全功能验收和驾驶行为分析的工程师。
2. 评价指标体系:从跟车、变道到决策迟滞,拆解行为安全的三层结构
2.1 操作层、决策层、规划层:为什么一层指标覆盖不了行为安全
行为安全评价最忌讳上来就定一个安全分数。实际项目里,驾驶行为必须拆成三个层面单独建模,最后再合并,否则某个风险被平均掉,问题找不到责任人。
操作层看车辆动力学响应。纵向看加速度、减速度、跟车时距THW和碰撞时间TTC;横向看横向加速度、车道偏移量、转向盘角速度。这一层数据直接来自惯性单元、轮速和转向角传感器,出错少,但信息量有限,只能告诉你车开得稳不稳,不能告诉你这个行为合不合理。
决策层看意图与时机。典型指标包括变道意图是否提前激活、超车时有没有足够安全裕度、路口通行时减速度是否突兀。这层最难量化,因为意图本身是个黑匣子,只能通过转向灯、轨迹预瞄点和横向偏移趋势反推。我在项目里通常用一个“意图激活点”的检测:当转向灯亮起且横向偏移超过0.2米时,标记为意图激活,再看激活点到实际跨越车道线的时间差,小于3秒记一次仓促变道。
规划层看行为与ODD的匹配。比如系统是否在ODD边界附近强行运行、感知置信度低时是否降级退出、决策是否存在明显迟滞。这一层直接关联主动安全功能的设计边界,是评价结果能否用于量产验收的关键。规划层的量化方法是统计ODD状态切换点的决策时间,以及感知置信度低于阈值时系统的响应策略。
三层指标的关系是递进式的:操作层异常大概率反映决策层或规划层的问题,规划层判断失误会直接表现为操作层的抖动。做评价项目时,我的习惯是先分别计算三层子分数,再按时间轴对齐,看某一项分数骤降的前后5秒内其他层的变化,这样出了问题改的是模块,不是分数。
下表是我在模拟项目X里使用的指标分层框架,供搭建体系时参考:
| 层级 | 纵向指标 | 横向指标 | 典型采集频率 |
|---|---|---|---|
| 操作层 | THW、TTC、加速度RMS、冲击度、急减速次数 | 横向加速度、转向角速度、车道偏移标准差 | 10–50Hz |
| 决策层 | 变道激活时序、超车安全裕度、路口减速合理性 | 变道持续时间、预瞄点横向偏差 | 事件触发 |
| 规划层 | ODD匹配度、感知置信度、决策迟滞时间 | 降级退出速度、接管请求提前量 | 1–10Hz |
2.2 主观评分到客观指标:一套可落地的映射方法
评价体系要让人信服,必须能和人工专家的评分对上号。常见做法是请三位驾驶教练分别给每个测试片段按0到10打分,取均值作为主观安全分,再和客观指标做相关性分析。
我做过一个真实交付项目,主观分和TTC最小值的斯皮尔曼相关只有-0.35,反而和单位时间内急减速次数的相关达到-0.72。这印证了一个经验:纯距离类指标覆盖不了行为安全,急减速频率这种“驾驶风格味十足”的指标才是教练最敏感的线索。因此映射方法上,我建议用加权组合来拟合主观分:
主观分估计值 ≈ a × 平顺性分 + b × 风险裕度分 + c × 决策合理性分
三个分量要独立计算。平顺性分用纵向加速度的RMS和冲击度(加速度的导数)统计,RMS越小越平顺;风险裕度分用TTC小于4秒的时间占比、TTC的5%分位数来构造;决策合理性分则看变道触发点与相对速度趋势的一致性,若相对速度持续为负时仍然变道,决策合理性显著下降。
权重a、b、c可以先做线性回归拟合一版,但回归系数在不同场景下漂移明显。雨天和夜间的主观分普遍压低,单纯拟合会把天气因素混进权重。我一般改成分层回归,晴/雨、昼/夜各标定一组权重,再用熵权法校验指标离散度,避免某个指标的权重被一台车的重复行为带偏。这一层是玄学最多的地方,多做几组交叉验证,别信一次拟合的结果。
2.3 权重标定:层次分析法与熵权法的组合使用
权重标定是整个评价体系里最容易被质疑的环节。层次分析法的优势是可解释,能交给专家拍板,缺点是专家打分的一致性检验经常不过关,尤其指标一多,判断矩阵的一致性比率就爆表;熵权法的优势是完全由数据驱动,缺点是某一维度数据波动异常时,权重会跑到奇怪的位置,比如一次极端刹停把急减速指标的熵拉低,权重虚高。
我在项目里的做法是两种方法结合。先用层次分析法得到初始权重向量,再用熵权法计算信息熵权重,最终权重取两者的几何平均。几何平均的好处是任何一项权重都不会归零,也不会出现某个指标权重超过0.5的失控情况。在模拟项目X里,最终权重大约是操作层0.4、决策层0.35、规划层0.25,具体到指标,TTC低占比和急减速频次各占约0.12。
权重标定完成后必须做一次敏感性检查。方法很简单:把某个指标的最小值强制替换成它的5%分位数,看总分偏移是否超过0.6分(10分制)。超过就说明该指标对异常值太敏感,需要先做截尾处理再进模型。这一步看起来笨,但能提前发现大部分评价体系的木桶短板。处理截尾时要注意,边界值按场景差异分开设置,高速场景的TTC截尾点和城市场景不能共用,否则城市工况会被高速标定的尺度压死。
3. ODD边界与场景提取:评价必须在限定域内才有意义
3.1 ODD参数化:机器可读的结构化定义
ODD(Operational Design Domain,设计运行域)是行为安全评价的地基。最常见的前提性错误就是拿ODD外的数据去评价ODD内的行为。比如系统设计只覆盖双向四车道城市道路,你却拿高速匝道的数据去测变道评价,结果没有任何意义,因为系统的设计目标和感知配置都不一样。
ODD至少要参数化成这几个维度:道路等级、车道数、车道宽度、道路曲率半径、限速值、光照条件、天气条件、GPS信号质量、交通参与者密度。每个维度都要有明确的边界值和单位,不能写“城市道路”这种程序没法判断的描述。和测试工程师约定边界时,最怕的就是文档里写“良好天气”,量化之后必须落到“能见度大于200米且无降水”。
结构化实现我用YAML,方便人工查看和改动边界,也方便版本管理。一个简化的ODD定义如下:
odd_boundary: road_level: ["highway", "urban_arterial"] lane_count: min: 2 max: 4 lane_width_m: min: 3.0 max: 3.75 curvature_radius_m: min: 150 speed_limit_kph: min: 40 max: 80 illumination: ["day", "twilight", "night_with_road_light"] weather: ["clear", "light_rain"] gps_quality_threshold: 1.2 traffic_density_limit_per_km: 40每个维度在评价前都要做一次逐项匹配检查,任何一项超出边界,对应的数据片段直接标记为OutOfODD,不进安全评价管道,单独进边界表现分析流。这个开关设计能省掉大量无效争议——当有人说“这个片段分数很低”时,先查ODD标签是否是OutOfODD,是的话压根不进最终统计。
3.2 危险片段筛选:从长日志里切出有效评价单元
有了ODD限定,接下来要从连续测试日志里切出评价片段。不能把一条三小时的路测数据整体打分,那样只有一个总分,出了问题根本定位不到行为。我一般按事件和时间窗口双维度切分。
事件维度包括:前车切入、本车变道、前车急刹、路口汇入、行人横穿。时间维度则是在事件前后各外扩固定时长,形成10到15秒的评价窗口。如果两个事件间距小于预设间隔,就把它们合并成一个复合窗口,避免重复计算。切分代码用Pandas处理时间序列很容易实现:
def split_evaluation_windows(events, data, pre=5.0, post=10.0, min_gap=15.0): windows = [] current_start, current_end = None, None for ev in events.sort_values("ts"): start = ev.ts - pre end = ev.ts + post if current_start is None: current_start, current_end = start, end elif start <= current_end + min_gap: current_end = max(current_end, end) else: windows.append((current_start, current_end)) current_start, current_end = start, end if current_start is not None: windows.append((current_start, current_end)) return windows这段逻辑的关键是min_gap参数。设成15秒是为了避免同一段连续风险被切碎,否则急减速频率会被人为夸大。实际路测数据里,前车急刹后5秒内驾驶员往往还会补一次刹车,事件系统可能记成两条,合并成单个窗口后评价结果更接近人的真实感受。pre和post的取值也有讲究:pre取5秒是为了覆盖决策反应时间,post取10秒是为了完整观察行为恢复过程,窗口太短会截断变道后果,窗口太长则会把无关的巡航特征混进来。
3.3 场景复杂度量化:保证不同测试片段可比
不同片段的难度差异不量化,横向对比就是在耍流氓。同样是城市跟车,一个片段车流密度低、另一个片段有连续切入车辆,后者的风险指标必然更差,但这不代表系统的行为更不安全,只能说明场景更难。
我处理这个问题的方式是给每个窗口打一个复杂度标签,用三个子项线性组合:交通密度系数,基于窗口内目标车平均数量;切入事件系数,基于单位时间切入次数;道路结构系数,基于是否有路口、弯道、匝道。复杂度分数用于事后分层统计,不直接混入行为安全总分。这样评价报告里可以按简单、中等、复杂三档分开呈现,验收会上争议会小很多。
实际操作时,复杂度标签的权重不追求精确,它的作用是分层对比而不是精确度量。测试样本足够多时,按复杂度分档分别计算每档的平均行为分和分位数区间,报告会清晰很多。这里有个硬性约束:复杂度划分阈值一旦确定,同一批次测试不能中途修改,否则回归对比全部失效。我在项目里吃过这个亏,后来把阈值表固定进配置文件,任何改动走评审流程。
4. 评价算法实现:从安全距离模型到特征融合打分
4.1 瞬时风险计算:TTC与Berkeley安全距离模型的差异
行为安全评价的核心算法层,第一步就是选对风险度量模型。TTC是最经典的时间类指标,定义是本车与目标相对距离除以相对速度,但它在实际数据里有一个明显的坑:相对速度接近0时TTC趋近无穷大。前车与本车几乎同步巡航、跟车距离很近的时候,TTC算出来几百秒,完全无法反映贴车跟驰的风险。
所以我在实际项目里把TTC当作辅助指标,主风险度量改用安全距离模型。Berkeley模型的思想是:若前车以某个紧急减速度急刹,本车经过反应时间后以最大制动减速度全力刹车,能停下来而不追尾,则当前距离是安全的。模型为每个时刻计算临界距离:
def berkeley_critical_distance(v_ego, v_front, a_max_brake=6.0, reaction_time=1.2): d_brake = (v_ego ** 2) / (2 * a_max_brake) d_reaction = v_ego * reaction_time d_front = (v_front ** 2) / (2 * a_max_brake) return d_reaction + d_brake - d_front参数a_max_brake按该车型主动安全系统的最大制动能力设,我一般取6m/s²,这是普通乘用车在不触发稳定性控制的前提下比较合理的紧急制动上限。reaction_time是系统响应时间加成,量产系统通常取1.0到1.5秒,L4级验证平台如果取到2秒,会明显高估风险,因为实际系统反应比人快。临界距离算出来后,用传感器实测距离减去临界距离,得到安全裕度DS,DS大于0视为有裕度,小于0进入风险区。DS是负数时评分不能线性下降,我用负指数函数做归一化,让评分对近距离风险更敏感,因为从工程经验看,DS从-1米恶化到-5米的风险增加程度远大于从1米恶化到-3米。
4.2 驾驶行为特征提取:把纵向、横向、频次信息压成特征向量
评价窗口切好之后,每个窗口要算一组统计特征,这是评价模型输入的基础。纵向特征包括:平均THW、THW小于2秒的时间占比、TTC最小值与10%分位数、急减速次数(减速度大于3m/s²)、加速度RMS;横向特征包括:车道偏移标准差、转向角速度90%分位、横向加速度峰值。
统计窗口长度直接影响结果,我踩过坑:用整条30秒窗口算RMS,一次极端抖动会被30秒的优秀表现稀释掉。后来改成先按1.5秒子窗口计算基础统计量,再对子窗口序列做分位数聚合。这样高频波动和极端事件都能被捕捉,加窗特征提取代码大致是这样:
def extract_window_features(ts_data, sub_window=1.5): features = {} rms_list, jerk_list = [], [] for start in np.arange(0, ts_data.duration, sub_window): sub = ts_data.slice(start, start + sub_window) rms_list.append(np.sqrt(np.mean(sub.long_acc ** 2))) jerk_list.append(np.mean(np.abs(np.diff(sub.long_acc)) / np.diff(sub.time))) features["acc_rms_p90"] = np.percentile(rms_list, 90) features["jerk_mean"] = np.mean(jerk_list) features["thw_lt_2s_ratio"] = (ts_data.thw < 2.0).mean() features["ttc_min"] = ts_data.ttc.min() return features特征计算时注意单位一致性,速度全部换算成米每秒,距离用米,时间用秒。acc_rms_p90取的是子窗口RMS序列的90%分位,比整窗口RMS更能还原密集加减速工况下的平顺性恶化程度。thw_lt_2s_ratio是跟车时距小于2秒的占比,这个指标在城市通勤场景里波动很大,单看一帧的THW没有意义,占比才是稳定特征。
4.3 融合评价:规则打分与异常检测的交叉验证
评价总分不能直接对特征做线性加权,原因很简单:不同特征的分布差异太大,线性加权会被量纲最大的特征主导。我的框架是三层结构:第一层规则打分,把每个特征通过分段函数映射到0到1的子分;第二层异常检测,用Isolation Forest找出特征组合异常的窗口;第三层融合,规则分正常但异常检测标记的窗口降权处理,规则分差且异常的窗口直接挂起人工复核。
from sklearn.ensemble import IsolationForest def evaluate_window(features, rule_score): clf = IsolationForest(contamination=0.05, random_state=42) anomaly_score = clf.fit_predict(features.reshape(1, -1)) if rule_score < 0.3 and anomaly_score == -1: return "needs_manual_review" elif rule_score < 0.3: return "unsafe" elif anomaly_score == -1: return "risk_unknown" return "safe"这段代码的价值在于把规则判死和特征组合异常分开处理。contamination参数表示预期异常比例,我一般设0.05,也就是约5%的窗口会被标为异常。设太高会把正常激进驾驶全部打入异常,测试车性能好的时候误报成片;设太低又漏掉组合型风险,比如某次测试里所有单项特征都在正常区间,但转向角速度的90%分位和车道偏移标准差同时偏高,这种组合异常单规则查不出来。用项目数据反复调参时,random_state固定下来,回归测试才能稳定复现。
5. 排查与避坑:行为安全评价项目里五个高发问题
5.1 现象:评价结果与主观感受严重背离
项目开发后期经常遇到一个情况:客观算法给某个片段打出8分,驾驶教练看完回放直接给了4分。第一反应可能怀疑算法,但说实话,问题出在指标优先级上。
原因在于主观评分关注的是预期风险,就是“我当时觉得就要出事了”这种感觉;客观指标算的却是瞬时物理风险,THW还有2秒的时候算法认为很安全,但教练看到驾驶员在这种间距下还分神看中控屏,主观分已经降到及格线以下了。
解决方法是把决策层指标放在前面,操作层指标放后面。先评价变道意图和时机是否合理,再去看方向盘打得顺不顺。也就是主观参考系先对齐决策质量,操作层指标只做降级因子,不在第一层参与总分判定。
5.2 现象:换一条测试路线评分差异巨大
同一台车、同一套系统,从环线换到老城区,平均行为安全分从7.8掉到5.2。测试团队第一反应是系统在城区表现差,但我查了复杂度标签后发现,环线路段的车流密度和弯道占比远低于老城区,完全不在一个难度档位。
原因是路线差异导致指标分布整体偏移,跟车时距在城区自然变小,急减速频次自然变高,拿低速拥堵数据跟高速顺畅数据直接比总分,必然失真。
解决方式是先按场景复杂度分档,再在档位内做归一化。所有指标用该档位测试数据的分位数做基准,把原始值映射到0到1的档内相对分数。报告里同时展示绝对分数和档内相对分数,验收会议上争议会小很多。
5.3 现象:ODD越界后的评价分数异常跳变
某次回归测试里发现,车辆正常行驶时评分突然从8分跳变到3分,持续几秒后又恢复。拉出数据一看,车辆并没有真正出ODD,是GPS信号在立交桥下短暂失锁,定位误差瞬时增大,被ODD检查逻辑判定为越界。
原因是ODD状态是逐帧二值判断的,没有做时间维度上的滤波,一帧信号异常就触发状态翻转。
解决方法是给ODD状态加滞回判定:连续3秒识别为越界才真正切换为OutOfODD,连续3秒回到边界内才切换回来。这个滞回时间要跟系统接管请求延迟匹配,不能太短也不能太长,我一般用3秒,既能滤掉瞬时毛刺,又不会掩盖真实的短暂脱域。
5.4 现象:数据时间戳不同步导致特征错位
融合评价时发现,同一时刻的TTC和加速度数值逻辑矛盾:TTC显示1.8秒,但本车正在加速远离,怎么算都对不上。排查半天,是摄像头、毫米波雷达、惯性单元各自时钟独立,毫秒级偏差在特征计算里被放大。
原因是多传感器数据到达记录模块的延迟不同,有些是事件触发上报,有些是周期上报,不做时间对齐就直接算特征,必然错位。
解决方式是统一时间基准。我的做法是选惯性单元的时间戳作为主时钟,因为它的频率最高,然后对摄像头和雷达的目标级数据做线性插值对齐,再计算TTC和THW。对齐窗口要记录在日志元数据里,方便复盘时追溯。
5.5 现象:轻量模型在夜间场景失效
夜间测试结果显示评价分数比白天整体低了两分,一开始以为是系统夜间驾驶行为确实更保守,但逐项排查发现,夜间视觉检测的置信度普遍偏低,目标车辆数被低估,导致交通密度系数计算失真,TTC也偏大,评价模型被喂了错数据。
原因是评价模型直接消费了感知输出,没有把感知置信度作为输入条件,低置信度场景下目标漏检和误检都会污染特征。
解决方法是给夜间和雨雾场景单独标定参数,感知置信度低于阈值时把相关特征标记为低质量,评价权重降为正常工况的一半而不是直接丢弃。保留低质量片段很重要,它们恰好是主动安全最该关注的场景。
6. 回归验证与影子模式:让评价方法在迭代中不被推翻
6.1 影子模式:旁路验证不打断实车流程
评价方法上线只是开始,真正的考验是后续系统迭代时,分数还能不能说明问题。我在项目里沉淀了两套机制,第一套是影子模式。所谓影子模式,是把评价算法挂在真实数据旁路,实时计算每个窗口的行为安全分,但不参与车辆控制。算法更新后先跑一周影子模式,产出一份分数分布快照。关键不是看平均分涨多少,而是看分布形态有没有变化。原本集中在7到9分的分布突然变成双峰,先不要高兴,大概率是某个边界条件被改坏了,而不是驾驶水平真的提升了。
6.2 回归测试集:分数变化超过0.5分必须人工回看
第二套机制是回归测试集管理。我固定维护一组历史片段,包括危险片段、正常巡航片段、ODD边界片段和传感器降级片段,每次评价模型更新必须在这些片段上重跑,把新旧分数并排列在表里。任何片段分数变化超过0.5分,要逐帧回看确认合理性。这套测试集规模不用大,五六十个片段足够覆盖主要风险类型。
从项目中期开始,我给自己定了一条硬规矩:无论看起来多小的参数改动,都强制走回归测试集,然后抽三个变更最大的片段写说明。这条习惯帮我避开了至少三次模型漂移事故,也让我在评审会上敢说这次改动是安全的。整套流程连同YAML模板、特征脚本和回归片段清单都整理进了资源包,拿去做评价基线可以直接用。希望帮到你。
本文还有配套的精品资源,点击获取