3. 常用基础模块(一):数学运算、逻辑关系与信号路由

各位好,欢迎来到第三章。今天我们要聊的,是Simulink建模里最基础、也最常用的一批模块。说白了,就是搭积木时那些最基础的砖块——数学运算、逻辑判断、还有信号怎么走线。

你可能觉得这些太简单了,不就是加加减减嘛。但我在项目里见过太多因为基础模块用错导致的bug,尤其是信号路由那块,新手特别容易踩坑。咱们一个一个来看。

3.1 数学运算模块:Add, Product, Gain

这三个模块,你几乎在每个模型里都会用到。我个人的习惯是,先把它们拖出来,再慢慢连。

3.1.1 Add(加法器)

Add模块不只是做加法。它可以配置成加、减、或者加减混合。双击打开,在“List of signs”里,用“+”和“-”控制每个输入端口的符号。

我的习惯: 如果只是两个信号相减,我更喜欢用Add模块,把第二个端口设成“-”,而不是用Subtract模块。因为Add模块的图标更清晰,团队里其他人一看就知道你在做什么。

举个例子,计算误差信号 error = target - actual:

Add模块配置:
  List of signs: +-
  输入端口:port1 = target, port2 = actual
  输出:error

3.1.2 Product(乘法器)

Product模块支持标量乘法、向量点乘、矩阵乘法。默认是“Element-wise”模式,也就是对应元素相乘。

我曾经在做一个扭矩估算模型时,把两个向量用Product做点乘,结果算出来的扭矩值一直不对。查了半天才发现,Product默认是元素乘,我需要的是矩阵乘。改成“Matrix”模式就好了。

Product模式 适用场景 注意事项
Element-wise 标量乘法、向量对应元素乘 输入维度必须一致
Matrix 线性代数运算、状态空间 维度需满足矩阵乘法规则

3.1.3 Gain(增益模块)

Gain模块就是一个乘法器,但它只乘一个常数。你可以在参数里直接写数值,也可以用变量名,比如 Kp、Ki。

关键点: Gain模块的乘法顺序很重要。如果是标量乘向量,无所谓。但如果是矩阵乘向量,你要在参数里指定“Multiplication”模式:Matrix(K*u) 还是 Matrix(u*K)。

我建议,凡是固定的比例系数,都用Gain模块,别用Product。因为Gain模块在代码生成时会被优化成一条乘法指令,效率更高。

3.2 逻辑与关系运算模块

逻辑模块用来做条件判断。ECU里到处都是逻辑——什么时候该开阀,什么时候该报警,全靠它们。

3.2.1 逻辑运算符:AND, OR, NOT

这些模块很简单,输入是布尔值(0或1),输出也是布尔值。但要注意,Simulink里的布尔信号和double信号不能直接连。你需要用“Data Type Conversion”模块转一下。

举个例子,一个简单的使能逻辑:

条件: (车速 > 0) AND (刹车未踩)
实现:
  车速 > 0 → Relational Operator (输出boolean)
  刹车信号 == 0 → Relational Operator (输出boolean)
  两个boolean → AND模块 → 输出使能信号
避坑指南: 我曾经在模型里直接用double信号连AND模块,结果仿真报错。Simulink不允许double直接进逻辑模块,必须先转成boolean。这个错误很隐蔽,尤其是从Excel导入参数时,一不小心就是double。

3.2.2 关系运算符:>, <, ==, !=

Relational Operator模块用来比较两个信号。输出是布尔值。你可以配置成大于、小于、等于、不等于等。

我个人习惯,在比较浮点数时,尽量避免直接用“等于”。因为浮点数精度问题,两个看起来相等的数,在计算机里可能差一点点。用“大于等于”或“小于等于”更安全。

3.3 信号路由模块:Mux, Demux, Bus Creator

这部分是新手最容易搞混的。Mux和Bus到底有什么区别?什么时候用哪个?我来给你讲清楚。

3.3.1 Mux 与 Demux

Mux把多个信号合并成一条向量信号。Demux是反过来,把向量拆开。

特点:

  • Mux出来的信号是向量,所有元素类型必须一致(比如全是double)。
  • Mux不保留信号名称。拆开后,端口名字自动变成 signal1, signal2。
  • Mux适合用在信号类型相同、且你不需要单独命名每个信号的场景。

举个例子,把三个传感器值合并成一个向量:

Mux配置:
  输入数量:3
  输入:sensor1, sensor2, sensor3 (都是double)
  输出:向量 [sensor1, sensor2, sensor3]

3.3.2 Bus Creator 与 Bus Selector

Bus Creator创建的是总线信号。总线里的每个信号可以有不同的数据类型,而且保留原来的名字。

特点:

  • Bus里的信号是结构体,不是向量。
  • 每个信号有自己的名字,用Bus Selector可以按名字提取。
  • Bus适合用在信号类型不同、或者你需要按名字访问的场景。
核心区别: Mux是向量,Bus是结构体。向量用索引访问,结构体用名字访问。在ECU代码生成时,Bus会生成结构体变量,Mux会生成数组。

我建议,在模型里尽量用Bus。因为Bus保留了信号名字,模型可读性更好。尤其是多人协作时,别人一看Bus Selector就知道你取了哪个信号。

3.3.3 什么时候用Mux,什么时候用Bus?

场景 推荐用 原因
信号类型相同,且不需要名字 Mux 简单,代码生成效率高
信号类型不同,或需要名字 Bus 可读性好,维护方便
需要传给MATLAB Function Bus MATLAB Function支持结构体输入
需要传给S-Function Mux S-Function处理向量更方便

3.4 知识结构图

下面这张图,帮你理清本章的核心脉络:

第三章知识结构图:常用基础模块 第三章:常用基础模块分类 数学运算模块 逻辑与关系运算 信号路由模块 Add(加法器) Product(乘法器) Gain(增益模块) AND / OR / NOT > / < / == / != Mux / Demux(向量) Bus Creator / Selector(结构体) 核心要点 Mux输出向量(索引访问),Bus输出结构体(名字访问) 逻辑模块输入必须是boolean,double需先转换

3.5 实战建议

嗯,到这里,基础模块就讲完了。最后给你几个实战建议:

  • 命名规范: 所有模块都改个有意义的名字,别用默认的“Gain1”、“Add2”。我见过一个模型里全是默认名,改个参数要找半天。
  • 信号标签: 用Signal Label给信号线命名。这样用Bus Selector时,名字会自动匹配,省得你一个一个敲。
  • 数据类型: 养成检查数据类型的习惯。双击信号线,看状态栏显示的类型。double、single、boolean混用,仿真可能不报错,但代码生成会出问题。
我的小技巧: 在模型里,我习惯把数学运算模块用蓝色背景,逻辑模块用红色背景,信号路由用绿色背景。这样一眼就能看出模型的结构。虽然Simulink不支持模块背景色,但我用注释框(Annotation)在模块旁边标颜色,团队里大家都觉得好用。