☰
基于Matlab/Simulink的增程式混合动力汽车建模仿真方法
2026/10/20 7:41:33 网站建设 项目流程

大概一年半前,我接到一个增程式混合动力的预研需求:没有台架、没有实车、没有标定数据,却要在节点前给出"这套架构到底省不省油、电池需要多大、增程器该选多大功率"的初步结论。我选择用Matlab/Simulink从零搭一套增程式混合动力汽车建模仿真模型,把整车控制逻辑、部件特性和能耗算清楚,而不是靠PPT拍脑袋。这套模型后来成了我项目组验证策略、出选型报告、甚至预筛选控制参数的主要工具。

这篇内容面向三类人:一是刚接触混动仿真、想搭一套自有模型的工程师,二是准备做能量管理策略却又不知道从哪儿下手的研究者,三是想快速评估增程架构油耗潜力的产品定义同事。我不打算只给个宏观框图,而是按我踩坑后的真实搭建顺序,把信号流、模块等效公式、控制器状态机、联调排错、结果判定都讲一遍,你照着这个思路,基本能搭出第一版能跑的增程车整车模型。

1. 先画信号流再开Simulink:增程模型的功能边界与前后向仿真取舍

动手开Simulink之前,第一件事不是找模块,而是回答一个问题:这个模型是要给谁用、用来验证什么。增程式混合动力车的模型用途大体分三类:控制策略开发与验证、部件选型与参数匹配、宏观经济性评估。这三种用途对模型精细度的要求完全不同。控制策略开发需要模型能复现扭矩响应、SOC波动、发动机起停行为,至少得是前向仿真加动态部件响应;选型和油耗评估则可以适当降低动态保真度,甚至后向仿真就够用。先把边界定下来,后面才不会被模型细节拖死。

1.1 前向仿真与后向仿真:增程车该选哪条路

增程车模型最常见的是前向仿真模型。驾驶员模型根据车速误差和踏板逻辑给出需求扭矩,然后扭矩沿"电机→传动系→车轮→整车纵向动力学"逐级传递,最后车速反馈回驾驶员。它的优点是物理因果链清楚,可以逼真地模拟控制延迟、扭矩限制、模式切换,缺点是需要认真处理数值环和求解步长。

后向仿真则反过来,先给定工况车速,从车轮需求功率反推发动机、电池和电机需要提供的功率。后向仿真计算快,对部件外特性数据敏感度低,很适合做早期的能耗边界扫描,但没法体现"控制器响应不及时导致车速跟踪失败"这类真实问题。我的建议是:如果目标是策略开发和整车控制器验证,直接用前向仿真;如果只是纯油耗预测、不用管动态表现,后向仿真跑一遍更省事。我自己最终选择前向仿真,就是因为这个项目最核心的风险在VCU逻辑,不在能耗数值精度。

1.2 顶层模块划分与信号流动线

敲定前向仿真后,接下来把顶层拆成几个功能清晰的模块,我用的是下面这套划分,和很多商用整车模型结构类似,但砍掉了一些视觉上的复杂包装:

  • 驾驶循环与工况输入模块:输出时间序列的目标车速、坡度。
  • 驾驶员模型:根据目标车速与实际车速的误差,给出油门踏板和制动踏板开度。
  • 整车控制器(VCU):根据踏板开度、SOC、档位状态,解析出驱动电机扭矩指令、增程器功率请求、再生制动扭矩。
  • 增程器模块:把目标功率转换成发动机转速/扭矩请求,并计算燃油消耗量。
  • 动力电池模块:接收净电功率,计算端电压、电流、SOC和内阻损耗。
  • 驱动电机模块:接收扭矩指令和当前转速,输出实际扭矩、机械功率、电功率和损耗。
  • 车辆纵向动力学模块:把轮端驱动力与阻力之差积分成车速。

