核心1:ECMS 对比 规则基 (油耗/SOC误差)
1. 基于规则的策略 (Rule-based Strategy)
- 控制逻辑:通常基于稳态查表、逻辑门限值(如电量消耗-电量维持 CD-CS 模式、恒温器策略或功率跟随策略)。系统在特定的车辆速度、需求功率和SOC阈值下触发发动机或电机的启停。
- 油耗表现:由于无法预知未来的行驶工况且主要依赖标定经验,发动机往往无法一直工作在最优工作线(OOL)上。整体油耗表现为次优(Sub-optimal)。
- SOC误差表现:SOC轨迹通常呈现出较硬的阶跃或较大的波动范围。只要SOC在允许的上、下限(例如 0.25 - 0.30)内,系统就不会主动干预。因此,最终的SOC与目标SOC往往存在较大的残差。
2. ECMS 策略 (Equivalent Consumption Minimization Strategy)
- 控制逻辑:这是一种基于瞬时优化的策略。核心思想是将电机的电能消耗(或回收)通过"等效因子 (Equivalence Factor, EF)"折算为等效油耗。在每个控制周期内,寻找使总等效瞬时油耗最小的发动机与电机功率分配。
- 油耗表现:ECMS 能够根据瞬时状态动态调整功率流向,使发动机尽可能避开低效区,工作在最佳油耗区域。其整体油耗显著低于基于规则的策略,且逼近全局最优解(如动态规划 DP 的结果)。
- SOC误差表现 :在自适应ECMS(A-ECMS)中,等效因子会根据当前SOC与目标参考SOC(SOCrefSOC_{ref}SOCref)之间的误差进行实时PI调节。这使得系统的SOC轨迹被紧紧"锚定"在参考值附近。在循环工况结束时,ECMS 的终端SOC误差极小(通常误差 <1%< 1\%<1%),从而保证了电量维持(CS)阶段的公平对比。
核心2:绘图 - 对比曲线 (论文结果图生成)
在撰写学术论文或处理仿真结果时,通常需要将这两种策略在同一工况(如 WLTC 或 NEDC)下的表现进行可视化叠加对比。如果需要提取模型数据并绘制这些核心曲线,可以通过配置 Simulink 模块并使用 MATLAB 脚本来实现:
1. SOC 轨迹对比图 (SOC Trajectory)
这是最能直观反映两种策略充放电行为倾向的图表。
- 现象:基于规则的曲线通常呈现锯齿状的大幅波动,或者过早消耗电量;而 ECMS 曲线波动更加平滑,且在终点处精准收敛于目标值(例如 0.3)。
- Simulink 提取方式 :在被控对象的电池模型输出端引出 SOC 信号,连接至
To Workspace模块,命名为soc_rule和soc_ecms(设为 Array 格式)。 - 绘图参考代码:
matlab
plot(tout, soc_rule, 'b--', 'LineWidth', 1.5); hold on;
plot(tout, soc_ecms, 'r-', 'LineWidth', 1.5);
plot(tout, ones(size(tout))*0.3, 'k:', 'LineWidth', 1); % 目标SOC参考线
xlabel('Time (s)'); ylabel('SOC');
legend('Rule-based', 'ECMS', 'SOC Reference');
title('SOC Trajectory Comparison');
2. 累计油耗对比图 (Cumulative Fuel Consumption)
用于直接证明 ECMS 的节能优势。
- 现象:随着时间推移(尤其是循环工况的中后段),Rule-based 的红色曲线会逐渐高于 ECMS 的蓝色曲线。终点处的纵轴差值即为 ECMS 节省的燃油量。
- Simulink 提取方式 :将发动机油耗率(g/s)通过
Integrator(积分器) 模块后,接入To Workspace模块,得到累计油耗(克 或 升)。 - 绘图参考代码:
matlab
plot(tout, fuel_rule, 'b--', 'LineWidth', 1.5); hold on;
plot(tout, fuel_ecms, 'r-', 'LineWidth', 1.5);
xlabel('Time (s)'); ylabel('Cumulative Fuel Consumption (g)');
legend('Rule-based', 'ECMS');
title('Fuel Consumption Comparison');
```
3. 发动机工作点分布对比散点图 (Engine Operating Points)
用于从微观机理上解释为什么 ECMS 油耗更低。
- 现象:在发动机万有特性图(BSFC Map)上打散点。基于规则的点散布较广,部分落在高油耗区域;而 ECMS 的点高度集中在发动机的最优工作线(Optimal Operating Line, OOL)附近。
- Simulink 提取方式 :将发动机转速(Speed)和转矩(Torque)通过
To Workspace导出。 - 绘图参考代码:
matlab
% 假设已有发动机 BSFC 等高线图绘制代码 (contour)
% contour(Speed_grid, Torque_grid, BSFC_map); hold on;
scatter(spd_rule, trq_rule, 10, 'b', 'x'); hold on;
scatter(spd_ecms, trq_ecms, 10, 'r', 'o', 'filled');
xlabel('Engine Speed (rpm)'); ylabel('Engine Torque (Nm)');
legend('Rule-based Points', 'ECMS Points');
建模过程
我将手把手带你完成从"捏造参数"到"跑出高质量对比图"的全套闭环流程。请严格按照以下 5 个步骤操作,一步都不要跳过。
第一步:构建全局变量池(解决"没有数据"的问题)
在打开 Simulink 之前,我们必须先在 MATLAB 的"大脑"里塞满虚拟的物理数据。
- 打开 MATLAB,在主界面的 Command Window(命令行窗口) 中,复制并运行以下所有代码:
matlab
% ==========================================
% 混合动力汽车基础参数初始化 (虚拟数据)
% ==========================================
% 1. 电池参数
Bat_Cap_J = 5 * 3600 * 1000; % 电池容量:5 kWh 转换为 焦耳 (J)
SOC_Init = 0.6; % 仿真初始 SOC
SOC_Ref = 0.3; % 目标维持 SOC
% 2. 发动机参数 (查表数据:发动机功率 -> 消耗克数)
Eng_Pwr_Breakpoints = [0, 10000, 20000, 30000, 40000, 50000]; % 发动机功率点 (W)
Eng_Fuel_Rate = [0, 0.8, 1.5, 2.2, 3.5, 5.0]; % 对应油耗率 (g/s)
% 3. ECMS 策略参数
LHV_gasoline = 42800; % 汽油低热值 (J/g)
s_base = 2.6; % 基础等效因子
运行后,你的 MATLAB Workspace(工作区)里就会出现这些变量。这就是你整个仿真的数据基石。
第二步:建立"被控对象"(汽车的物理本体)
现在,在 MATLAB 界面点击 Simulink ,新建一个 Blank Model (空白模型)。我们将在这个空白画板上搭建汽车的三个基本器官。
1. 需求功率发生器(模拟司机踩油门)
- 动作 :在库浏览器找
Sources→\rightarrow→Sine Wave,拖入画板。 - 改名 :双击模块名称,改名叫
P_demand。 - 参数 :双击模块内部,
Amplitude设为20000,Bias设为15000,Frequency设为0.05。 - 解释:这代表汽车正在经历一个需求功率在 -5kW 到 35kW 之间来回波动的工况。
2. 发动机油耗计算器
- 动作 :找
Lookup Tables→\rightarrow→1-D Lookup Table,拖入画板。 - 参数 :双击它,
Table data填Eng_Fuel_Rate,Breakpoints 1填Eng_Pwr_Breakpoints。 - 动作 :找
Continuous→\rightarrow→Integrator(积分器),拖到查表模块后面。 - 参数 :双击它,
Initial condition填0。 - 连线 :将
1-D Lookup Table的输出连到Integrator的输入。Integrator的输出引出一根线,这就是最终的总油耗。
3. 电池 SOC 计算器
- 动作 :找
Math Operations→\rightarrow→Gain(增益),拖入画板。 - 参数 :双击它,
Gain填-1 / Bat_Cap_J。 - 动作 :找
Continuous→\rightarrow→Integrator,拖到 Gain 后面。 - 参数 :双击它,
Initial condition填SOC_Init。 - 连线 :将
Gain的输出连到Integrator。Integrator的输出引出一根线,这就是最终的实际 SOC。
第三步:搭建策略一 ------ 基于规则控制器 (Rule-based)
控制器的大脑任务是:根据 P_demand 和 实际 SOC,决定发出多少 PengP_{eng}Peng,算出多少 PmotP_{mot}Pmot。
- 判定当前模式:
- 找
Discontinuities→\rightarrow→Relay。 - 连线:把第二步算出的实际 SOC 信号连到
Relay的输入端。 - 参数:双击,
Switch on point=0.25,Switch off point=0.35。
- 决定发动机功率 (PengP_{eng}Peng):
-
找
Signal Routing→\rightarrow→Switch。 -
参数:双击,
Criteria for passing first input选择u2 > 0。 -
连线:
-
最上面的输入端:连到第一步的
P_demand。 -
中间的输入端:连到
Relay的输出。 -
最下面的输入端:找一个
Constant模块,设为0,连上去。 -
关键点 :这个
Switch的输出端,就是发动机指令功率 (PengP_{eng}Peng) 。请把这根线拉过去,连到第二步那个发动机油耗计算器 (1-D Lookup Table) 的输入端。
- 计算电机功率 (PmotP_{mot}Pmot) 【你之前缺少的量】:
-
找
Math Operations→\rightarrow→Sum,双击将符号改为|+-。 -
连线:
-
+号端:连到P_demand信号。 -
-号端:连到刚才算出来的发动机功率 PengP_{eng}Peng (Switch的输出)。 -
关键点 :这个
Sum模块的输出,就是电机指令功率 (PmotP_{mot}Pmot) 。请把这根线拉过去,连到第二步电池 SOC 计算器 (Gain) 的输入端。
第四步:搭建策略二 ------ A-ECMS 控制器
为了对比,我们需要搭建第二个模型。你可以按 Ctrl+S 把刚才的模型保存为 Model_Rule.slx。然后另存为 一个新文件 Model_ECMS.slx,删掉第三步的 Rule-based 部分,替换为以下 A-ECMS 结构:
- 生成动态 s 因子:
- 找一个
Sum,符号|+-。+端连一个值为SOC_Ref(0.3) 的Constant,-端连第二步的实际 SOC信号。 - 找
Continuous→\rightarrow→PID Controller。连在上述 Sum 后面。参数:P设为40,I设为0.8。 - 找一个
Sum,符号|++。将 PID 的输出,与一个值为s_base(2.6) 的Constant相加。输出线命名为s_dyn。
- 极小值寻优代码块:
- 找
User-Defined Functions→\rightarrow→MATLAB Function,拖入画板。 - 连线:将
P_demand信号和刚才算出的s_dyn信号接进去。 - 双击模块,清空里面的字,完整复制粘贴以下代码:
matlab
function [P_eng, P_mot] = fcn(P_dem, s)
% 预设候选功率点
Pe_cand = 0:1000:50000;
J_cost = zeros(1, length(Pe_cand));
% 读取基础数据
fuel_pwr = [0, 10000, 20000, 30000, 40000, 50000];
fuel_rate = [0, 0.8, 1.5, 2.2, 3.5, 5.0];
LHV = 42800;
% 遍历所有点找最小代价
for i = 1:length(Pe_cand)
Pe_test = Pe_cand(i);
Pm_test = P_dem - Pe_test;
% 查表算当前油耗率
m_dot = interp1(fuel_pwr, fuel_rate, Pe_test, 'linear', 'extrap');
if m_dot < 0; m_dot = 0; end
% 计算代价 J
J_cost(i) = m_dot + s * (Pm_test / LHV);
end
% 提取最小值对应的功率
[~, min_idx] = min(J_cost);
P_eng = Pe_cand(min_idx);
% 自动算出 P_mot
P_mot = P_dem - P_eng;
end
- 连接输出 :此时该模块右侧有两个端口
P_eng和P_mot。把P_eng连到发动机查表模块,把P_mot连到电池 SOC Gain 模块。
第五步:导出数据与终极对比绘图
这步最关键,关系到论文出图。在两个模型中都做如下操作:
- 添加 To Workspace 模块:
- 找
Sinks→\rightarrow→To Workspace。 - 挂在实际 SOC 输出线上,双击改名
soc_out,Save format**必须选Array**。 - 再找一个,挂在总油耗 输出线上,双击改名
fuel_out,Save format**必须选Array**。
- 设置时间并运行:
- 在 Simulink 顶部菜单栏,将 Stop time 改为
1000。 - 打开
Model_Rule.slx,点击 Run (运行)。运行完后,去 MATLAB 命令行输入:soc_rule = soc_out; fuel_rule = fuel_out; - 打开
Model_ECMS.slx,点击 Run (运行)。运行完后,去 MATLAB 命令行输入:soc_ecms = soc_out; fuel_ecms = fuel_out;
- 生成论文图表:
- 最后,在 MATLAB 命令行运行这段代码:
matlab
% 绘制精美对比图
figure('Color', 'white');
% 1. SOC 对比图
subplot(2,1,1);
plot(tout, soc_rule, 'b-.', 'LineWidth', 1.5); hold on;
plot(tout, soc_ecms, 'r-', 'LineWidth', 1.5);
plot(tout, 0.3*ones(size(tout)), 'k--', 'LineWidth', 1.5);
xlabel('Time (s)'); ylabel('SOC');
legend('Rule-based', 'A-ECMS', 'Target SOC');
title('SOC Trajectory Comparison');
grid on;
% 2. 油耗对比图
subplot(2,1,2);
plot(tout, fuel_rule, 'b-.', 'LineWidth', 1.5); hold on;
plot(tout, fuel_ecms, 'r-', 'LineWidth', 1.5);
xlabel('Time (s)'); ylabel('Fuel (g)');
legend('Rule-based', 'A-ECMS');
title('Fuel Consumption Comparison');
grid on;
最终效果


