4. 实时模型构建基础
在桌面仿真中,Simulink 可以自由使用变步长求解器、连续状态和代数环,只要结果收敛即可。但 MicroAutoBox 上的实时模型运行在硬实时约束下:每个采样周期必须在下一个周期到来前完成全部计算,否则会触发超时(Overrun)。因此,把普通 Simulink 模型改造成可实时运行的模型,核心是四件事:固定步长求解器选择、代数环消除、模型分割、任务调度配置。本节围绕这四点展开,并给出可直接参考的配置示例。
一、固定步长求解器:实时模型的节拍来源
实时模型必须使用固定步长(Fixed-step)求解器,因为只有固定步长才能保证每个采样周期计算量可预测、执行时间可测量。MicroAutoBox 常用的求解器是 ode1(Euler)、ode4(Runge-Kutta)和 ode14x。选择依据是模型动态特性与实时性要求的折中:
ode1:每步只计算一次导数,计算量最小,适合快速原型中采样率较高、动态不剧烈的控制模型;缺点是精度较低,步长过大时容易发散。ode4:每步四次导数计算,精度明显优于 ode1,适合含连续状态(如电机、液压执行器)的模型;代价是单步计算时间约为 ode1 的 4 倍。ode14x:隐式求解器,适合刚性系统,但每步需要迭代,实时性最差,一般只在模型刚性很强且步长可放宽时使用。
固定步长值不是随意填写的。它必须满足两个条件:一是小于模型最小时间常数的 1/10~1/20,二是与 MicroAutoBox 的定时器基准对齐。例如控制模型最小时间常数为 5 ms,则步长取 0.5 ms 或 0.25 ms 较合适;若模型含 1 kHz PWM 载波,步长通常取 0.1 ms 或 0.05 ms。配置位置在 Simulink > Model Configuration Parameters > Solver:Solver 选 Fixed-step,Fixed-step size 填具体数值,Solver 选 ode4。
二、代数环:实时模型中最常见的“隐形炸弹”
代数环是指模型中存在一个闭环,环内没有状态或延迟,导致当前时刻的输出直接依赖当前时刻的输入。Simulink 在变步长下可以用迭代求解,但固定步长实时模型无法迭代,代数环会导致编译失败或运行结果错误。常见来源包括:
- 控制器输出直接反馈到自身输入,中间没有单位延迟或状态;
- 多个 Gain、Sum 模块构成无状态闭环;
- 使用
Algebraic Constraint模块或某些自定义 S-Function。
处理代数环的优先级是:先改结构,再考虑加延迟。改结构的典型做法是把直接反馈改为状态反馈,例如把 y = K*u 且 u = r - y 的闭环,改写为 y(k) = K*(r(k-1) - y(k-1)),即插入 Unit Delay 或 Memory 模块。插入延迟会引入一个采样周期的相位滞后,对控制带宽有影响,因此应尽量把延迟放在对相位不敏感的信号路径上,或通过提高采样率来补偿。
判断代数环是否消除,可以在 Simulink 中执行 Simulation > Update Diagram,若模型仍报 “Algebraic loop” 警告,则需继续定位。也可用 Simulink.BlockDiagram.getAlgebraicLoops 命令列出所有代数环路径。
三、模型分割:把大模型拆成可调度的任务
MicroAutoBox 的实时内核按任务调度模型,每个任务有独立的采样周期和优先级。模型分割就是把一个大的 Simulink 模型按采样率拆成多个子系统,每个子系统对应一个任务。分割原则是:
- 按采样率分组:同一采样率的模块放在同一子系统,避免不必要的 Rate Transition;
- 按功能分组:控制算法、信号采集、故障诊断、通信分别成组,便于单独调整优先级;
- 按计算量分组:把计算量大的模块放在低优先级任务,避免阻塞高优先级任务。
在 Simulink 中,分割通过 Subsystem 和 Rate Transition 实现。例如一个电机控制模型可拆为:1 ms 电流环、5 ms 速度环、10 ms 通信与诊断。跨速率信号必须经过 Rate Transition 模块,并设置 Ensure data integrity during data transfer 和 Ensure deterministic data transfer,前者保证数据一致性,后者保证传输时刻确定。
四、任务调度配置:让模型按节拍运行
在 MicroAutoBox 中,任务调度通过 dSPACE 的 RTI(Real-Time Interface)配置。每个任务需要设置:任务名、采样周期、优先级、堆栈大小。优先级数值越小优先级越高。典型配置如下:
Task Name Period Priority Stack
BaseTask 0.001 s 1 4096
SpeedTask 0.005 s 2 4096
CommTask 0.010 s 3 8192
DiagTask 0.050 s 4 8192
配置完成后,用 rti_build 生成实时代码并下载到 MicroAutoBox。运行后通过 ControlDesk 观察任务执行时间(Turnaround Time)和超时计数(Overrun Count)。若某任务执行时间接近其周期,说明该任务负载过重,需要拆分或优化;若 Overrun Count 持续增加,则必须降低该任务计算量或提高其周期。
五、一个可参考的配置检查清单
在把模型下载到 MicroAutoBox 之前,建议按以下清单逐项检查。该清单可直接用于项目评审或自检:
| 检查项 | 合格标准 | 常见问题 |
|---|---|---|
| 求解器类型 | Fixed-step,且步长与任务周期一致 | 误用 Variable-step,导致无法生成实时代码 |
| 代数环 | Update Diagram 无 Algebraic loop 警告 | 反馈路径缺少 Unit Delay |
| Rate Transition | 所有跨速率信号均经过 Rate Transition | 直接连线导致数据撕裂 |
| 任务优先级 | 高频率任务优先级数值更小 | 优先级反转,低优先级任务阻塞高优先级 |
| 执行时间 | 各任务执行时间不超过其周期的 70% | 单任务负载过重,Overrun 频发 |
| 堆栈大小 | 按任务复杂度分配,通信任务适当加大 | 堆栈溢出导致任务异常复位 |
完成上述改造后,模型即可进入实时运行阶段。实际调试中,建议先用 ControlDesk 观察各任务的 Turnaround Time 曲线,确认没有超时后再接入被控对象。若发现某个任务执行时间波动较大,通常是因为该任务内包含了条件分支或查表运算,可考虑把查表数据移到初始化阶段或改用更高效的插值方式。实时模型构建不是一次性的工作,而是随着模型功能增加需要持续维护的过程。