模块之间的信号流主线是:工况->驾驶员->VCU->执行部件->车辆动力学->车速反馈回驾驶员。这条环线必须在模型里形成闭环,增程器模块和电池模块都属于能量源,它们提供的是功率信号,不是扭矩信号,所以不会直接进入车辆动力学的受力求和,这是和并联混动模型最大的区别,也是最容易上手的地方。建议一开始就用Bus对象定义信号结构,而不是到处拉飞线,否则后面改参数时一定会后悔。

2. 从车轮倒推到电机:车辆纵向动力学与驾驶员模型的连乘关系

整车模型里最底层的物理主体是车辆纵向动力学,它决定车速怎么随力变化。很多新手先把发动机和电池建模做得特别复杂,结果发现车速都不准,回头再改底盘参数,极其难受。我的习惯是先搭好车身和驾驶员,让最简单的"电池直驱电机"闭环先跑起来,再往里面加增程器。

2.1 纵向受力模型与传动链的扭矩换算

车辆纵向动力学不复杂,就是牛顿第二定律在汽车方向的展开。驱动轮上的牵引力来自电机扭矩经过传动比放大并考虑传动效率后的轮端力,阻力和牵引力求和后除以整车质量得到加速度,再积分就是车速。

公式可以拆成四块:牵引力 F_drive = T_motor * i_gear * eta_drive / r_wheel;滚动阻力 F_roll = m * g * fr;空气阻力 F_air = 0.5 * rho_air * cd * A * v^2;坡度阻力 F_grade = m * g * sin(alpha)。合起来写成:ma = F_drive - F_roll - F_air - F_grade。其中 m 是整车质量,alpha 是道路坡度,v 是车速,r_wheel 是车轮滚动半径。

Simulink里的做法很直接:用一个Sum模块把四个力加起来,除以质量得到加速度,再两个Integrator串联得到速度和位移。加速度和速度初始值我都设成0,但要注意给的初速度不能影响坡度阻力和空气阻力计算。空气阻力的车速反馈是代数关系,直接用当前速度就行,不会产生代数环。传动链效率可以放在电机扭矩换算到轮端力的地方,取0.92~0.95,这个值对油耗仿真影响不大,但别遗漏。另一个容易忽略的是旋转质量惯量效应,也就是实际加速需要的等效质量比整车质量大,好在这类仿真里一般取一个修正系数δ=1.08~1.15即可,不需要真的把每个旋转部件的惯量都建模。

仿真前把参数统一放到一个初始化脚本里,别散落在模块里。我习惯用一个结构体变量保存全部参数,例如veh.veh.mass、veh.veh.radius,这样跑参数扫描时可以批量修改。

veh.veh.mass = 1800; % 半载质量,kg veh.veh.radius = 0.32; % 车轮滚动半径,m veh.veh.g = 9.81; % 重力加速度 veh.veh.cd = 0.32; % 风阻系数 veh.veh.A = 2.35; % 迎风面积,m^2 veh.veh.fr = 0.012; % 滚动阻力系数 veh.veh.eta_drive = 0.94; % 主减速效率 veh.veh.delta = 1.1; % 旋转质量换算系数

2.2 驾驶员模型:让模型自己"踩"油门和刹车

驾驶员模型看起来是个小角色,但它的质量直接影响整个闭环仿真。我见过很多模型干脆把目标车速直接换算成功率塞给VCU,那样做省事,却埋了一个坑:车速跟踪误差为0,控制器策略就没法根据"误差"调整能量分配,尤其是再生制动介入逻辑,完全看不出问题。我最终用的是经典PID闭环加踏板开度映射:目标车速减去实际车速得到误差,经过PI控制器得到修正量,再映射到油门踏板开度0~1和制动踏板开度0~1。

PID参数的经验值我给出一个可用的起点:如果速度单位是m/s,比例项Kp取1.0~1.5,积分项Ki取0.3~0.5,微分项Kd取0.01~0.05。超出范围后模型会抖,尤其是制动踏板输出饱和会引发车速振荡。踏板输出要加饱和和变化率限制,模拟真实驾驶员不敢一脚跺死刹车。另外驾驶员模型要能输出一个连续踏板信号,而不是离散的1或0,这样VCU才有足够的调节空间。

