4. 联合仿真原理

PreScan 与 Simulink 的联合仿真,本质上不是“两个软件互相调用”,而是把 PreScan 构建的虚拟交通场景与传感器模型,编译成一个可在 Simulink 中运行的 S-Function 模块,由 Simulink 作为主求解器统一推进仿真时间。理解这条主线,就能看清通信机制、接口形态、步长同步与数据交换之间的因果关系。

核心结论:Simulink 是主控与积分器,PreScan 是被集成的场景/传感器执行体;两者通过 S-Function 的输入输出端口在每个仿真步长上交换数据,时间推进由 Simulink 的求解器统一裁决。

一、通信机制:编译期绑定 + 运行期端口交换

PreScan 与 Simulink 的通信分为两个阶段。第一阶段是编译期绑定:在 PreScan GUI 中完成场景搭建、车辆动力学配置、传感器(雷达、摄像头、激光雷达、GPS/IMU)参数设置后,执行 “Build” 生成 C 代码与 S-Function 描述文件,并自动创建或更新对应的 Simulink 模型(.slx)。此时 PreScan 场景被“固化”为一个模块,而不是运行时动态查询。

第二阶段是运行期端口交换:Simulink 在每个仿真步长调用该 S-Function 的 mdlOutputs、mdlDerivatives 等回调,PreScan 侧计算车辆位置、姿态、传感器探测结果,并通过模块的输出端口交给 Simulink 中的控制算法;控制算法算出的油门、制动、转向又通过输入端口回传给 PreScan 车辆模型。整个闭环就在端口数据的一来一回中完成。

PreScan × Simulink 联合仿真:S-Function 接口与步长同步 PreScan 侧(被集成) 场景 / 道路 / 交通流 World Model 传感器模型 Radar / Camera / LiDAR / GPS 车辆动力学模型 2D / 3D / 自定义 编译产物 .dll / .mex + S-Function 描述文件 Simulink 侧(主控) S-Function 模块 PreScan 场景接口 控制算法 AEB / ACC / 路径跟踪 信号记录与可视化 Scope / To Workspace 求解器 定步长 / 变步长 统一推进仿真时间 S-Function 接口 mdlInitializeSizes mdlOutputs / mdlDerivatives mdlUpdate / mdlTerminate 输入端口 ← 控制量 输出端口 → 状态/传感器 输出 输入 每个仿真步长:Simulink 调用 S-Function → 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 模块支持在任意时刻被调用,否则应改为定步长。

判断步长是否匹配的简单方法:在 Scope 中观察车辆位置或传感器目标距离曲线,若出现阶梯状跳变、周期性毛刺或目标丢失,往往说明 PreScan 更新周期与 Simulink 步长不一致。

四、数据交换的时序与案例场景

以一个 AEB 联合仿真为例:Simulink 中搭建 AEB 控制算法,输入来自 PreScan 输出的前车距离与相对速度,输出为制动指令。每个仿真步长的执行顺序是:

  1. Simulink 求解器到达当前时刻 t;
  2. 调用 PreScan S-Function 的 mdlOutputs,PreScan 计算本车与前车位置、传感器探测结果;
  3. 输出端口将距离、相对速度传给 AEB 算法;
  4. AEB 算法计算制动量,通过输入端口写回 PreScan 车辆模型;
  5. Simulink 推进到 t + Δt,进入下一循环。

这个顺序说明:同一时刻内,PreScan 先输出、Simulink 后输入,控制算法看到的是当前时刻的传感器信息,制动指令在下一时刻才作用于车辆。若在算法中误以为制动会立即改变本时刻距离,就会产生“控制超前”的错觉。

五、常见误区与复盘

  • 误区一:把 PreScan 当主控。 实际上 Simulink 才是主求解器,PreScan 模块只是被调用者,仿真启停、步长、终止条件都由 Simulink 决定。
  • 误区二:改完 PreScan 场景不重新 Build。 场景、传感器、端口任何变化都必须重新编译,否则 Simulink 仍运行旧版本 S-Function。
  • 误区三:步长随意设置。 Simulink 步长大于 PreScan 更新周期,会丢失传感器帧;小于更新周期,则重复读取同一帧,造成控制抖动。
  • 误区四:忽略端口维度。 传感器目标数量变化时,输出端口维度可能改变,需在 Simulink 中同步调整或使用可变维度信号。
排障顺序建议:先确认 Build 是否成功且模型已更新,再检查 Simulink 求解器类型与步长,最后核对端口连接与信号维度。多数“联合仿真跑不通”的问题,都集中在这三步之内。

掌握通信机制、S-Function 端口契约、步长同步规则和数据交换时序,就抓住了 PreScan 与 Simulink 联合仿真的骨架。后续无论是接入 AEB、ACC 还是路径跟踪算法,都可以在这套骨架上替换控制模块,而不必重新理解底层通信。