资讯动态

基于CarSim与Simulink的三车纵向编队跟随联合仿真实践

发布时间:2026/10/20 7:04:18 来源:尧图企业网站定制
做车队纵向跟随仿真很多人一开始以为最难的环节是控制算法真正上手之后才发现CarSim和Simulink这对组合怎么在工程上配合起来才是第一个拦路虎。接口配置对不上、仿真步长不一致、变量映射混乱任何一个小问题都能让整个模型直接跑不起来算法再漂亮也没有用武之地。我这次做的是一套三车纵向编队跟随仿真环境核心目标是让后车在前车变速时保持安全车距同时做到速度跟踪和间距收敛。整个过程从控制策略选型、联合仿真环境搭建、上下层控制器实现到最后的调试和参数整定都有不少值得记录的经验。这篇文章就把完整探索过程展开聊一聊包括每一步为什么要这么做、关键细节怎么处理、以及我在实际调试中踩过的坑给正在做这个方向的朋友一个可以直接参考的路径。如果你之前只做过单车模型仿真或者对CarSim比较陌生也不用太担心我会把那些容易踩坑的配置环节讲得尽量细一点。1. 车队纵向跟随的控制思路与方案选型1.1 车队纵向跟随到底在解决什么问题车队纵向跟随这个问题本质上可以拆成两个层面看。一个是单车自适应巡航层面也就是每辆车都要能根据前车的运动状态自动调节节气门和制动踏板维持期望的车间距另一个是多车协同层面车队中的每一辆车都要以队列整体为控制目标既要跟踪自己的前车又要保证整个队列的稳定性避免出现“源头一个小小的波动越往后传递越剧烈”的放大效应也就是车队串稳定性问题。纵向跟随控制的核心性能指标有三个间距误差、速度跟踪偏差和加速度冲击度。间距误差是实际车间距与期望车间距的差值直接决定了跟随安全性速度跟踪偏差衡量本车车速跟随前车车速的能力加速度冲击度关系乘坐舒适性——如果控制器输出忽大忽小即使间距误差能收敛车内人员的体感也会非常糟糕。这三个指标往往是互相制约的间距误差收敛太快意味着加减速度变化剧烈舒适性就会下降。所以控制参数的设计本质上是一个权衡过程不能只盯着某一个指标死磕。在我这次的仿真设置里车队结构是“一辆领航车加两辆跟随车”。领航车按照预设的速度序列行驶不需要接收控制指令跟随车通过实时获取前车状态信息和本车与前车的间距来计算控制量。这里的“状态信息”包括前车速度和前车加速度在纯仿真环境中这些信号可以认为是理想可得的不需要额外处理传感器延迟和噪声问题。但即便是这样的理想条件控制器参数没调好仿真照样会振荡甚至发散。这说明纵向跟随控制本身就是一个对参数比较敏感的问题不能指望随便一组增益就能跑出好结果。1.2 为什么选择CarSim加Simulink联合仿真做车辆控制算法验证仿真工具的选型是个绕不开的话题。一种做法是在Simulink里直接用简化的车辆纵向动力学模型用一阶惯性环节或者二阶传递函数来表示车辆从控制指令到加速度的响应。这个做法开发速度快、参数少、理论分析和控制器设计都很方便但缺点同样明显简化模型忽略了太多真实车辆特性比如传动系统的延迟、制动系统的响应滞后、轮胎力的非线性变化。算法在简化模型里表现很好换到真实车辆上往往差距很大。CarSim的优势在于它提供了高精度的整车动力学模型内置车身、悬架、转向、轮胎、制动等多个子系统可以比较逼真地模拟车辆在各种工况下的动态响应。使用的时候你只需要在CarSim界面里选定车型参数、设置道路环境和初始工况就能得到一个接近真实车辆的纵向动力学行为。所谓联合仿真就是用CarSim来替代那套简化的车辆模型把控制算法实现在Simulink中两者通过专用接口进行数据交换CarSim输出车速、加速度、位置等车辆状态Simulink输出节气门开度和制动压力等控制指令。这样既保留了Simulink在算法开发上的灵活度又保证了车辆底层动力学模型的真实性。我在几组对比测试里的感触挺深。同一套PID参数在三阶简化车辆模型里能收敛得挺好换到CarSim高精度模型上低速起步阶段就出现了明显的速度波动尤其是在油门刹车切换的瞬间响应特性差异非常大。这也是我坚持用CarSim联合仿真的原因——宁可前期搭建环境多花点时间也比算法在简化模型上看着完美、一到真实平台就露馅要强得多。1.3 控制架构怎么定分层控制是工程主流纵向跟随控制的架构工程上最常用的是分层控制方案把整个控制系统拆成上层控制器和下层控制器两个层级。上层控制器负责“策略层”的计算输入车队状态信息间距误差、相对速度等输出期望加速度下层控制器负责“执行层”的映射把期望加速度转换成具体的节气门开度和制动压力输出给CarSim车辆模型。很多刚接触这个方向的人会问能不能设计一个单层控制器输入间距误差直接输出油门踏板百分比一步到位理论上可以但工程上不太推荐。原因是油门制动到车辆加速度之间的映射关系受到车速、挡位、路面坡度、载重等多方面因素影响高度非线性直接一步映射的鲁棒性很差。分层控制的巧妙之处在于把“策略”和“执行”解耦上层可以放心使用线性控制理论来设计只要保证输出的期望加速度落在车辆物理能力范围内下层专注于处理非线性映射可以用查表、逆模型、拟合等多种手段来实现。上层控制器的具体选型我对比过PID、LQR和滑模控制。LQR需要建立车辆纵向误差的状态方程并求解Riccati方程理论完备但对建模精度要求高滑模控制对抗动和参数不确定性强但容易带来控制抖振需要额外设计边界层来缓解PID结构简单、参数物理意义明确、调试直观是工程中最容易落地的一种。考虑到我这次的主要目标是先把联合仿真链路完整跑通把高精度车辆模型对控制的影响看清楚PID作为第一版实现是性价比最高的选择。后续如果想做更深层的性能优化再换成MPC或滑模控制也不迟。2. 联合仿真环境搭建与关键配置2.1 CarSim与Simulink接口配置的第一步CarSim联合Simulink的配置整套流程里最关键的一步是搞清楚CarSim把车辆模型打包给Simulink调用的机制。CarSim车辆模型通常以一个S-Function的形式存在于Simulink中——你在CarSim图形界面里配置好的车型参数、道路信息和初始工况会被打包到一个模型文件夹中里面包含参数文件和仿真器接口文件。使用时在Simulink模型中放置一个CarSim S-Function模块把它当作一个高精度“车辆子系统”通过它的输入输出端口与你的控制逻辑进行数据交互。这一步最容易翻车的地方是版本兼容性。CarSim的版本和MATLAB版本之间存在特定的对应关系我最早搭建环境时就是因为版本不匹配导致S-Function一直编译失败。解决方式没什么技术含量但非常有效——在装环境之前先去CarSim官方文档里查版本兼容性表格把本地的MATLAB版本、Simulink版本和CarSim版本逐一核对尽量选用官方明确列出的组合。千万别想当然随便装这个环节出错之后的排查时间比提前查文档要长得多。另一个容易被忽视的点是系统里的C编译器。Simulink要编译CarSim的S-Function需要环境里有可用的C编译器这在Windows平台上尤其容易出问题。我遇到的情况是Simulink自动检测到了一个不兼容的编译器版本导致编译报错。解决方法是手动指定编译器或者安装一个与当前MATLAB版本匹配的工具链。这类问题属于典型的环境问题虽然不难解决但要是没经验光排查报错信息就能消耗好几个小时。2.2 多车车队在CarSim里的搭建方式搭建三车车队CarSim里的做法不是在一个模型里塞三辆车而是给每辆车分别建立独立的CarSim模型实例然后在Simulink层把它们组合成一个车队系统。每一辆车的CarSim模型都拥有独立的车辆参数文件、仿真配置和输入输出接口。这里“独立”二字非常重要——三辆车虽然在同一个Simulink模型中同步仿真但每一辆的数据文件和工作目录必须完全分开不能混用否则会出现数据串号的诡异问题。具体到我的项目里用的是“一员领航加两辆跟随”的配置方式。领航车不需要接收控制指令它按照预设的目标速度曲线行驶所以它的模型最简单——只需在CarSim里设置好速度跟踪目标即可。跟随车则需要完整配置控制接口CarSim的输入是节气门和制动压力信号输出是当前车速、加速度、位置等状态。跟随车的输出状态在Simulink中经过信号处理计算得到本车与前车之间的实际间距再送入控制器。这里有个细节必须提醒车辆位置信息的获取方式。CarSim输出的车辆位置通常是大地坐标系下的XY坐标如果前后车保持在同一条直线上行驶直接用欧氏距离计算车间距没问题。但如果车队行驶在弯道上就需要先换算到道路中心线坐标系下的弧长距离否则间距误差的计算会失真控制器的性能会受到直接影响。我在这次仿真中让车队走直线所以没有涉及这个问题。如果要做弯道跟随场景建议提前把曲线距离换算模块加进去不要事后补。在Simulink模型组织上我建议把每辆车的CarSim模块分别放在独立的子系统里然后用总线信号把速度、位置等状态汇聚起来。这样做最大的好处是方便排查问题——哪辆车的数据异常直接观察对应子系统的输出就能定位不需要在密密麻麻的连线里翻找。2.3 仿真步长设定与数据交互逻辑联合仿真里一个极易踩坑的环节是仿真步长的设置。CarSim内部的车辆动力学求解器通常采用变步长方式但Simulink需要一个固定的通信步长来推进整个仿真流程。我见过不少同学直接把Simulink求解器设置为变步长结果仿真要么慢得离谱要么出现莫名其妙的数值振荡。正确做法是在Simulink中把求解器设置为固定步长步长通常取1毫秒或2毫秒具体取值取决于你对控制精度的要求和仿真耗时的权衡。步长选小了仿真精度高、数值更稳定但计算时间明显增加步长选大了计算速度快但在控制量剧烈变化的瞬态工况下容易引发数值不稳定。这次我使用的是1毫秒固定步长三车模型跑完一次仿真大约在一分钟以内精度和速度都比较均衡。如果你的场景是几十辆车的大规模队列可以把步长放宽到2毫秒甚至5毫秒试一试在保证稳定的前提下换取效率。数据交互方面最关键的是保证输入输出端口的对应关系。CarSim的输入端口有默认定义顺序比如前几个端口通常对应转向、节气门、制动但你也可以在CarSim界面中修改端口的数量和排列方式。在Simulink侧每个CarSim S-Function模块的端口数量和顺序必须和CarSim内部配置完全一致。这个一致性检查是我每次新建模型必做的一步——端口对不上往往是“仿真根本跑不起来”的头号原因而且报错信息经常很模糊不仔细看根本看不出来是哪里的问题。3. 纵向跟随控制算法的实现细节3.1 上层控制器间距策略与PID设计上层控制器的设计第一步是确定期望间距的表达式。我采用的是工程中最常用的恒定车头时距策略期望间距可以写成d_des d0 h * v_f其中d0是车辆静止时的最小安全间距h是车头时距参数v_f是本车车速。这个策略的直观含义是车速越高期望保持的车间距越大为潜在的危险工况留出更多反应时间车速低时间距可以适当压缩有利于提高车队对道路空间的利用率。我这次取d0等于3米h等于1.2秒属于比较常规的设定。h的选取很有讲究太小时安全性不足太大时车队过于松散容易被其他社会车辆插入实际工程里一般取值在0.8秒到2秒之间。有了期望间距之后定义间距误差e_d d_actual - d_des以及相对速度v_rel v_f - v_leader。注意符号方向要保持一致我在最初实现时就把相对速度的符号搞反了结果控制器输出了完全相反方向的加速度第一次联调时速度差越来越大。PID控制器以这两个量作为主要输入输出期望加速度。我最终采用PD加积分修正的形式比例项驱动间距误差收敛微分项抑制相对速度的波动积分项用于消除残余的稳态误差。function a_des upper_controller(e_d, v_rel, Ts) % 上层PID控制器 % 输入间距误差e_d、相对速度v_rel、采样周期Ts % 输出期望加速度a_des persistent error_integral; if isempty(error_integral) error_integral 0; end Kp 0.7; % 比例增益 Kd 0.6; % 微分增益对应相对速度项 Ki 0.08; % 积分增益 error_integral error_integral e_d * Ts; error_integral max(-5, min(5, error_integral)); u Kp * e_d Kd * v_rel Ki * error_integral; a_max 2.5; a_min -4.0; a_des max(a_min, min(a_max, u)); end这段代码里有两个容易被忽略但很重要的细节。第一是积分限幅——如果没有限幅长时间的大误差会让积分项越积越大当误差方向改变时积分项需要很长时间才能“消化”掉导致系统出现明显超调甚至振荡。第二是期望加速度限幅——控制器不能输出超出车辆物理能力范围的加速度指令否则下层控制器饱和执行器进入非线性区整个控制性能会急剧恶化。从实际仿真数据来看纯PD控制下稳态间距误差大约在0.2米上下波动加入合适的积分项后可以压到接近零。这就是为什么PID虽然常被说“传统”在纵向跟随这类动态相对温和的问题上依然非常实用。3.2 下层控制器从期望加速度到节气门和制动上层控制器给出期望加速度之后下层控制器要把它映射成CarSim能够接收的物理执行指令。CarSim的节气门和制动输入通常以0到1之间的无量纲数值表示1代表全油门或最大制动压力0代表不动作。那么问题就变成了如何把a_des映射到合理的节气门和制动数值上。最直接的方法是采用逆纵向动力学模型。车辆纵向运动方程可以简化写成m * a F_drive - F_resist其中m是整车质量F_drive是驱动力或制动力F_resist是总的行驶阻力包含滚动阻力、空气阻力和坡度阻力。给定期望加速度a_des后先计算出需要的轮端力F_drive m * a_des F_resist然后根据传动比和车轮半径换算成发动机需求扭矩驱动工况或者根据制动系统特性换算成制动压力制动工况。我在这次仿真中用了分层近似映射当F_drive为正时将其归一化到节气门开度当F_drive为负时把减速需求归一化到制动压力。这个映射的精度不如完整的查表法高但联合仿真链路第一版完全够用而且实现逻辑非常清晰function [throttle, brake] lower_controller(a_des, v) % 下层逆纵向动力学子层控制器 m 1412; % 整车质量 kg g 9.8; f 0.015; % 滚动阻力系数 Cd 0.3; % 空气阻力系数 A 2.3; % 迎风面积 m^2 rho 1.206; % 空气密度 kg/m^3 F_resist m * g * f 0.5 * rho * Cd * A * v^2; F_drive m * a_des F_resist; if F_drive 0 F_max 7000; throttle max(0, min(1, F_drive / F_max)); brake 0; else F_brake_max 9000; throttle 0; brake max(0, min(1, -F_drive / F_brake_max)); end end一个非常值得注意的细节空气阻力项包含车速的平方所以在高速巡航工况下即使期望加速度为零节气门也需要维持一定开度来克服阻力。很多人在简化模型里习惯了“目标速度到了油门就松开”的逻辑换到高精度模型上就会发现油门完全松开之后车辆会被空气阻力和滚动阻力拖慢车速持续往下掉。这个差异是简化模型和真实车辆模型在纵向动力学上最大的区别之一也是联合仿真价值最直观的体现。3.3 Simulink模型整体组织与信号流整套Simulink模型可以划分成几个模块区块领航车速度序列模块、前车状态接收模块、间距计算模块、上层控制器模块、下层控制器模块、CarSim车辆模块和数据记录模块。信号流向是这样的跟随车CarSim模块输出当前车速和位置前车模块输出前车位置和车速间距计算模块算出实际间距并与期望间距比较得到间距误差送入上层控制器上层控制器输出期望加速度下层控制器把它转换为节气门和制动信号送回跟随车CarSim模块完成一次闭环控制。搭建时一个容易被忽略的细节是初始状态的设置。三辆车在仿真开始的瞬间必须设置好各自的初始位置让两车之间的初始间距恰好等于期望间距否则仿真起步就会带有一个很大的初始误差控制器需要耗费大量时间去收敛初期还会产生很剧烈的加速度波动。我的做法是在CarSim中分别设置每辆车的初始X坐标让相邻两车的初始距离等于该时刻的期望间距然后在Simulink里跑一个很小的初始化检查确认初始间距误差近似为零再开始正式仿真。另一个组织层面的建议是数据记录方式。Simulink自带的Scope模块可以看波形但在大型多车模型里频繁打开Scope会拖慢仿真速度。更合理的做法是把关键信号统一通过To Workspace模块保存到工作区变量中仿真结束后用脚本做统一后处理。我把输出数据结构设计为包含时间戳、三辆车各自的速度和位置、间距误差、期望加速度、实际加速度、节气门和制动信号的格式一次仿真跑完所有需要分析的指标都能从这份数据里直接提取后续做参数对比和画图都非常方便。4. 仿真调试与常见问题排查实录4.1 仿真发散、信号振荡的排查思路联合仿真最容易遇到的第一个难题是仿真中途信号振荡、数值发散典型表现是车速和加速度出现高频抖动严重时直接报错退出。根据我的调试经验这类问题有几个比较常见的原因排查时建议按顺序梳理。首先是控制增益过大的问题。PID增益调得过高尤其是微分项增益偏高时控制器会对信号中的噪声和量化误差进行放大产生高频振荡。解决方法很直接把增益降下来逐步增大找到一个稳定边界附近的值。其次是期望加速度限幅设置不合理。当控制器输出频繁触到上下限、在限幅值附近来回跳动时系统容易产生极限环振荡这时需要同时调整限幅值和积分项设计。第三种常见原因是CarSim输出的速度信号没有经过滤波就直接送进控制器微分环节对高频噪声极其敏感。解决方法是在Simulink里加一个一阶低通滤波器对速度信号做平滑处理后再送入控制器。我在排查自己仿真里的振荡问题时用的是“从外到内、逐级隔离”的策略。先把上层控制器的输出固定为一个常数直接给定一个不变的期望加速度看CarSim车辆响应是否正常——如果正常说明底层车辆模型和接口没问题问题出在上层。再把PID改成纯比例控制看系统是否仍然振荡——如果仍然振荡说明比例增益过大。这种逐级隔离的思路比盯着波形盲猜高效得多强烈建议每个搭联合仿真的人都掌握。调振荡问题最忌讳的就是同时改多个参数改乱了之后根本不知道是哪个参数引起的最后只能全部推翻重来。4.2 参数整定的实际经验先内环后外环分类分速调参数整定是纵向跟随控制里最费时间的一步。我的整定方法可以总结为“先内后外”四个字。具体来说先把下层控制器单独验证一遍——给一个固定的期望加速度序列看CarSim车辆能否精确跟踪。如果下层映射不准上层调得再好整体性能也不可能好。确认下层响应准确之后再接通整个闭环去整定上层PID。几个具体的整定心得值得分享。第一比例增益Kp的初始值可以用理论计算来定。比如期望间距误差为0.5米时我们希望期望加速度能达到每秒平方1米左右Kp的初值就可以取2左右再根据实际响应调整。第二微分项增益Kd不要一开始就加先让系统在纯比例控制下稳定再慢慢增加Kd来抑制超调。否则一边加增益一边观察振荡很容易失去对系统响应的直觉。第三积分项放在最后加而且务必配合积分限幅。积分饱和带来的滞后性问题往往比它消除的稳态误差更棘手。第四参数修改遵循“一次只动一个”原则改完之后先观察一个完整的跟车工况周期再决定下一步调整方向。另一个容易被忽视的问题是不同速度区间的参数表现差异很大。低速起步时车辆的传动和制动响应特性和中高速巡航完全不同。我调试中亲身遇到过同一组PID参数在40km/h巡航工况下表现良好但换成低速起步跟车工况后前几个控制周期就出现明显振荡。应对方法是拆开工况整定参数比如分别标定低速起步、中速巡航、急减速三种典型工况的参数再通过增益调度的思路衔接起来。这个方式工作量稍大但在接近工程实际的场景中几乎是必须的。4.3 从三车编队到多车编队的扩展要点三车编队验证通过之后向多车编队扩展是一个很自然的方向。我的体会是多车扩展的难点不在控制算法的架构而在于数据管理和通信结构的建模。数据管理层面N辆车就需要N个CarSim实例每个实例都涉及独立的参数文件、输入输出接口和初始位置配置。手写配置极易出错更高效的做法是写脚本自动生成批量配置用循环的方式生成本车与前车的CarSim配置和Simulink模型连接关系。通信结构层面最简单的拓扑是“每辆车只接收直接前车的信息”这种前车跟随策略在中低速队列中广泛使用。如果考虑更复杂的拓扑比如领航车广播状态给所有跟随车控制问题就从单纯的前车跟踪变成了多车协同控制这时控制器设计需要引入车队整体稳定性分析理论复杂度会上升一个档次。做纵向跟随控制的人还绕不开一个扩展话题通信时延的模拟。在Simulink里可以通过延迟模块来模拟信息从采集到接收的处理延迟。我强烈建议在基础模型跑通之后至少加一组50到200毫秒的延迟测试。加入时延之后系统对控制参数的敏感度显著提高原本稳定的参数很可能变得不稳定。这个步骤虽然会增加调试工作量但能让你直观认识到“真实通信环境下控制性能会受影响”这一事实这也是联合仿真平台对比简化模型平台最明显的优势之一。扩展的最终形态可以做三个方向第一把上层控制器从PID换成模型预测控制MPC在约束处理和多目标优化上表现会更好第二加入执行器饱和与延迟的动态模型让下层控制器更贴近真实执行器的响应特性第三做硬件在环测试把真实的控制器硬件接入仿真回路验证算法在实时环境下的运行效果。三个方向都能让这套联合仿真平台从“算法验证工具”升级为“接近工程落地的开发平台”。做完整套三车纵向跟随联合仿真之后我最大的体会是联合仿真的价值不完全在于模型精度有多高而在于它逼着你把一套控制算法从理论到工程完整地走了一遍。在简化模型里你永远不会注意到油门松开车辆会减速这件事也不会意识到通信时延对参数稳定性的影响有多敏感——这些问题只有在接近真实车辆动力学的仿真环境里才会暴露出来而早一步暴露就意味着后续实车测试时少走一次弯路。最后分享一个小技巧如果刚开始搭联合仿真环境别急着追求多车编队和控制器复杂程度先花半天时间把单辆车的CarSim与Simulink闭环链路彻底跑通确认接口、步长、数据记录全部正常再去扩展多车和控制算法。这个“单车先通、从简到繁”的策略能帮你避免在多问题叠加时无从下手。希望这篇记录能给正在做CarSim联合仿真的朋友提供一些参考祝你们少踩几个坑。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