在Simulink里,我一般用连续时间PID控制器模块,输出范围设0~1;然后通过一个简单的分配逻辑:正部分作为油门信号,负部分取绝对值作为制动信号。注意这里油门和制动是两个独立量,不要把负值直接传给VCU,否则再生制动和机械制动的分配逻辑会纠缠在一起。如果想让模型更真实,还可以在驾驶员模块里叠加一个速度误差前馈项,加速响应更快,但这个属于可选项,前期不做也行。

3. 三个核心部件模型的工程取舍:电池、电机、增程器的等效思路

部件建模是整个工程里最需要"功力"的地方,但不是越复杂越好。增程构型里,发动机与车速解耦,这给电池和电机建模留出了很大的简化空间。我的原则是:动态行为能简化就简化,但要保住三个关键特性——效率、限制边界、响应延迟。

3.1 动力电池:Rint等效电路与SOC安时积分

增程车电池模型主流选择是Rint等效电路,一个电压源串联一个内阻就够了。比它更复杂的Thevenin模型,也就是多两个RC并联环节模拟极化效应,对SOC和功率流影响不大,主要影响端电压瞬态,前期完全可以不加。Rint模型建模需要的输入是净电功率P_bat,输出是端电压U、电流I和SOC。其中Voc是开路电压,R是内阻,两个都随SOC变化,我做成两个一维查表。

电流按照放电为正来定义,给定净功率后,端电压和电流的关系是 U = Voc - IR,功率是 P=IU。联立求解会得到一个一元二次方程,我直接在MATLAB Function模块里用解析式算,避免在Simulink里形成代数环。公式是 I = (Voc - sqrt(Voc^2 - 4RP_e)) / (2R),这里P_e是电功率,正数为放电。然后SOC通过安时积分更新:SOC = SOC0 - ∫ I dt / (3600*Ah)。

数据质量直接决定电池模型可信度。没有实测数据时,可以用典型三元锂电池的开路电压和内阻曲线形状做近似:SOC从0到1,Voc从约240V平滑上升到340V左右;内阻在中段較低、低SOC和高SOC变高。初期模型把温度因素忽略,只给一个常温内阻表就够了,温度影响放到后期再补。另外必须给SOC加饱和限幅,防止积分器越界后查表出错。

3.2 驱动电机:外特性扭矩限制、效率map与再生制动

电机模块接收VCU的扭矩指令和当前转速,输出实际轮端扭矩和电功率。建模分三层:需求扭矩限制、实际扭矩响应、电功率计算。第一层是外特性限制:基速以下恒扭矩区,扭矩上限就是峰值扭矩;基速以上恒功率区,扭矩上限按 9550*P_max/n 计算,其中n是当前转速。Simulink里直接用两个端点取值并取min即可,注意转速单位要换算成rpm再算,不然系数错得离谱。

第二层是扭矩响应,真实电机响应很快,通常几十毫秒,我一开始把手写常量当瞬态响应,也就是指令多少就输出多少,结果导致整车控制器发出的扭矩变化太快,和底层逆变器行为不匹配。后来我加了一个一阶惯性环节,时间常数取30~50ms,这就够模拟扭矩建立过程了。第三层是效率。电机效率是转速和扭矩的二维查表,仿真时用查表得到效率η,电功率等于机械功率除以效率,放电时机械功率是Tω,如果扭矩为负也就是再生发电时,电功率=机械功率η,此时电流充入电池。

再生制动是这个模型里容易被低估的部分。我的做法是把制动扭矩上限设成负扭矩外特性的一部分,但加两个额外条件:SOC低于95%时才允许回馈,否则为了保护电池禁止大电流充电;车速低于某个很小值如5km/h时退出回馈,因为低速时电机反电动势太低,回收效率没有意义。VCU端只需要算好再生扭矩和机械制动扭矩的分配,电机模型端只是按指令执行。

