AI+Simulink学习

一、Simulink / Simscape 中的三种端口体系详解

——电气端口、物理信号端口与数值信号端口的本质区别

一句话总结
在 Simulink + Simscape 中,线不是线,端口不是端口
不同端口代表的是不同“物理世界”,混接一定会报错。

本文用于系统性梳理 Simulink 中三类端口的本质区别、连接规则和典型模块,适合作为长期复习用的技术笔记。


如果你只用过纯 Simulink,可能会觉得:

“信号就是一根线,接上就行了。”

但一旦你进入 Simscape(物理建模),Simulink 的世界会被严格划分为 多个“物理域”

  • 电压 ≠ 一个数字
  • 电流 ≠ 一个数字
  • 功率守恒 ≠ 随便算

👉 端口类型的存在,是为了保证物理一致性(Physical Consistency)


二、三种端口的总览对比

端口类型 所属世界 是否守恒 是否有单位 能否进 Scope
电气端口(Electrical Conserving Port) 物理建模
物理信号端口(Physical Signal, PS) 物理信号
数值信号端口(Simulink Signal) 数值计算

三、电气端口(Electrical Conserving Port)

1️⃣ 它是什么?

真实的电气连接端口,代表一个电气节点。

  • 满足 基尔霍夫电流定律
  • 满足 能量守恒
  • 端口本身 不携带“数值信号”

📌 本质:“物理连接点”


2️⃣ 常见模块

  • Resistor(电阻)
  • Capacitor(电容)
  • Inductor(电感)
  • Voltage Source / Current Source
  • Electrical Reference(地)
  • Voltage Sensor / Current Sensor(其 ± 端)

3️⃣ 端口特征

  • 在 MATLAB Engine 里体现为:
    • LConn
    • RConn
  • 不能直接接:
    • Scope
    • Gain
    • Sum
    • PS-Simulink Converter

4️⃣ 示例

Vdc ── R ── C ── GND

这里每一根线都是 电气端口之间的连接


四、物理信号端口(Physical Signal, PS)

1️⃣ 它是什么?

物理量的“数值表达”,但仍然属于 Simscape 世界。

  • 有明确物理意义
  • 有单位(V、A、N、Pa)
  • 不参与守恒计算

📌 本质:“带单位的物理量信号”


2️⃣ 它从哪里来?

通常来自 传感器模块

  • Voltage Sensor → 输出电压(V)
  • Current Sensor → 输出电流(A)
  • Force Sensor / Torque Sensor 等

3️⃣ 常见模块

  • Voltage Sensor(V 端)
  • Current Sensor(I 端)
  • PS-Simulink Converter(输入端)
  • PS Gain / PS Sum(Simscape 内部处理)

4️⃣ 示例

[Voltage Sensor] -> Physical Signal (V)


1️⃣ 它是什么?

普通的 Simulink 数值信号

  • 没有物理单位
  • 只是 double / array
  • 用于控制、算法、显示

📌 本质:“纯数值”


2️⃣ 常见模块

  • Scope
  • Gain
  • Sum
  • PID Controller
  • MATLAB Function

3️⃣ 示例

PS-Simulink Converter ──▶ Scope


六、域转换:三种端口如何“合法交互”

✅ 合法的转换路径(唯一正确方式)

Electrical Domain
↓(Sensor)
Physical Signal (PS)
↓(PS-Simulink Converter)
Simulink Signal


❌ 非法连接(必报错)

错误连接 原因
电气端口 → Scope 域不匹配
电气端口 → PS-SL 缺少传感器
PS 端口 → 电气端口 方向错误
电气端口 → Simulink 模块 物理规则被破坏

七、以 RC 电路测量电容电压为完整示例

正确结构

Vdc ── R ── C ── GND

├─ Voltage Sensor (+)
└─ Voltage Sensor (−)

Voltage Sensor (V)

PS-Simulink Converter

Scope


核心原则

任何物理量想“被看到”,都必须经过:
Sensor → PS → PS-Simulink Converter


如果你在做:

自然语言 → LLM → Simulink 模型

那么模型必须理解:

  • 哪些模块是 物理模块
  • 哪些是 传感器
  • 哪些是 信号处理模块
  • 哪些连接 绝对不能出现

否则就会生成:

