4. Simulink模型基础:创建第一个Simulink模型、常用模块库、信号线与总线、子系统与封装

说实话,很多刚接触dSPACE的朋友,上来就急着搞硬件在环,结果连Simulink模型都跑不利索。我见过太多人,模型画得跟蜘蛛网似的,信号线乱飞,子系统嵌套七八层,最后调试时自己都看不懂。嗯,咱们今天就把基础打扎实。

4.1 创建第一个Simulink模型

打开MATLAB,在命令行敲个 simulink,或者直接点工具栏上的Simulink图标。我个人习惯用快捷键,快很多。

新建一个空白模型,你会看到一个灰色的画布。这就是你的工作台。先别急着拖模块,我建议你先想清楚:这个模型要干什么?输入是什么?输出是什么?

举个例子,咱们做一个最简单的模型:正弦波输出

  1. Simulink Library Browser 里找到 Sources 库,拖一个 Sine Wave 出来。
  2. 再找 Sinks 库,拖一个 Scope 出来。
  3. 用鼠标把两个模块的端口连起来。嗯,就这么简单。
  4. 双击 Sine Wave,设置幅值为1,频率为2*pi(也就是1Hz)。
  5. 点运行,双击 Scope 看波形。

关键点:模型跑通了,但别高兴太早。你想想看,这个模型在dSPACE上跑的时候,Scope是看不到的。Scope只是仿真时用的调试工具。真正到硬件在环阶段,你得用 RTI(Real-Time Interface) 模块来替代它。

4.2 常用模块库:Sources, Sinks, Math Operations

这三个库,你玩dSPACE的话,几乎天天打交道。我按我的经验给你捋一捋。

Sources(信号源)

说白了,就是给模型提供信号的。常用的有:

  • Sine Wave:正弦波,做测试信号首选。
  • Constant:常数,比如给个偏置电压。
  • Step:阶跃信号,测系统响应速度用的。
  • From Workspace:从MATLAB工作空间读数据。我在项目中经常用它来导入实测的传感器数据。
  • From File:从.mat文件读数据。适合大数据量场景。

小技巧:用 From Workspace 时,数据格式必须是 [time, data] 的二维数组。我曾经因为格式不对,卡了整整一个下午。

Sinks(信号接收器)

信号最终要去哪?Sinks就是终点站。

  • Scope:示波器,仿真时看波形。
  • Display:数字显示,看数值。
  • To Workspace:把仿真结果存到工作空间,方便后续分析。
  • To File:存成.mat文件。
  • Terminator:终结符。有些信号你不关心,但又不能悬空,就用它。

注意:在dSPACE实时模型中,绝对不能直接用Scope。你得用 RTI Data Acquisition 模块来替代。否则模型编译都过不去。

Math Operations(数学运算)

加减乘除、三角函数、逻辑运算,全在这。

  • Add:加法器。可以设置多个输入。
  • Gain:增益。就是乘一个常数。
  • Product:乘法器。两个信号相乘。
  • Trigonometric Function:三角函数。sin、cos、tan等。
  • Abs:取绝对值。
  • Relational Operator:比较运算。大于、小于、等于。

我记得有一次做电机控制,需要计算 sin(theta) * cos(theta),直接用两个模块连起来就行。但要注意,Simulink的信号是向量化的,如果你不小心把维度搞错了,会报维度不匹配的错误。

4.3 信号线与总线

信号线,就是模块之间的连线。看起来简单,但坑不少。

信号线的基本操作

  • 连线:鼠标左键点住一个端口,拖到另一个端口。
  • 分支:在线上右键,选 Signal → Branch,或者按住Ctrl键拖拽。
  • 标签:双击信号线,输入名字。我强烈建议你给关键信号加标签,不然调试时根本不知道哪根线是干嘛的。
  • 颜色:右键信号线,选 Signal Properties,可以设置颜色。我习惯把控制信号标成红色,反馈信号标成蓝色。

总线(Bus)

当信号多起来,一根根线连会乱成一团。这时候就该用总线了。

总线,说白了就是把多个信号打包在一起。就像一根网线里包着8根铜线一样。

  • Bus Creator:把多个信号合并成一条总线。
  • Bus Selector:从总线里取出需要的信号。
  • Bus Assignment:修改总线里某个信号的值。

实战经验:我在做整车控制器模型时,把发动机转速、车速、油门踏板位置、刹车信号全部打包成一条 Vehicle Bus。这样整个模型看起来清爽多了。而且dSPACE的RTI模块也支持总线,可以直接映射到硬件IO。

使用总线时要注意:总线里的信号必须有唯一的名字。如果两个信号重名,Simulink会报错。我曾经因为复制粘贴模块,忘了改信号名,查了半天才找到问题。

4.4 子系统与封装

模型大了,就得拆。子系统就是用来做这件事的。

创建子系统

有两种方式:

  1. 自上而下:先拖一个 Subsystem 模块,然后双击进去,在里面画模型。
  2. 自下而上:选中一堆模块,右键选 Create Subsystem。Simulink会自动帮你打包。

我个人更喜欢第二种方式。先搭好功能模块,验证没问题了,再打包成子系统。这样逻辑更清晰。

子系统的好处

  • 模块化:每个子系统负责一个功能,比如 PID ControllerSignal Filter
  • 层次化:双击子系统可以看内部细节,返回上层看整体架构。
  • 复用性:做好的子系统可以复制到其他模型里用。

封装(Mask)

子系统默认是灰色的,端口也不直观。封装就是给它穿个衣服,让它看起来像个专业的模块。

右键子系统,选 Mask → Create Mask。你可以:

  • 设置图标:画个示意图,或者写个文字标签。
  • 添加参数:比如PID的Kp、Ki、Kd,可以在封装界面里设置,不用进子系统内部改。
  • 添加文档:写清楚这个模块是干嘛的,输入输出是什么。

封装小技巧:我习惯在封装里加一个 Help 按钮,点击后弹出使用说明。这样团队里其他人用我的模块时,不用来问我。省事。

封装参数传递

封装界面里设置的参数,怎么传到子系统内部的模块?

在封装编辑器的 Parameters 选项卡里,定义一个变量名,比如 Kp。然后在子系统内部,把 Gain 模块的增益值设为 Kp。这样,你在封装界面改 Kp,内部的 Gain 就会自动更新。

// 封装参数示例
// 参数名:Kp
// 提示:比例增益
// 默认值:1.0

避坑指南:封装参数名不要和MATLAB工作空间的变量重名。我曾经设了一个 t 作为参数名,结果和MATLAB的时间变量冲突了,模型跑出来的结果全是错的。查了两天才发现。

4.5 小结

嗯,这一章内容不少。咱们从创建第一个模型开始,到常用模块库,再到信号线和总线,最后是子系统和封装。这些都是Simulink建模的基础,也是dSPACE联合仿真的前提。

你想想看,如果连信号线都连不明白,子系统都不会封装,那到了dSPACE实时仿真阶段,模型一跑起来,各种时序问题、数据溢出问题,你根本无从下手。

所以,我建议你花点时间,把今天讲的内容亲手练一遍。建一个简单的模型,用上总线,再封装成子系统。相信我,这个基本功打好了,后面的路会顺很多。

下一章,咱们开始讲dSPACE的RTI模块,那才是真正进入硬件在环的世界。