3.3 增程器:转速扭矩解耦的最优工作点拟合

增程器是增程构型的灵魂,它的特征是发动机与车轮完全解耦,所以发动机转速不需要跟随车速,可以自由选择最低油耗工作点。这也是增程式能在市区工况比燃油车省油的根本原因。建模时不需要详细发动机动力学模型,而应该聚焦在输入输出关系上:输入是目标电功率,输出是发动机转速、扭矩请求、轴功率和燃油消耗率。

最省心的方案是提前离线做好"最优工作点表":在发动机转速网格上,对每个目标电功率反算需要多大的扭矩,再从BSFC油耗map里找出该功率下油耗最低的转速和扭矩组合,存成三张一维查表,输入是功率,输出分别是最优转速、最优扭矩、对应燃油消耗率。仿真时直接查表,速度快且结果稳定。下面是一张示意工作点表,数值不具备实机参考性,但结构就是长这样。

目标电功率(kW)最优转速(rpm)最优扭矩(Nm)燃油消耗率(g/kWh)
5150031.8280
10160059.7245
15180079.6230
20200095.5222
302300124.7218
402600147.0225

增程器模块还要考虑功率响应延迟。发动机从停机到目标功率不可能瞬间响应,我在目标功率后面加了一个带斜率限制的一阶环节,模拟从点火、拖转、达到目标功率的过渡过程。燃油消耗不是从瞬态油耗积分,而是先算发动机在当前转速扭矩下的瞬时油耗率,再积分得到总量油耗。这个积分量最后要除以燃油密度转为升,再和里程做百公里油耗。

4. 让增程器像真车一样起停:VCU状态机与功率跟随策略

增程车的VCU核心是模式管理。整车应该什么时候纯电行驶、什么时候启动增程器、增程器启动后以什么功率运行,每一条都会直接影响油耗和体验。我在Simulink里用Stateflow搭状态机,而不是简单的逻辑判断模块,因为模式切换存在时序和停留时间,Stateflow更直观,边界条件也好维护。

4.1 模式划分与SOC迟滞带的必要性

我定义了两个主状态:EV模式和CS模式。EV模式对应纯电驱动、增程器停机,适合电量充足时使用;CS模式对应电量保持,增程器根据需求功率和电池目标功率按需运行。切换条件的关键是SOC阈值,如果只有一个阈值线,比如SOC低于30%就启动、高于30%就停机,那么当SOC在30%附近抖动时发动机会频繁启停,电池寿命和实际油耗都完蛋。所以一定要加迟滞带:SOC降到24%触发增程器启动,SOC升到27%以上才允许停机,中间有一段缓冲区。迟滞带的宽度取3%~5%比较合理,太窄起不到防抖作用,太宽会导致电量保持区间偏大。

同时,切换条件还要加上时间确认。我要求SOC穿越阈值且持续3秒以上才允许模式切换,这个3000ms的时间窗能滤掉短暂功率冲击引起的误判。这些逻辑用Stateflow表达就是两个状态之间的迁移条件:from EV to CS的条件是SOC < 0.24 && temp_ev > 3;from CS to EV的条件是SOC > 0.27 && temp_cs > 5。其中temp状态从进入当前模式开始累计时间。实际开关一次增程器要做的工作量不小,没必要因为一次偶然瞬时波动就来回切换。

4.2 功率跟随与启停防抖:从逻辑表到Simulink实现

CS模式下的能量管理策略我选的是经典的功率跟随策略,不做全局优化,原因是项目周期不允许上动态规划或MPC,而且规则型策略后期标定好查问题。核心公式是:增程器目标功率 = 整车驱动需求功率 + 电池目标充电功率。驱动需求功率由VCU根据踏板开度和车速计算,电池目标充电功率是固定的一个值,比如5kW,这样在稳态工况下电池SOC会缓慢回升并维持在CS阈值附近。

