4. 联合仿真原理
PreScan 与 Simulink 的联合仿真,本质上不是“两个软件互相调用”,而是把 PreScan 构建的虚拟交通场景与传感器模型,编译成一个可在 Simulink 中运行的 S-Function 模块,由 Simulink 作为主求解器统一推进仿真时间。理解这条主线,就能看清通信机制、接口形态、步长同步与数据交换之间的因果关系。
一、通信机制:编译期绑定 + 运行期端口交换
PreScan 与 Simulink 的通信分为两个阶段。第一阶段是编译期绑定:在 PreScan GUI 中完成场景搭建、车辆动力学配置、传感器(雷达、摄像头、激光雷达、GPS/IMU)参数设置后,执行 “Build” 生成 C 代码与 S-Function 描述文件,并自动创建或更新对应的 Simulink 模型(.slx)。此时 PreScan 场景被“固化”为一个模块,而不是运行时动态查询。
第二阶段是运行期端口交换:Simulink 在每个仿真步长调用该 S-Function 的 mdlOutputs、mdlDerivatives 等回调,PreScan 侧计算车辆位置、姿态、传感器探测结果,并通过模块的输出端口交给 Simulink 中的控制算法;控制算法算出的油门、制动、转向又通过输入端口回传给 PreScan 车辆模型。整个闭环就在端口数据的一来一回中完成。
二、S-Function 接口:端口即契约
S-Function 是 Simulink 提供的系统函数扩展机制,PreScan 生成的模块正是遵循这一规范。对使用者而言,最需要关注的是端口契约:输入端口接收来自 Simulink 控制算法的指令,输出端口提供 PreScan 计算出的车辆状态与传感器目标信息。常见端口内容如下表所示。
| 端口方向 | 典型信号 | 物理含义 | 常见单位 |
|---|---|---|---|
| 输入(Simulink → PreScan) | Throttle | 油门开度指令 | 0~1 或 % |
| 输入(Simulink → PreScan) | Brake | 制动压力或踏板指令 | 0~1 或 bar |
| 输入(Simulink → PreScan) | Steering | 前轮转角指令 | rad 或 deg |
| 输出(PreScan → Simulink) | Position / Pose | 车辆全局坐标与姿态 | m、rad |
| 输出(PreScan → Simulink) | Velocity / YawRate | 纵向速度与横摆角速度 | m/s、rad/s |
| 输出(PreScan → Simulink) | Sensor Targets | 雷达/摄像头探测到的目标距离、方位、相对速度 | m、rad、m/s |
接口一旦生成,端口数量、数据类型和维度就固定下来。若在 PreScan 中增删传感器或改变输出项,必须重新 Build,否则 Simulink 侧会出现端口不匹配或维度错误。
三、仿真步长同步:谁决定时间,谁必须服从
联合仿真中最容易出问题的是步长。Simulink 是主求解器,它决定仿真时间如何推进;PreScan 的 S-Function 在每个采样时刻被调用,因此 PreScan 侧的计算必须与 Simulink 步长匹配。若 Simulink 使用变步长求解器(如 ode45),而 PreScan 场景或传感器内部按固定周期更新,就可能出现“Simulink 已经走到下一步,PreScan 还没更新”的错位。
工程上推荐的做法是:联合仿真优先使用定步长离散求解器,例如 Fixed-step discrete,步长与 PreScan 传感器更新周期保持一致或成整数倍关系。典型配置如下:
Solver: Fixed-step
Solver type: Discrete (no continuous states)
Fixed-step size: 0.01 s % 对应 100 Hz
PreScan sensor update rate: 100 Hz
Stop time: 20 s
如果控制算法包含连续状态,也可以使用 ode4 等定步长连续求解器,但步长仍需与 PreScan 侧保持一致。变步长并非绝对不能用,但必须确认 PreScan 模块支持在任意时刻被调用,否则应改为定步长。
四、数据交换的时序与案例场景
以一个 AEB 联合仿真为例:Simulink 中搭建 AEB 控制算法,输入来自 PreScan 输出的前车距离与相对速度,输出为制动指令。每个仿真步长的执行顺序是:
- Simulink 求解器到达当前时刻
t; - 调用 PreScan S-Function 的
mdlOutputs,PreScan 计算本车与前车位置、传感器探测结果; - 输出端口将距离、相对速度传给 AEB 算法;
- AEB 算法计算制动量,通过输入端口写回 PreScan 车辆模型;
- Simulink 推进到
t + Δt,进入下一循环。
这个顺序说明:同一时刻内,PreScan 先输出、Simulink 后输入,控制算法看到的是当前时刻的传感器信息,制动指令在下一时刻才作用于车辆。若在算法中误以为制动会立即改变本时刻距离,就会产生“控制超前”的错觉。
五、常见误区与复盘
- 误区一:把 PreScan 当主控。 实际上 Simulink 才是主求解器,PreScan 模块只是被调用者,仿真启停、步长、终止条件都由 Simulink 决定。
- 误区二:改完 PreScan 场景不重新 Build。 场景、传感器、端口任何变化都必须重新编译,否则 Simulink 仍运行旧版本 S-Function。
- 误区三:步长随意设置。 Simulink 步长大于 PreScan 更新周期,会丢失传感器帧;小于更新周期,则重复读取同一帧,造成控制抖动。
- 误区四:忽略端口维度。 传感器目标数量变化时,输出端口维度可能改变,需在 Simulink 中同步调整或使用可变维度信号。
掌握通信机制、S-Function 端口契约、步长同步规则和数据交换时序,就抓住了 PreScan 与 Simulink 联合仿真的骨架。后续无论是接入 AEB、ACC 还是路径跟踪算法,都可以在这套骨架上替换控制模块,而不必重新理解底层通信。