这套基于模型预测控制的混合储能微电网双层能量管理系统,是储能优化控制方向里很值得啃的一块硬骨头。核心思路其实不复杂:微电网里同时装了锂电池和超级电容,两种储能特性正好互补;控制系统拆成上下两层,上层管长周期的经济调度,下层管秒级的实时功率分配;模型预测算法贯穿两层,用滚动优化把预测、约束和动态响应都塞进同一个框架里。我自己前前后后折腾过好几版模型和Matlab代码,踩过的坑能列一长串,这次把最容易劝退新手的关键环节都整理出来,包括数学建模、QP求解、双层嵌套循环写法、参数整定和典型故障排查,希望能帮正在做相关仿真和论文的朋友少走弯路。
1. 这套系统到底解决什么问题
1.1 单电池不香吗,为什么非要混合储能
很多人刚开始接触微电网储能时都会有这个疑问:既然电池能存能放,直接上一组大电池不就行了?问题出在电池的物理性格上。锂电池能量密度高,能长期提供稳定的较小功率,但它的功率密度有限,大倍率充放电会加速老化,频繁的浅充浅放也会让循环寿命快速缩水。而微电网里的负荷和光伏出力波动不是单一频率的,有缓慢的分钟级趋势,也有秒级的快速抖振。这些高频抖振如果全部压在电池上,电池会很痛苦,温度升高、寿命下降,严重的还会触发保护。
超级电容正好是另一个极端。它的功率密度高,能做到几十毫秒级响应,循环寿命轻松到百万次级别,但能量密度低,存不了太多电,无法长时间支撑功率缺额。一个形象的类比:电池像是拉货的重卡,能装但起步慢,不适合用来跑短途高频运输;超级电容像跑车,起步极快但后备箱小,装不了几箱货。一个混合储能系统把两者并联到直流母线,就是要让重卡拉长途、跑车跑短途高频,各干各擅长的活。
但把两种储能简单并联在一起还不够,谁来指挥它们分工?这就是能量管理系统存在的意义。它要根据负荷需求、可再生出力预测和实时状态,算出电池该出多少、超级电容该出多少,还要保证SOC不越限。混合储能只是硬件基础,能量管理系统才是真正让这套硬件发挥价值的核心。
1.2 “双层”到底在分什么工
双层能量管理系统是一种典型的“战略与战术分离”架构。上层管战略,下层管战术。上层接收负荷预测、光伏预测和电价信号,以15分钟或1小时为时间尺度做经济调度,算出未来一天或几个小时内的储能总功率参考曲线、并网交互计划,以及SOC的参考轨迹。下层不受这么长远的目标影响,它只盯着当前到未来几十秒的窗口,根据上层给的总功率指令和当前实时波动,在电池和超级电容之间做优化分配,目标是维持直流母线电压稳定和功率平衡。
为什么非得拆成两层?如果把全天经济调度和秒级功率分配放在同一个优化问题里求解,决策变量跨度和采样尺度差距太大。全天优化需要小时级预测,秒级控制需要毫秒级响应,两边的时间基准完全不同,强行耦合会导致求解规模爆炸,而且日前预测误差本身就大,精确优化出来的“完美计划”执行没几分钟就失效了。分层是一种工程惯用的降维手段,各层只在自己关心的尺度上做决策,层与层之间用指令和参考轨迹衔接,整体系统既有前瞻性又有快速响应能力。
1.3 MPC凭什么适合干这事
模型预测控制相比PID和简单规则,最大优势在于三件事:能预测、能优化、能滚动。PID只能根据当前误差做反馈,看不到未来趋势;规则控制虽然简单好用,但遇到SOC约束、功率限幅和爬坡约束同时生效的情况,规则很难协调这些相互制约的需求。MPC不同,它内部带一个预测模型,可以推算未来几步的状态,每一步都求解一个有限时域优化问题,把目标函数和约束条件全部纳入,算完后只执行第一步,到下一时刻重新优化,形成闭环反馈。
对于微电网能量管理来说,MPC几乎是量身定做的。储能系统的动态模型相对明确,SOC演变规律可以通过安时积分精确描述;控制周期是秒级或分钟级,留给求解器的计算时间充足;而且功率限制、SOC上下限这类约束本来就该在控制里显式处理。在这些条件下,MPC能一次性解决“跟踪功率指令”“维持SOC健康”“抑制电池频繁动作”这几个互相拉扯的目标,比手动调半天规则靠谱得多。
2. 整体架构与数学建模
2.1 研究对象的结构组成
我搭建的仿真结构是典型的直流微电网,光伏阵列通过DC/DC变换器接入直流母线,锂电池和超级电容分别通过双向DC/DC变换器并联到母线上,负荷挂载在母线侧,系统还通过一个双向AC/DC变流器与上级电网连接,用来在必要时候交换功率。上层能量管理系统跑在监控层,接收预测数据和实时量测,输出调度指令;下层MPC控制器跑在本地控制器里,输出给电池和超级电容变换器的功率参考值,最终由底层电流环PI控制去执行。
各环节的时间尺度差别很大,做模型的时候先明确分工很重要。
| 控制环节 | 典型时间尺度 | 主要任务 |
|---|---|---|
| 上层调度 | 15分钟~1小时 | 经济调度、SOC参考轨迹 |
| 下层MPC | 0.1秒~1秒 | 实时功率分配、电压稳定 |
| 底层变换器 | 微秒~毫秒 | 电流内环、PWM调制 |
我在做代码时把这三层分开封装,上层调度是一个独立的滚动优化模块,下层MPC是另一个求解模块,底层变换器在纯脚本仿真里用一阶惯性环节近似,在Simulink里用受控电流源加PI环实现。这样拆的好处是,不管换模型还是换场景,三层之间只通过接口数据交互,不会相互污染。
2.2 储能系统的状态空间模型
模型预测控制需要一个能反映系统动态的预测模型。对混合储能系统来说,状态变量选两个SOC最直观,控制量选电池和超级电容的功率指令。定义储能放电功率为正,则SOC离散动态可以写成:
SOC_b[k+1] = SOC_b[k] - (Ts / (C_b * U_b)) * P_b[k] SOC_sc[k+1] = SOC_sc[k] - (Ts / (C_sc * U_sc)) * P_sc[k]
这里C_b是电池容量,U_b是电池端电压,乘积代表额定能量,单位要和功率、采样时间匹配。很多新手在写这一步时不注意单位统一,容量用了Ah、功率用了kW、时间用了小时,结果离散矩阵系数差了3600倍,仿真结果完全失真。我的习惯是全部换算成国际单位,容量用库仑,功率用瓦,时间用秒,虽然在加载数据时要多转几步,但排查问题的时候省心得多。
写成矩阵形式就是:
x[k+1] = A * x[k] + B * u[k]
其中x = [SOC_b; SOC_sc],u = [P_b; P_sc],A是单位阵,B是对角负系数矩阵。功率平衡关系作为系统输出的代数方程参与约束:
P_pv + P_b + P_sc + P_grid = P_load
在仿真里,如果忽略线路损耗,这个等式可以直接作为MPC的硬约束或者用惩罚项软约束。我实测下来,直接把等式约束放硬约束,在预测时域较短时问题不大,但预测时域拉长后容易因为预测误差导致不可行,后来改成软约束更稳。
2.3 上层调度层的目标与约束
上层调度解决的是“未来一段时间内怎么运行最划算”的问题。目标函数一般包含购售电费用、储能老化成本、弃光惩罚等。用MPC框架表达,每个调度周期求解一个多步优化问题,目标可以写成:
min Σ( C_grid[k] * P_grid[k] + α * ΔSOC_b[k]² + β * ΔSOC_sc[k]² )
其中C_grid是分时电价,P_grid是并网功率,ΔSOC项用来近似表达储能充放电循环带来的寿命损耗。SOC变化越多,损耗越大,这样模型能自动避免电池反复深度充放,起到保护寿命的作用。
约束条件包括功率平衡等式、并网功率限制、储能功率限制、SOC上下限,以及相邻时段爬坡约束:
P_b_min ≤ P_b[k] ≤ P_b_max SOC_b_min ≤ SOC_b[k] ≤ SOC_b_max |P_b[k] - P_b[k-1]| ≤ ΔP_b_max
上层求解后,输出未来若干个时段的储能总功率参考序列 P_ref_total、各个时段的SOC参考轨迹,以及并网交换计划,这些数据作为下层的输入。
2.4 下层MPC功率分配层的优化问题
下层是这套系统的发力点。它的任务是:在上层给定储能总功率指令P_ref的前提下,实时决定电池和超级电容各自承担多少功率,同时满足SOC和功率约束,还要尽量减少电池动作的剧烈程度。目标函数设计成:
J = Σ_{i=1}^{Np} [ q1 * (P_b[i] + P_sc[i] - P_ref[i])²
- q2 * (P_b[i] - P_b[i-1])²
- q3 * (SOC_b[i] - SOC_b_ref[i])²
- q4 * (SOC_sc[i] - SOC_sc_ref[i])² ]
第一项是功率跟踪项,保证储能总输出跟上上层指令;第二项电池爬坡抑制项,是保护电池的关键;第三四项让SOC尽量贴近参考轨迹或者某个健康区间,防止长时间贴边界运行。
约束方面除了SOC和功率幅值限制,最重要的一条是电池爬坡约束:
|ΔP_b| ≤ ΔP_b_max
这条约束在物理上对应电池变换器的电流变化率限制,也是MPC相比低通滤波方案的一个制胜点。传统低通滤波做功率分配时,把高频分量直接丢给超级电容,低频分量给电池,完全不管电池当前SOC还有没有空间承接、超级电容会不会被迫长期工作在高SOC区。MPC把所有这些因素放进一个优化问题里,每个控制周期重新算一次,分配方案自然更柔性、更健康。
3. Matlab代码实现:从公式到可跑仿真
3.1 代码框架怎么搭才省心
Matlab实现这类双层系统,代码结构如果一开始就乱了,后期改参数能改到怀疑人生。我建议按模块拆文件,每个文件职责单一:
- init_parameters.m:统一管理所有系统参数
- load_data.m:加载负荷、光伏、电价预测数据
- model_hess.m:储能预测模型,返回A、B、C、D矩阵
- upper_mpc_solve.m:上层调度MPC求解函数
- lower_mpc_solve.m:下层功率分配MPC求解函数
- run_simulation.m:主仿真循环
- plot_results.m:结果可视化
参数文件单独放是我反复强调的习惯。这个项目调参频率极高,权值矩阵、预测时域、SOC上下限、电池爬坡率,几乎每换一个运行场景都要动。如果参数写在主循环里,找起来痛苦;放在一个init文件里,所有可调量一目了然,改完重跑一遍脚本就行。
关于求解器选择,YALMIP加CPLEX确实是最省事的组合,写约束和目标几乎和数学公式一一对应。但有个现实问题:如果以后要发给别人跑代码,对方不一定装了YALMIP和CPLEX。所以我的做法是先用YALMIP把算法逻辑跑通验证没问题,再改成纯quadprog实现,发布出去的版本不依赖任何额外工具箱。这样代码的普适性强很多,别人拿到手装个Matlab就能跑。
3.2 核心循环:下层MPC滚动优化怎么实现
下层MPC的每个控制周期都要做这几件事:读取当前SOC、构造预测矩阵、构建QP问题、调用求解器、取第一步控制量执行、更新状态。以下是简化的核心循环结构:
for k = 1:T_total % 当前状态 xk = [SOC_b_history(end); SOC_sc_history(end)]; % 未来Np步的储能总功率参考 P_ref_vec = P_ref_total(k : min(k+Np-1, T_total))'; % 求解MPC优化问题 [u_opt, exitflag] = lower_mpc_solve(xk, P_ref_vec, param); % 只取第一步执行 P_b_ref = u_opt(1); P_sc_ref = u_opt(param.n_u + 1); % 用模型更新实际SOC(仿真环境) SOC_b_history(end+1) = SOC_b_history(end) - (Ts/(C_b*U_b)) * P_b_ref; SOC_sc_history(end+1) = SOC_sc_history(end) - (Ts/(C_sc*U_sc)) * P_sc_ref; end这里P_ref_total是上层调度给出来的储能总功率参考序列,在仿真开始时一次性加载,时间对齐非常重要。我在这踩过一个很隐蔽的坑:上层时间尺度是15分钟,下层是1秒,直接把上层的P_ref序列按索引赋值给下层,结果下层每隔900秒才更新一次参考值,中间的波动完全没管。后来我用了时间戳对齐,把上层序列插值到秒级,问题才解决。
3.3 求解函数内部的矩阵构建要点
MPC求解函数的核心是把优化问题写成quadprog能吃的标准形式。状态预测的矩阵化展开是新手最容易卡住的地方。定义预测矩阵Phi和Gamma,状态预测表达为:
X_pred = Phi * xk + Gamma * U
其中X_pred是未来Np步的SOC预测序列,U是未来控制序列。构造方式可以用循环:
Phi = zeros(n_x * Np, n_x); Gamma = zeros(n_x * Np, n_u * Np); for i = 1:Np A_pow = A^i; Phi((i-1)*n_x+1 : i*n_x, :) = A_pow; for j = 1:i Gamma((i-1)*n_x+1 : i*n_x, (j-1)*n_u+1 : j*n_u) = A^(i-j) * B; end end目标函数写成标准二次型min 1/2 * U' * H * U + f' * U之后,H矩阵由预测模型和权值矩阵共同构成:
H = Phi' * Q * Phi + R
这里有个特别容易出的问题:quadprog的目标函数是1/2 * U' * H * U,如果直接把Phi' * Q * Phi赋值给H,结果会比预期偏下一倍,因为quadprog内部默认乘了1/2。正确做法是H = 2 * (Phi' * Q * Phi + R),或者把权值矩阵按2倍系数设进去。我一开始在这个细节上栽过跟头,仿真出来的功率输出偏小,查了很久才发现是系数问题。
3.4 上层调度MPC的实现思路
上层调度MPC和下层的代码逻辑很相似,区别在于时间尺度、决策变量范围、目标函数内容。上层的采样步长是15分钟,预测时域通常取24或48个点,对应6到12小时。决策变量除了电池和超级电容功率,还包含并网交换功率,变量维度比下层大不少。
目标函数以经济性为主,电价信号是核心。分时电价下,MPC会倾向于在电价低的时段给储能充电,在电价高的时段放电,同时还要照顾SOC的持续性,避免在电价高峰前SOC已经耗尽。我实现时把成本函数写成:
J_upper = Σ ( price[k] * P_grid[k] * Ts_up + lambda_soc_b * (SOC_b[k]-SOC_ref_b[k])² )
代价函数里加SOC回中项是有讲究的。如果没有这一项,优化器很容易把SOC推到头,用满全部容量,表面上看经济性最优,但实际运行中一旦预测偏差出现,就没有调节余量了。加一个中等权重的SOC回中项,相当于给储能留一点“安全垫”,整体鲁棒性会好很多。
3.5 Simulink联调时的三个关键选择
纯脚本仿真跑通之后,如果要发论文或者做更接近实际的分析,一般还要搭Simulink模型。三个关键点值得注意。
第一个是MPC控制器如何嵌入。最灵活的方式是用MATLAB Function模块,把下层MPC求解函数封装进去。但有一个硬约束:嵌入到Simulink的代码最终要支持C代码生成,而quadprog是不支持代码生成的。解决方式有两种,要么用MPC Toolbox自带模块,要么自己实现一个固定求解器。我推荐后一种,因为MPC Toolbox的模块自由度有限,很多自定义约束加不进去。
第二个是自己写求解器时的选择。对HESS这种小型QP,ADMM算法非常合适,实现简单、迭代速度快、可编译。我实测用ADMM求解Np为10的MPC问题,单步求解时间在十几毫秒量级,完全能满足秒级控制周期的实时性要求。此处也可以使用OSQP,性能更好但需要额外的MEX文件。
第三个是底层变换器建模。纯脚本里可以用一阶惯性环节近似,但在Simulink里想看到更真实的母线电压动态,建议用Simscape Electrical搭建电池和超级电容模型,变换器用受控电流源简化,实际输出接一个电流环PI控制直流母线电压。MPC输出功率参考,然后换算成电流参考给PI环,这样控制链路才是完整的。
3.6 结果可视化要画什么
一套仿真跑完,哪些图画出来才有说服力?我给个常用清单:
- 负荷、光伏、并网功率时序对比图
- 电池和超级电容各自的功率曲线,与储能总功率叠加展示
- SOC轨迹图,重点看有没有越限
- 母线电压波动对比(MPC控制 vs 无控制)
- 电池功率变化率曲线,直接反映保护效果
- 经济性对比表格:总运行成本、电池等效循环次数、功率波动方差
画图时注意把MPC方案和基准方案放一起对比。基准方案可以用低通滤波功率分配,也可以用规则控制。对比这件事非常重要,单看MPC自己的曲线看不出优劣,有对照组才有说服力。
4. 参数整定与调优实录
4.1 预测时域Np、控制时域Nc、采样时间怎么定
这几个参数直接决定MPC的性能和计算量,没有万能公式,但有几个经验法则。采样时间由系统的动态特性和执行器能力决定,下层建议0.1到1秒,取1秒配合秒级负荷波动是常用选择;上层建议15分钟到1小时,如果要配合分时电价,至少取15分钟才能分辨电价边界。
预测时域Np的选择要按波动周期来倒推。先看负荷或光伏偏差的主波动周期,如果主要波动周期是60秒,采样1秒时Np至少要到15到30才能“看得到”这个波动的影响。Np太小,MPC反应迟钝;Np太大,后段预测误差累积,反而会带来错误的控制量。我见过有人把Np设到100,结果后30步的预测全是噪音,控制器被未来不存在的波动牵着走,效果比Np=20差得多。
控制时域Nc建议设1到3。Nc是控制量可变的步数,Nc以后控制量保持不变。由于目标函数里已经有了爬坡惩罚项,本身就限制了控制量的变化,Nc设太大只会增加决策变量和计算量,控制效果几乎没有提升。我做实验时Nc从1调到5,输出差别很小,但求解时间多了将近一倍,所以一般取1或2足够。
4.2 权值矩阵的调整顺序
调参是MPC最像“做实验”的部分。我的顺序是先把物理量归一化,再逐个目标按权重调整。归一化非常关键,SOC范围是0到1,功率是几千瓦到几百千瓦,如果不归一化直接放进同一个目标函数,功率项数值上完全淹没SOC项,优化器会无视SOC状态。把功率除以额定功率基准值,SOC偏差也归一化到同样量级,然后权值就可以在0.1到10之间细调。
调权顺序上,先把q1功率跟踪项调大,保证储能总功率能准确跟上参考,这和控制器基础功能直接相关;然后加q2电池爬坡惩罚,看功率曲线是否平滑,超级电容是否承担了高频部分;再调q3和q4让SOC别贴边界。每调完一个权值,跑一次仿真,对比一下功率曲线和SOC轨迹再继续下一个。一次只动一个参数也是铁律,同时调好几个权值,出了问题都找不到是谁引起的。
最终权值调节可以参考这个速查方向:
| 参数 | 常见范围 | 作用 | 调大后效果 |
|---|---|---|---|
| q1 | 5~30 | 功率跟踪 | 更激进地满足指令 |
| q2 | 10~50 | 电池爬坡惩罚 | 电池动作更平缓 |
| q3 | 1~10 | 电池SOC回中 | SOC更接近参考 |
| q4 | 1~10 | 超级电容SOC回中 | 超级电容不易贴边 |
4.3 判断结果好坏不能只看一条曲线
仿真做完,怎么评价这套系统好不好?只看功率跟踪曲线是不够的。我常规会整理几个量化指标:
电池总吞吐量是最直观的指标,单位是千瓦时,反映电池承担的总充放电量,吞吐量小说明超级电容分担了大量高频能量,电池压力小。电池越限次数和时间占比是硬指标,越限说明约束没守住,可能对应MPC的软约束惩罚不够大。母线电压波动方差反映整体控制品质,方差小说明功率平衡做得好。系统总运行成本是上层调度的评价标准,成本降低是经济性的最终体现。超级电容SOC最低值如果经常跌到下限,说明超级电容的能量被榨干了,电池响应不及时或预测时域太短。
我做对比实验时喜欢把不同权值组合的结果整理成一张表,每列是一个方案的指标,一眼就能看出某个参数变化带来的是哪方面改善。这样写论文的时候说服力也强。
5. 常见问题与排查技巧实录
5.1 quadprog报错“不可行”怎么处理
这是MPC调试中遇到最多的报错。不可行问题的本质是约束条件之间互相矛盾,在当前状态下找不到任何控制序列能同时满足所有约束。典型场景:超级电容SOC只有0.15,下限是0.1,预测时域10秒,而上层指令要求储能大功率放电100kW,MPC算出来无论怎么出力SOC都会在3秒内跌破0.1,整个求解就直接失败。
处理不可行最有效的方案是引入松弛变量,把硬约束变成软约束。具体做法是给SOC约束加一个非负松弛向量,约束条件写成SOC_min - slack ≤ SOC ≤ SOC_max + slack,目标函数里加上一个很大的惩罚系数乘以松弛量的平方。这样求解器在发现约束无法满足时,不再直接放弃,而是选择“尽量贴近约束”的解,控制量会主动降下来避免越限。这属于MPC标准做法,做法上也很成熟。
我自己的代码里对SOC下限的软约束惩罚系数取100,对上限取80,实测效果是SOC偶尔会短暂越限几个百分点,但功率输出不会间断,整体稳定性比硬约束好很多。
5.2 电池功率指令抖动得厉害
现象是P_b控制量在相邻步之间来回大幅跳动,功率曲线像锯齿一样,看着就心疼电池。最直接的原因是目标函数里缺少电池爬坡惩罚项,或者q2权重设了但没生效。排查时先检查目标函数里有没有(q2 * deltaP_b²),再看构造f向量时有没有把初始时刻的上一步功率带入。
还有一个特别隐蔽的原因容易忽略:控制序列取错行。MPC求解结果U_opt是一个长度为2*Np的向量,排列方式通常是[P_b(1), P_sc(1), P_b(2), P_sc(2), ...]。如果代码里误取了U_opt的第二个P_b,也就是未来第二步的控制量用到当前时刻,控制序列整体错位,输出就剧烈抖动。我用打印每一时刻P_b指令的方式排查了半天,才意识到索引写错了。这个bug非常容易发生在矩阵拼接比较多的代码里,写完索引一定要手动检查。
5.3 超级电容SOC长期贴边界不回来
超级电容SOC长时间顶在上限或压在下限,说明MPC对超级电容的SOC缺乏回中动力。常见原因有两个:q4权重设太小,优化器觉得SOC偏离参考也无所谓;或者上层给的P_ref高频分量太多,远超超级电容的能量吞吐能力,导致它在每个周期都被榨干。
解决思路一方面是把q4调大,或者在目标函数末尾加一个末端惩罚项,专门惩罚预测时域末端的SOC偏差,相当于强制MPC为将来留有余量。另一方面是检查上层调度,如果上层生成的总功率指令本身剧烈波动,等于把太多高频分量甩给储能层,这时候应该在上层目标函数里加入P_ref变化的惩罚,或者对并网交换功率设置爬坡率,让储能系统面对的需求本身不要那么苛刻。
5.4 仿真计算太慢,一天跑不完
长时仿真慢是常态,但能优化。首先,每次调用MPC求解时重复构造H矩阵、f向量非常浪费,预测模型矩阵是不变的,离线算好存入param结构体,每次只更新f向量的线性部分,速度能快不少。
其次,求解器选型影响巨大。YALMIP+CPLEX适合小规模验证,跑大规模长仿真效率不如直接用OSQP或ADMM。我自己用ADMM实现后,同一个仿真从原来的一天缩短到不到两小时。
还有个实用技巧:设置触发机制,只有功率偏差超过阈值才重新求解MPC,否则保持上一时刻的控制量不变。MPC本身是滚动优化,小偏差下重新计算不会带来本质提升,但能省大量时间。在纯脚本仿真里尤其管用,5000个控制周期如果只在2000个时刻触发求解,整体速度能再快一倍。
5.5 问题速查表
| 症状 | 可能原因 | 排查方向 |
|---|---|---|
| 求解不可行 | SOC初值越限、约束互相矛盾 | 引入松弛变量、软约束 |
| 电池功率抖动 | 缺爬坡惩罚或控制序列取错行 | 检查权重和索引 |
| SOC贴边不回来 | q3/q4偏小 | 提高权重、加末端惩罚 |
| P_ref和实际功率对不上 | 时间尺度没对齐 | 统一时间戳、插值处理 |
| 求解慢 | 矩阵重复构造 | 离线缓存、换ADMM |
| 脚本和Simulink结果不一致 | 单位或信号未对齐 | 检查单位换算和数据类型 |
最后说点实际体会
做这套双层MPC系统这么久,我最大的感受是:MPC的公式推导其实不难,真正的坎在于把不同时间尺度的系统层“合”起来跑通。上层每15分钟出一次调度结果,下层每1秒执行一次MPC,两层数据交接稍不注意就会差半个采样周期,导致SOC参考轨迹和实际控制脱节。后来我把所有预测数据统一打上时间戳,再用一个数据结构体在两层之间传递,问题才算彻底解决。
还有一个心得想分享给做Matlab仿真的朋友:这类研究代码,能跑通比写得多漂亮更重要。发代码或者跟别人交流的时候,尽量用Matlab基础工具箱、用清晰的函数模块,不要依赖一长串第三方工具箱,否则别人拿到手光是配环境就劝退了。我们做的是控制系统研究,核心价值在算法逻辑和参数设计的合理性,不在求解器调用的花哨程度。