增程器启动后,目标功率并不是一步到位,而要以斜率限制爬坡到目标值,我取5kW/s的爬坡速率,模拟发动机和发电机扭矩建立的动态过程。此外我还做了两个防抖细节:第一是停机前需要有最低运行时间,比如增程器启动后至少运行60秒才可以停机,防止走走停停时反复启停;第二是功率跟随求出的目标功率要做低通滤波,时间常数取200~500毫秒,防止驾驶员扭矩波动传导到增程器引起功率抖动。

VCU输出到增程器和电机的所有指令都设置了一致的离散采样时间,我用的是10ms。这里要强调:控制器输出必须是离散信号,别让Stateflow和连续动力模块直接混在一个斜率里,否则后面很容易出现步长问题和代数环。再生制动分配我放在VCU模块里做,逻辑是:制动踏板开度对应总制动力,先尝试让电机回馈一部分,上限受电机外特性、电池充电功率限制,剩余部分由机械摩擦制动承担。别忘了再给一个SOC低但还没到充电上限的场景,这时候的回馈可以尽可能大,增程器不需要额外补偿。

5. 闭环联调时最常遇见的五个问题:代数环、单位、查表与求解器

模型搭完后,第一次闭环仿真往往不会顺利跑完。我把自己踩过的高频问题做了个清单,每一个都是真实的仿真事故,如果你也碰到类似报警,按这个思路排查会快很多。

5.1 代数环与振荡:一次真实踩坑记录

我第一次把驾驶员、VCU、电机、车辆动力学闭环连起来时,Simulink直接报代数环警告,Scope里的车速在0附近来回震荡,看起来像"违反物理"的抖动。查了半天发现环路在这:驾驶员根据车速误差算扭矩请求,VCU把这个请求直接送给电机,电机输出扭矩到车辆动力学,车辆动力学再输出车速反馈给驾驶员。如果车速在这个求解步长里还没有更新,那么误差就包含当前步长下的未知量,Simulink只能靠迭代求解,一旦迭代不收敛就开始振荡。

解决办法有两个,我最终两个都用了:一是把VCU输出信号通过Unit Delay延迟一个采样周期,模拟真实控制器"上一帧决策、下一帧执行"的特性;二是在VCU所有输出前加Rate Limiter限制变化率,进一步增加数值稳定性。经过处理后,后续整条仿真链路再也没有出现代数环警告。这个经历也说明,控制器离散建模不是形式主义,它和连续动力学模型的耦合方式就是需要主动切一刀。

5.2 查表边界、单位一致性与求解器配置

查表是这类模型的"偏科项"。Lookup Table如果断点设置为线性外推,SOC一旦越过0或1时表值会夸张到离谱,电流和功率都会爆炸;所以我所有关于SOC、转速、扭矩的表都选择clip方式,也就是查表到边界就锁在边界值。同时,一维表断点必须单调递增,二维表X/Y轴别搞反,这是Simulink最常报的错。

单位一致性也很重要。车速在驾驶员里如果用了km/h,在空气阻力公式里却用了m/s,结果会差一个3.6因子。我的习惯是整车动力学的所有内部值统一用国际单位:车速m/s,功率W,扭矩Nm,转速rad/s;只有和驾驶循环、控制器人机接口交互时才换算成km/h、kW这种工程单位。每个模块加注释标明单位,仿真报告里如果有疑似异常值,第一个查的一定是单位换算。

求解器我用的是变步长ode45配合MaxStep=0.05s,另外因为控制器是离散的10ms采样,所以仿真时能跑得比较快,不会因为固定步长过小把时间拖长。如果你的模型存在比较硬的切换,比如离合、制动抱死,建议直接改固定步长ode4,步长0.01s,这样稳定性和结束结果可复现性都更好。

5.3 仿真跑太慢的优化办法