❌ “画得出来,但跑不起来”的模型


九、可以写进系统 Prompt 的硬规则

1
2
3
4
5
Rules:
1. Electrical conserving ports can only connect to electrical conserving ports.
2. Physical quantities must be measured using sensors.
3. Physical Signals must be converted using PS-Simulink Converter before entering Simulink.
4. Never connect electrical ports directly to Simulink signals.

二、simulink获取某模块的路径

simulink中某个模块在库浏览器中的路径不是它真实的在simulink引擎中的路径,当我们使用.m代码或者pythpn matlab.engine去添加模块的时候,我们需要知道该模块的simulink引擎中的真实路径

方法一:使用gcb

  • 找到模块所属的上一级库,比如scope所属的上一级是sink库,右键sink库,选择打开sink库,打开后,用鼠标点击scope模块
  • 回到matlab命令行,输入gcb运行,即可看到输出的该模块的路径

方法二、使用get_param

  • 把你想要知道路径的模块拖到sinmulink界面中,用鼠标点击选中它
  • 回到matlab命令行,依次运行h = get_param(gcb, 'Handle')get_param(h, 'ReferenceBlock')
  • 输出的路径就是我们要的路径

知道路径,我们就可以使用add_block将模块添加到模型中,以下是一个RC电路的python代码,使用matlab.engine驱动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import matlab.engine

eng = matlab.engine.start_matlab()

model = 'rc_circuit'

eng.new_system(model, 'Model', nargout=0)
eng.open_system(model, nargout=0)

blocks = {
'SolverConfig': 'nesl_utility/Solver Configuration',
'Ground': 'fl_lib/Electrical/Electrical Elements/Electrical Reference',
'Vsrc': 'fl_lib/Electrical/Electrical Sources/DC Voltage Source',
'R': 'fl_lib/Electrical/Electrical Elements/Resistor',
'C': 'fl_lib/Electrical/Electrical Elements/Capacitor',
'PS2SL': 'nesl_utility/PS-Simulink Converter',
'Scope': 'simulink/Sinks/Scope',
'Voltage_Sensor': 'fl_lib/Electrical/Electrical Sensors/Voltage Sensor',
}

for name, path in blocks.items():
eng.add_block(path, f'{model}/{name}', nargout=0)

# 获取端口句柄
ph_vsrc = eng.get_param(f'{model}/Vsrc', 'PortHandles')
ph_r = eng.get_param(f'{model}/R', 'PortHandles')
ph_c = eng.get_param(f'{model}/C', 'PortHandles')
ph_gnd = eng.get_param(f'{model}/Ground', 'PortHandles')
ph_solver = eng.get_param(f'{model}/SolverConfig', 'PortHandles')
ph_ps2sl = eng.get_param(f'{model}/PS2SL', 'PortHandles')
ph_scope = eng.get_param(f'{model}/Scope', 'PortHandles')
ph_vsensor= eng.get_param(f'{model}/Voltage_Sensor', 'PortHandles')


eng.add_line(model, ph_vsrc['LConn'], ph_r['LConn'], 'autorouting', 'on', nargout=0)
eng.add_line(model, ph_r['RConn'], ph_c['LConn'], 'autorouting', 'on', nargout=0)
eng.add_line(model, ph_c['RConn'], ph_gnd['LConn'], 'autorouting', 'on', nargout=0)
eng.add_line(model, ph_gnd['LConn'], ph_solver['RConn'], 'autorouting', 'on', nargout=0)
eng.add_line(model,ph_vsrc['RConn'],ph_gnd['LConn'],'autorouting', 'on',nargout=0)
# Voltage Sensor connections
eng.add_line(model,ph_vsensor['LConn'],ph_c['LConn'],'autorouting', 'on',nargout=0)
eng.add_line(model,ph_vsensor['RConn'][0][1],ph_c['RConn'],'autorouting', 'on',nargout=0)
# Voltage Sensor -> PS2SL
eng.add_line(model,ph_vsensor['RConn'][0][0],ph_ps2sl['LConn'],'autorouting', 'on',nargout=0)
# -> Scope
eng.add_line(model,ph_ps2sl['Outport'],ph_scope['Inport'],'autorouting', 'on',nargout=0)


eng.save_system(model, nargout=0)