4、联合仿真接口配置:CarSim S-Function模块、输入输出信号定义、通信协议设置
好,咱们接着往下聊。上一章我们把CarSim和MATLAB的环境搭好了,也跑通了第一个简单的联合仿真。但说实话,那个只是“能跑”,离真正的工程应用还差得远。这一章,咱们要深入进去,看看联合仿真的“接口”到底是怎么一回事。
我个人习惯把联合仿真比作两个人合作搬东西。一个人(CarSim)负责搬,另一个人(MATLAB/Simulink)负责指挥。那他俩怎么沟通?总得有个对讲机吧?这个对讲机,就是咱们今天要讲的接口配置。
4.1 CarSim S-Function模块:联合仿真的“翻译官”
CarSim本身是个独立的软件,它不认识Simulink的方块图。Simulink也不懂CarSim的数学模型。那怎么办?中间需要一个“翻译官”。这个翻译官就是CarSim S-Function模块。
你想想看,S-Function是Simulink里的一种特殊模块,它允许你用C、C++或者MATLAB代码来定义自己的算法。CarSim公司很聪明,他们就把自己的车辆动力学模型封装成了一个S-Function。这样,在Simulink里拖一个S-Function模块进来,就相当于把整个CarSim的求解器请进了你的仿真环境。
核心要点:CarSim S-Function模块不是CarSim软件本身,而是CarSim模型在Simulink里的一个“代理”。它负责在每一个仿真步长里,接收Simulink发来的控制信号(比如方向盘转角、油门、刹车),然后调用CarSim的求解器算出车辆状态,再把结果(比如车速、横摆角速度)送回给Simulink。
我记得刚开始带团队的时候,有个小伙子死活搞不明白,为什么他改了CarSim里的参数,Simulink这边没反应。后来发现,他忘了重新生成S-Function。嗯,这里要敲黑板:每次修改CarSim模型后,必须重新生成S-Function,Simulink那边才会更新。
4.2 输入输出信号定义:你得告诉CarSim你要什么
S-Function模块放上去了,但还没完。你得告诉它:Simulink这边要送哪些信号进去?CarSim那边要送哪些信号出来?这就是输入输出信号的定义。
在CarSim里,有一个专门的界面叫“Send to Simulink”和“Import from Simulink”。说白了,就是定义接口的“接线图”。
4.2.1 输入信号(Import from Simulink)
输入信号,就是Simulink发给CarSim的控制指令。常见的输入信号有:
- 方向盘转角(Steer_L1, Steer_R1):单位一般是度(deg)。注意,CarSim里方向盘转角和车轮转角是分开的,有转向传动比的关系。
- 油门开度(Throttle):0到1之间的无量纲数。0是松油门,1是地板油。
- 制动主缸压力(Brake_MC):单位一般是MPa。或者你也可以用制动踏板位移(Brake_Pedal),0到1。
- 挡位(Gear):整数,比如1、2、3、4、5、6。0表示空挡,-1表示倒挡。
我的小技巧:我习惯把输入信号的数量控制在10个以内。太多了,模型会变得很乱,而且容易出错。如果控制策略很复杂,我会在Simulink里先做一个“信号打包”的子系统,把多个控制信号合并成一个总线信号,再送给CarSim。这样接口清爽很多。
4.2.2 输出信号(Send to Simulink)
输出信号,就是CarSim算出来的车辆状态,反馈给Simulink。常见的输出信号有:
- 车辆纵向速度(Vx):单位m/s。这是最常用的信号,没有之一。
- 车辆横向速度(Vy):单位m/s。侧滑分析时必看。
- 横摆角速度(Yaw_Rate):单位deg/s。稳定性控制的核心。
- 质心侧偏角(Beta):单位deg。ESP算法里经常用到。
- 四个车轮的转速(Wheel_Speed_FL, FR, RL, RR):单位rad/s。做ABS或者TCS时,这个信号是必须的。
- 车辆位置(Xo, Yo):单位m。做路径规划或者轨迹跟踪时用。
我曾经犯过一个低级错误:做车道保持辅助(LKA)仿真时,我忘了把“车道线偏移量”这个信号从CarSim里导出来。结果Simulink里的控制器一直收不到反馈,方向盘乱打。查了半天才发现是输出信号没定义全。所以,在开始仿真前,一定要列一个信号清单,把输入输出都核对一遍。
4.3 通信协议设置:别让数据“丢包”
信号定义好了,接下来就是通信协议。说白了,就是CarSim和Simulink之间怎么“说话”。
CarSim支持多种通信方式,最常用的是共享内存(Shared Memory)和TCP/IP。
| 通信方式 | 特点 | 适用场景 |
|---|---|---|
| 共享内存 | 速度快,延迟低,但只能在同一台电脑上运行 | 单机仿真,实时性要求高(如HIL) |
| TCP/IP | 可以跨电脑、跨网络,但延迟稍高 | 分布式仿真,或者CarSim跑在另一台机器上 |
我个人习惯用共享内存。为什么?简单、快。你想想看,联合仿真本身计算量就大,如果通信再慢一点,仿真速度会让人崩溃。共享内存就像两个人面对面说话,几乎没有延迟。TCP/IP就像打电话,中间还得经过交换机,总归慢一拍。
避坑指南:我曾经在做一个实时仿真项目时,用了TCP/IP通信。结果发现,当仿真步长小于1毫秒时,数据经常“丢包”——Simulink这边收不到CarSim的反馈,导致仿真中断。后来换成共享内存,问题立刻解决。所以,如果你的仿真步长很小(比如0.5ms或1ms),强烈建议用共享内存。
在CarSim里设置通信协议很简单:在“Send to Simulink”和“Import from Simulink”界面里,有一个下拉菜单让你选“Shared Memory”还是“TCP/IP”。选好之后,CarSim会自动生成一个S-Function的配置文件(.m文件),你把这个文件放到Simulink模型所在的文件夹里就行了。
4.4 实战:手把手配置一个联合仿真接口
光说不练假把式。咱们来走一遍完整的配置流程。
- 打开CarSim模型:随便选一个已有的车型,比如“Indy_IndyCar”。
- 设置输入信号:在“Import from Simulink”里,添加“Steer_L1”、“Throttle”、“Brake_MC”三个信号。注意单位要选对。
- 设置输出信号:在“Send to Simulink”里,添加“Vx”、“Vy”、“Yaw_Rate”、“Xo”、“Yo”五个信号。
- 选择通信协议:在“Send to Simulink”界面里,把通信方式选为“Shared Memory”。
- 生成S-Function:点击“Send to Simulink”界面里的“Create S-Function”按钮。CarSim会生成一个名为“simfile.sfun”的文件(名字可以自己改)。
- 在Simulink里调用:打开Simulink,从“User-Defined Functions”库里拖一个“S-Function”模块出来。双击它,在“S-function name”里填“simfile”(不带后缀)。
- 连接信号:把Simulink里的控制信号(比如正弦波模拟方向盘转角)连到S-Function模块的输入端口。把S-Function模块的输出端口连到示波器或者To Workspace模块。
- 运行仿真:设置好仿真时间,点击运行。如果一切正常,你会看到CarSim的动画窗口自动打开,车辆开始运动。
关键一步:在Simulink里运行仿真前,一定要确保CarSim软件是关闭的。因为S-Function模块会自动启动CarSim的求解器,如果CarSim已经打开了,反而会冲突。我第一次用的时候就被这个坑过——Simulink报错说“无法启动CarSim”,我还以为是软件装错了。
好了,接口配置就讲到这里。说白了,就是三步:定义信号、选择协议、生成模块。但每一步都有细节,细节决定成败。你想想看,如果信号单位搞错了,仿真结果就是错的;如果通信协议选错了,仿真可能跑不起来。所以,别嫌我啰嗦,多检查几遍总没错。