
这两年智能驾驶开发圈里AEB自动紧急制动基本成了ADAS入门必做的项目。学校里做课题、企业里做预研、甚至个人想搞一套完整的仿真验证链路都绕不开Carsim与Matlab/Simulink这套组合。我最初接触这个方向的时候也踩了不少弯路要么只顾着调算法参数要么一头扎进Carsim的车辆模型里出不来真正把联合仿真跑通、把AEB逻辑闭环调稳花的功夫远比想象中多。这篇就把我做“基于Carsim与Matlab Simulink的AEB联合仿真算法设计”这套模块化建模方案的完整过程拆开讲从架构思路到算法实现、从接口配置到工况测试全部梳理出来给正在做联合仿真或者准备入坑AEB的朋友一个可直接复现的参考。先交代一下这个方案解决的痛点。AEB算法开发不能只停留在纯数学推导层面车辆在紧急制动时的俯仰、轮胎滑移、制动系统响应延迟都会直接影响碰撞距离和减速度表现。如果只用简单的运动学模型算出来的TTC和制动距离往往偏乐观落地到实车就会出问题。Carsim提供高保真车辆动力学响应Simulink承载AEB算法逻辑两者联合起来才能在仿真阶段就把动力学边界吃透。这也是为什么我坚持用联合仿真而不是纯Simulink建模的核心原因。1. 为什么必须联合仿真Carsim与Simulink的分工逻辑1.1 AEB算法开发的仿真需求到底在哪AEB系统的核心任务是在检测到前方碰撞风险时通过主动制动避免碰撞或减轻碰撞后果。这个任务听起来就是“距离近就刹车”但真正实现起来算法需要同时处理感知输入、危险评估、执行决策三个层面的问题。感知输入层面需要融合目标车辆的距离、相对速度、相对加速度等信息危险评估层面要在“过早制动造成误触发”和“过晚制动导致刹不住”之间找到平衡执行决策层面要有明确的减速度请求输出给车辆制动系统。这三个层面单独看都不复杂但它们共同依赖一个关键前提——车辆在当前车速、当前路面条件下的真实制动响应是多少。这就是Carsim的意义所在。Carsim内置了车身、悬架、轮胎、制动系统、转向系统等详细的动力学模型能给算法提供一个接近真实的“被控对象”。我在实际测试中对比过给同一个AEB算法分别接Carsim车辆模型和接简化运动学模型同样的初始车速和距离最终碰撞结果完全不同。Carsim模型里制动减速度会随着车速下降而衰减轮胎附着力有边界制动系统有响应延迟这些细节直接决定了算法触发的边界条件要不要留安全余量。1.2 模块化建模的核心价值很多人在Simulink里开发AEB算法时习惯把所有逻辑堆在一个大子系统里信号线拉得密密麻麻。这种方式在单工况调试时勉强能跑但一旦要扩展传感器模型、切换控制策略、复现不同车型参数就会陷入“改一处动全身”的泥潭。我采用的模块化建模方式是把整个算法拆成四个独立层次感知输入层、危险评估层、决策执行层、参数标定层。每个层次有明确的输入输出接口层与层之间通过Simulink总线信号交互。这样做的好处有三个第一可替换性强。感知输入层以后要接真实雷达数据或者换成毫米波雷达模型只改这一层就行危险评估和决策执行不需要动。第二标定效率高。所有阈值参数统一集中在参数标定层用结构体管理。测试不同工况时直接改标定文件不用打开模型逐个查找。第三团队协作方便。不同层次可以由不同人并行开发只要接口定义清楚最后集成时的冲突会少很多。这套模块化思路我后来用在不同项目里也都成立。AEB只是起点这套架构往FCW、ACC方向扩展只需要替换危险评估层或者决策执行层的部分模块整体框架完全能复用。2. AEB算法核心TTC计算与分级制动策略2.1 TTC的计算与触发逻辑AEB算法中最核心的危险评估指标是TTCTime to Collision碰撞时间。它的原始定义是当前相对距离除以相对速度TTC D / VrelD是本车与前车的相对距离Vrel是本车相对前车的速度本车更快时为正。这个公式直观、计算量小是AEB算法的基础。但我实测下来直接用这个原始公式在真实场景中误报率偏高原因在于它假设相对速度恒定没有考虑本车加速度和前车加减速的影响。实际项目中我更推荐使用考虑加速度修正的TTC形式TTC Vrel / (Arel) sqrt((Vrel/Arel)^2 2D/Arel)其中Arel是相对加速度。这个公式在相对加速度不为零时更准确但要注意当Arel接近于零时计算会发散必须在代码里加保护条件。我在模型里用一个Switch模块判断|Arel|小于某个阈值时回退到原始公式这样既保证稳定性又不牺牲精度。TTC的触发逻辑需要结合车速分档处理。低速工况比如低于30km/h和前车静止系统反应时间相对充裕可以在TTC较小时触发高速工况下制动距离更长需要在TTC较大时就提前介入。我的做法是设计两套阈值——预警阈值和制动阈值分别对应FCW功能前方碰撞预警和AEB主动制动。2.2 分级制动策略与舒适性平衡AEB不是一上来就全力制动。粗暴的全制动虽然碰撞概率最低但会给驾乘人员带来强烈的冲击感也会让后车追尾风险上升。合理的策略是分级制动。我在这个项目中设计了三段式制动策略第一级是预警阶段。TTC达到预警阈值后系统先输出声音报警信号同时施加一个极小的预填充制动压力比如0.2MPa目的是消除制动间隙为后续制动做准备。这一级不产生明显减速度驾乘人员几乎感知不到。第二级是部分制动阶段。TTC继续缩短达到部分制动阈值后系统按照标定好的减速度曲线进行部分制动。减速度一般控制在2.5到4m/s²之间这个区间既要保证明显的减速效果又不至于让车辆姿态发生剧烈变化。第三级是全力制动阶段。当TTC进入紧急区域且驾驶员仍然没有接管迹象时系统输出最大制动减速度请求。这里要注意最大减速度受到路面附着系数的限制。干燥沥青路面可以请求7到8m/s²但湿滑路面如果把请求值拉满车轮会抱死反而延长制动距离。为了解决这个问题我在决策执行层集成了路面附着系数估算模块。一种实用的做法是利用ABS轮速信号和车身参考车速的差值估算滑移率再根据滑移率反推当前路面的峰值附着系数然后限制最大减速度请求。这套逻辑在Carsim里验证效果很好仿真中设置湿滑路面工况后AEB依然能在不抱死的前提下尽可能缩短制动距离。2.3 用Simulink快速实现AEB状态机AEB的逻辑具有明显的状态迁移特征无风险、预警、部分制动、全力制动、碰撞后解除。用Stateflow实现状态机比纯逻辑判断清晰得多。我的状态机设计如下State 0: Idle无风险 条件: TTC TTC_WARN || Vrel 0 动作: 输出无制动请求 State 1: Warning预警 条件: TTC TTC_WARN TTC TTC_PARTIAL 动作: 输出报警信号预填充压力 State 2: PartialBrake部分制动 条件: TTC TTC_PARTIAL TTC TTC_FULL 动作: 输出部分减速度请求并随时间递增 State 3: FullBrake全力制动 条件: TTC TTC_FULL 动作: 输出最大减速度请求受附着系数限制 State 4: Release解除 条件: Vrel 0.5 m/s 且相对距离开始增大 动作: 解除制动这个状态机的关键细节是State 2向State 3的转移一定要快。部分制动阶段如果持续时间过长实际车速已经下降很多TTC的变化速率会比预期慢全力制动的介入时机就晚了。我在这里用了一个持续计数器当TTC持续低于部分制动阈值超过200ms就立即转移防止信号抖动造成状态来回跳。另外State 4解除条件不能只看TTC。如果本车已经刹停但前车在缓慢移动TTC可能仍然很小但继续制动已经没有必要。所以解除条件要加上“相对距离开始增大”这条确保碰撞已经规避。3. 模块化Simulink模型搭建实录3.1 接口定义Carsim输入输出变量的映射关系联合仿真的核心是搞清楚Carsim和Simulink之间的数据流方向。Carsim作为被控对象接收Simulink发出的控制指令Simulink中的AEB算法接收Carsim反馈的车辆状态。我习惯把Carsim的输入输出变量定义成一个接口表固定下来了再动模型。典型配置如下信号方向变量名含义单位Simulink - CarsimIMP_BRK_MASTER_CYL_PRESSURE制动主缸压力请求MPaSimulink - CarsimIMP_THROTTLE_ENGINE节气门开度通常置0percentCarsim - SimulinkVx_SM纵向车速km/hCarsim - SimulinkAx_SM纵向加速度m/s²Carsim - SimulinkStation_X_SM本车纵向位置mCarsim - SimulinkYaw_Rate_SM横摆角速度rad/sCarsim - SimulinkSteer_LF_SM前轮转角deg这里有一个非常容易踩的坑Carsim的输出车速默认是km/h而Simulink中的TTC计算需要m/s单位不一致会导致距离计算结果差3.6倍。我第一次联调时TTC算出来始终偏大排查了半天才发现是单位问题。现在我的做法是在Simulink输入端口后统一加一个单位转换模块把km/h转成m/s后续所有计算都用国际单位制。另外一个要注意的是制动压力的接口。Carsim的制动模型接受主缸压力作为输入但AEB算法计算出的通常是减速度请求中间需要做一次转换。转换公式为P_brake a_request * m_vehicle / (K_brake * BRK_EFF)其中P_brake是主缸压力a_request是减速度请求m_vehicle是整车质量K_brake是制动效能系数BRK_EFF是制动效率。这些参数都放在参数标定层中通过Carsim的车辆参数读取不写死。3.2 感知层、决策层、执行层的解耦设计感知层在真实车辆中对应的是毫米波雷达或激光雷达输出。在仿真环境中我直接使用Carsim输出的目标车辆信息在Carsim中配置跟随前车场景时会输出前车位置、速度等加上一个理想传感器模型模块。理想传感器模型的意义在于模拟信号延迟和噪声。实际雷达的测量周期一般是50ms数据还有高斯噪声。在感知层中加入一个Transport Delay模块延迟50ms和Band-Limited White Noise模块这样AEB算法在仿真中就能提前暴露真实传感器带来的问题。我测试过不加噪声时TTC计算曲线非常平滑加上噪声后触发时刻会有几十毫秒的抖动这直接影响了不同的延误和误报概率。决策层是AEB算法的核心包含TTC计算模块、危险评估状态机和制动策略生成模块。这一层只接受感知层的处理结果不直接读取Carsim的原始信号。感知层输出的目标距离、相对速度已经经过滤波和单位转换决策层的职责就是纯粹的逻辑判断。执行层负责把决策层输出的减速度请求转换为Carsim可接受的指令信号并加上斜率限制器。斜率限制器很关键如果减速度请求直接从0跳到8m/s²车辆模型会出现明显的俯仰震荡这在实车上会严重损害乘坐舒适性。我设置的默认斜率为5m/s³即从0加速到8m/s²需要1.6秒。在紧急工况下可以放宽到8m/s³但不能再高。3.3 参数标定层的设计思路参数标定层不参与实时计算它只是一个包含所有可调参数的Simulink结构体参数空间。我的做法是在模型初始化回调函数中加载一个.m文件里面定义各种参数% AEB参数定义文件 % —— 基础参数 veh.mass 1700; % 整车质量 kg veh.brakeEff 0.8; % 制动效率 % —— TTC阈值参数 aeb.TTC_WARN 2.8; % 预警TTC阈值 s aeb.TTC_PARTIAL 1.8; % 部分制动TTC阈值 s aeb.TTC_FULL 0.8; % 全力制动TTC阈值 s aeb.MIN_VREL 2.0; % 最小相对速度阈值 m/s % —— 制动请求参数 aeb.a_partial 3.0; % 部分制动减速度 m/s^2 aeb.a_full 8.0; % 全力制动减速度 m/s^2 aeb.a_rate 5.0; % 减速度斜率 m/s^3 % —— 传感器参数 sens.radarPeriod 0.05; % 雷达周期 s sens.radarDelay 0.05; % 雷达延迟 s sens.noiseSigma 0.1; % 测距噪声标准差 m这样设计的好处非常明显标定工程师不需要打开Simulink模型不需要懂算法逻辑只需要改.m文件里的数值就能调整AEB系统的表现。我做的某次测试中要把同一套算法从轿车适配到SUV车型只改了整车质量和制动效率两个参数模型结构完全没动。这里还要提醒一个细节参数命名要带模块前缀。aeb开头的参数属于危险评估层sens开头的属于感知层veh开头的属于车辆参数。这样在模型里看信号线标注时一眼就能看出参数来源排查问题时不会混乱。4. Carsim与Simulink联合仿真配置与工况测试4.1 Carsim S-Function的生成与配置Carsim和Simulink联合仿真的标准方式是生成S-Function。具体步骤是第一步在Carsim中建立或选择车辆模型配置好仿真工况包括本车初始车速、目标车辆状态、路面附着系数等。第二步选择Simulink联合仿真接口Carsim会生成一个包含S-Function的Simulink模型模板这个模板里面预设了输入输出变量映射。第三步把Carsim生成的S-Function模块复制到自己搭建的AEB模型里替换掉原来的车辆数学建模部分。保持接口名一致算法模型不用做任何修改。这里有一个关键配置项——S-Function的采样时间。Carsim的内部仿真步长一般设置为0.001s但S-Function模块在Simulink中的采样时间可以设置得更大比如0.01s。我建议保持Carsim内部步长不变Simulink中S-Function采样时间设置为0.01s或0.005s这样仿真速度与精度比较平衡。注意Simulink的主步长必须与S-Function采样时间匹配否则会产生代步误差。还有Carsim的模型文件路径不能包含中文和空格。这个坑我已经踩过很多次一旦路径有问题S-Function初始化就会报错而且报错信息往往不直接提示路径问题排查起来很折磨。现在我的项目目录一律用英文小写加下划线命名。4.2 测试工况选择与测试矩阵AEB算法验证不能只跑一种工况。按照行业标准里的测试场景要求至少要覆盖三类目标车状态和多个车速组合。我整理的测试矩阵如下工况编号本车初始速度目标车状态路面条件预期结果TC-0130 km/h静止干燥沥青完全避免碰撞最小距离 0TC-0250 km/h静止干燥沥青完全避免碰撞最小距离 0TC-0380 km/h静止干燥沥青完全避免碰撞或碰撞速度 10 km/hTC-0450 km/h匀速 20 km/h干燥沥青完全避免碰撞不与前车距离小于0.5mTC-0580 km/h匀速 40 km/h干燥沥青完全避免碰撞最小相对距离 1mTC-0650 km/h减速 8m/s²干燥沥青完全避免碰撞TC-0750 km/h静止湿滑沥青避免碰撞或碰撞速度尽量低TC-0830 km/h静止冰雪路面避免碰撞或碰撞速度尽量低每个工况至少重复三次仿真对比结果的一致性。Carsim的仿真本身是确定性的但加入传感器噪声后每次仿真的触发时刻会有细微差异这正好可以验证算法的鲁棒性。4.3 数据记录与结果分析在Simulink中我通过Signal Logging记录关键信号TTC计算值、AEB状态、制动压力请求、本车速度、本车加速度、相对距离、碰撞指示标志。仿真结束后用一个简单的脚本自动生成指标报告% 指标计算脚本摘要 % 1. 最小相对距离min(relDist) % 2. 碰撞速度如果 relDist 0取碰撞时刻本车速度 % 3. 最大减速度max(abs(a_request)) % 4. AEB介入时刻state从Idle变为Warning的时刻 % 5. 制动距离从AEB介入到车速为零行驶的距离实测下来TC-02工况50km/h对静止目标车的结果最有代表性。在干燥沥青路面AEB从预警到全力制动介入的时间大约0.9秒最小相对距离保持在25厘米左右最大减速度约8.4m/s²整个制动过程车辆无抱死现象。TC-07工况50km/h对静止目标车湿滑路面则展示出路况修正的作用如果没有附着系数限制算法会请求8m/s²的减速度车轮很快抱死车辆进入滑移状态实际减速度只有4m/s²左右最终碰撞速度达到15km/h加入附着系数修正后算法把请求减速度限制在4.5m/s²以内车辆全程处于稳定制动区间碰撞速度降低到8km/h。这就是为什么我说“最大减速度”参数绝对不能写死。5. 联调常见问题与避坑清单5.1 Carsim模型修改后Simulink不更新这是我遇到最多的问题。在Carsim中修改了车辆参数或工况回到Simulink重新运行结果仿真结果没有任何变化——这通常是因为Carsim的S-Function缓存没有刷新。解决办法是清理Simulink的缓存并重新生成S-Function。在Matlab命令行执行clear all; close all; clc; busyCounter 0; % 清理函数缓存 delete(findall(0,Type,block,Name,PPCarsim)) bdclose all;然后重新打开模型运行。另外一个常用技巧是在Carsim中重新点一次Send to Simulink按钮覆盖生成S-Function文件确认文件的时间戳是最新的。5.2 仿真步长不匹配导致结果抖动如果Simulink主步长与Carsim S-Function采样时间不匹配刹车压力曲线会出现锯齿状抖动TTC计算也会产生高频振荡。尤其是当Simulink使用变步长求解器时Carsim S-Function的固定采样周期可能与求解器自适应步长产生冲突。我最终使用的配置是Simulink求解器选择固定步长Fixed-step步长设为0.01sCarsim内部步长保持0.001sS-Function采样时间设为0.01s。这样在10ms的算法周期内Carsim已经完成了10次动力学计算精度足够仿真速度也在可接受范围。5.3 AEB频繁误触发在加入传感器噪声后AEB偶尔会在明显没有碰撞风险的情况下进入预警状态。排查后发现问题出在TTC计算时相对速度接近零的情况。当Vrel很小时TTC计算值会瞬间变成非常大的数或者变成负数导致状态机做出错误判断。解决方法是加入最小相对速度阈值判断当Vrel小于2m/s时认为不构成追尾风险不触发AEB。同时在状态机中引入持续条件确认——风险信号必须连续保持两帧40ms以上才触发状态迁移这样偶发的噪声尖峰不会引起误报。5.4 车辆模型制动响应滞后AEB算法计算出的减速度请求在Carsim车辆模型中大约有100到200ms的响应延迟这包括制动系统建压时间和制动器作用时间。如果算法不考虑这个延迟实际减速度曲线会比请求曲线滞后导致真实制动距离比理论值长。我的解决办法是在决策层中加入动态补偿模块。具体来说就是根据当前的制动系统状态预测实际减速度并以此预测值作为TTC计算的输入。这样计算出的TTC虽然略保守但更贴近实际制动结果。实测下来补偿后的系统在触发时机上提前了约0.15秒制动终点距离更充裕。6. 算法扩展方向与项目体会模块化建模的框架跑通后AEB只是起点。我在同一个框架上扩展过两项功能第一项是加入FCW与AEB的联合联动。FCW在更早的TTC阈值下预警同时预留驾驶员接管判断窗口——如果驾驶员在预警后的1.2秒内踩下制动踏板AEB自动退出把控制权交还给驾驶员如果没有接管动作AEB才自主介入。这套逻辑在Simulink中实现起来非常方便因为状态机框架已经搭好了。第二项是ACC自适应巡航与AEB的协同控制。ACC负责跟车巡航AEB负责紧急避险两者共享感知层和车辆接口层区别只在决策层的控制目标不同。ACC用PID控制期望车速与车距AEB用TTC控制碰撞规避。把这两套逻辑模块并联在决策层里根据工况优先级做仲裁整个系统的架构没有改变只是多了一个仲裁模块。最后说一点个人体会AEB联合仿真的难点从来不在算法公式本身而在于把各层模块边界划清楚、把各接口参数定明白。很多同学做项目时喜欢一开始就打开Simulink拖模块结果做到一半发现接口不统一、单位不一致、参数散落在模型各处改起来焦头烂额。我自己也经历过这个阶段后来养成了先画接口表、先写参数文件、先设计状态图、最后才动手搭模型的习惯效率高了很多。这套方法论不管你是做课题、做量产预研还是个人学习都值得参考。希望这篇内容能帮你少踩几个坑把精力真正花在算法设计本身。