整车模型跑一个NEDC工况约20分钟,但跑WLTC要30分钟,再配上参数扫描就很痛苦。我建议做三件事:第一,Scope不要到处挂,用信号日志功能只记录你关心的信号,比如SOC、车速、油耗、发动机工作点,记录完导出到工作区再画图;第二,把模型构建模式调到加速器模式Accelerator,编译后运行速度提升一个量级;第三,如果要做几十组参数扫描,写个MATLAB脚本循环改参数并用sim()批量运行,别在GUI里手点。第四,善用Root Inport Mapping批量导入不同驾驶循环文件,省去每次改From Workspace的连接。

6. 结果怎么判:SOC曲线、发动机工作点和百公里油耗的后处理

模型跑通了不代表能出结论。如果只是看最终油耗数字,而不管中间SOC变化和发动机工作状态,很容易被假象误导。我给自己定了一套后处理流程:先看SOC整体趋势,再看发动机启停次数和工作点分布,最后才是油耗折算。

6.1 先看SOC是否"躺平"了:电量保持与动态响应

正常的CD阶段SOC会从初始值缓慢下降,曲线基本贴近一条平滑斜线;进入CS阶段后,SOC会在阈值附近震荡,幅度不超过2%。如果CS阶段SOC持续下降,说明增程器目标功率小于整车电需求加电池目标充电功率,要么提高爬坡功率,要么提高电池充电功率;如果SOC一直快速上升,说明增程器功率给大了,会造成额外油耗和浪费。车速跟踪精度也反映驾驶员和VCU匹配情况,WLTC这类高动态工况车速误差在2km/h以内我认为是合理的,超过5km/h要考虑PID参数。

还有一个动态细节:急加速时SOC瞬时下降后,CS阶段能不能平滑补回来;急减速时再生回充功率有没有让SOC出现瞬间尖峰。这两种事件的处理直接影响真实驾驶体验,比纯油耗更有价值。

6.2 从油耗数字到等效油耗:如何公平评价不同控制参数

油耗计算不复杂,单位里程百公里油耗 = 燃油总质量(kg)/燃油密度(kg/L)/总里程(km)100。燃油密度取0.725 kg/L。但更严格的做法是算出等效油耗:如果仿真结束时SOC低于初始值,相当于电池多放了一部分电,这部分电要折算到燃油消耗里。我用的简化折算系数是:每消耗1kWh电池电量约对应0.3L油耗,这是增程器平均发电油耗水平。等效百公里油耗 = (油耗升数 + ΔSOC电池总能量kWh*0.3/100?) 不对,应该是 ΔSOC(负为放电)电池总能量kWh0.3L每kWh 除以里程再乘100,方向别搞反。两个策略对比时,如果SOC初末相差超过2%,必须做这个折算,否则结论可能完全相反。

发动机工作点散点图是判断策略是否高效的另一把尺子。把每次仿真记录的发动机转速和扭矩工作点画在BSFC等值线图上,观察散点是否集中在高效区。我看到过很多模型策略"油耗数字漂亮",但工作点散落在低效区,原因是频繁启停或功率跟随响应太激进。好的增程策略应该是:CS阶段大多数工作点落在BSFC最低区域的附近,少量低功率点落在高效区边缘。调优时先调SOC阈值和启停延迟,再调功率爬坡率,每次只动一个参数,并保存实测数据,因为多变量一起改时你根本无法定位是谁起的作用。

6.3 关于模型可信度的一点个人习惯

模型搭完能跑出曲线只是第一步,我更建议留出两份留存:一是"基准工况归档",把每版参数对应的仿真结果、初始化脚本、模型版本号一起打包,方便后续复现和回溯;二是"可视化自查表",用固定几个典型工况做成模板,每次改参数后快速跑对照,看SOC、油耗、启停次数是否符合预期。我在实际项目里最常遇到的情况不是模型不工作,而是跑出来的结果好像合理,却不知道是哪个参数改出了这个效果。所以,做好仿真日志,比堆模型复杂度管用得多。反正后来我再做选型对比时,已经不怎么看单一油耗值了,而是直接调出当时的发动机工作点分布和SOC历史曲线,一眼就能判断策略有没有跑偏。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询