一、系统是怎么分工的
RT-LAB 把一次仿真拆到两台机器上做:上位机(Host PC) 管界面,实时目标机(Real-time target) 管计算。两边靠一条 TCP/IP 链路连着。
flowchart LR
subgraph HOST["上位机 Host PC(Windows)"]
M["MetaController<br/>RT-LAB 主程序"]
SC["SC_ 子系统<br/>示波器 / 旋钮 / 开关 / 显示"]
end
subgraph RT["实时目标机(RedHat Linux + FPGA)"]
SM["SM_ / SS_ 计算子系统<br/>按 CPU 核分配"]
MOD["电力系统模型、物理模型、控制算法"]
IO["I/O 板卡"]
end
M <-->|"TCP/IP,异步"| SM
SC --- M
SM --- MOD
MOD --- IO上位机上看到的是曲线和仪表,真正在算的是下位机。这条链路是异步的,界面刷新慢一点、快一点,都不影响目标机按自己的步长跑下去。
二、Simulink 模型
2.1 为什么一定要分子系统
在 RT-LAB 里跑 Simulink 模型,顶层不允许出现孤立的 Gain、Sum、Scope 这类模块和连线,顶层只能是几个子系统(subsystem)。设子系统有两个目的:
- 把计算部分和用户界面分开;
- 把不同的计算部分分到不同的 CPU 核上。
flowchart TB
subgraph BAD["不符合要求:顶层是零散模块"]
b1["Constant"] --> b2["Gain"] --> b3["Sum"] --> b4["Scope"]
end
subgraph OK["符合要求:顶层只有子系统"]
o1["SM_computation"] --- o2["SC_GUI"]
o3["SM_computation"]
o4["SS_plant1"] --- o5["SS_plant2"]
end子系统本身的含义没变:把一串模块封装进一个框里,画面上就清爽了,也好做层次化。区别只在于 RT-LAB 会给这些框赋予运行上的含义。
2.2 命名规则:SM、SS、SC
名字不是随便起的,前缀决定了它跑在哪里、占几个核。
| 前缀 | 干什么用 | 跑在哪 | 数量 | 占核 |
|---|---|---|---|---|
SM_xxx | 主运算系统:数学运算、I/O 模块、信号发生器、物理模型 | 目标机 CPU 核 | 只能 1 个 | 1 核 |
SS_xxx | 追加的运算系统,内容同 SM | 目标机 CPU 核 | 0 到多个 | 每个 1 核 |
SC_xxx | 界面:示波器、显示、手动开关、常数 | 上位机 | 0 到 1 个 | 不占核 |
SC_ 里不能有信号生成、不能有数学运算、不能放物理模型——它只是从计算子系统引出来的一段界面,跟下位机的核没有关系。
几种常见组合:
| SM | SS | SC | 说明 |
|---|---|---|---|
| 1 | — | — | 纯计算,没有界面 |
| 1 | n | — | 多核并行,没有界面 |
| 1 | — | 1 | 单核算,带上位机界面 |
| 1 | n | 1 | 多核并行 + 界面,最常见 |
flowchart LR
subgraph CORE1["CPU 核 1"]
SM["SM_xxx"]
end
subgraph CORE2["CPU 核 2"]
SS1["SS_xxx"]
end
subgraph CORE3["CPU 核 3"]
SS2["SS_xxx"]
end
SM <-->|"共享内存,同步"| SS1
SS1 <-->|"共享内存,同步"| SS2
PC["上位机 SC_xxx 界面"] <-.->|"TCP/IP,异步"| SM几条必须记住的结论:
- 顶层只允许一个
SM_; - 一个授权核只跑一个运算系统,
SS_加一个就多占一个核; - 计算子系统之间是同步通信,走共享内存;
- 运算系统和 GUI 系统之间是异步通信,走 TCP/IP;
- 信号可以是标量也可以是矢量,但类型必须是
double。
2.3 OpComm:进子系统的门
子系统之间、子系统和界面之间的每一路信号,都要经过一个 OpComm 模块才能接进来。位置在 Simulink 库里的 RT-LAB 模块库里。所有 SM、SS、SC 的输入都必须先过 OpComm,否则线连上了也跑不通。
flowchart LR
SC["SC_GUI<br/>2 个 OpComm"] -.->|"异步"| SM["SM_computation1<br/>2 个 OpComm"]
SC -.->|"异步"| SS3["SS_computation3<br/>2 个 OpComm"]
SS2["SS_computation2<br/>1 个 OpComm"] -->|"同步"| SM
SS3 -->|"同步"| SS2
SM -->|"同步"| SS3数 OpComm 的个数不用猜:进来几路、来自哪种系统,就配几个。上图中 SM 既收 SC 的异步信号又收 SS2 的同步信号,所以两个;SS2 只收 SS3 的同步信号,所以一个;SS3 两头都收,所以两个。
几个操作上的约束:
- 必须先把子系统建好、改好名字(SS / SM / SC),才能往里插 OpComm;
- 一个 OpComm 可以接多路输入,双击模块选输入数;
- SM / SS 里的 OpComm,收到的是实时同步信号;收到 GUI 的则是异步信号;
- SC 里通常一个就够,也可以多插(最多 25 个),多输入的 OpComm 按接收参数可以分成不同的接收组。
2.4 并行运算:先在纸上把死锁排掉
RT-LAB 每一步都要在两个核之间交换数据,谁等谁决定了这段代码是并行、串行,还是根本跑不起来。
先看状态量(state):输出只由上一拍的输入和输出算出来的量,就是状态量。能产生状态量的典型模块是 integrator 和 memory;gain 不算,因为它这一拍的输出完全由这一拍的输入决定。
| 模块 | 递推关系 | 有没有状态 |
|---|---|---|
| Integrator | y(z) = y(z-1) + x(z-1)·t | 有 |
| Memory | y(z) = x(z-1) | 有 |
| Gain | y(z) = A·x(z) | 无 |
知道哪些点是状态,就能判断回路能不能断开。四种典型连接:
死锁(跑不起来)
sm_subsystem [ 计算 ]──── 等 ss 的信号 ────╳
ss_subsystem [ 计算 ]──── 等 sm 的信号 ────╳
双方互相等,一步都走不完串行(能跑,最差)
时间 →
sm [ 计算 ][ 等 ss ][ 计算 ][ 等 ss ]
ss [ 等 sm ][ 计算 ][ 等 sm ][ 计算 ]
每一步都有一半时间在干等部分并行(能跑,凑合)
sm [ 计算 ][ gain ][ 等 ss ][ 余下的运算 ]
ss [ 等 sm ][ 计算 ]──────────[ 计算 ]
gain 那一步先把环路断开,两边就能重叠一段全并行(最好的情况)
sm [ 计算 ]────────[ 计算 ]
ss [ 计算 ]────────[ 计算 ]
信号交换前后各自有状态量兜住,两个核同时跑,谁也不等谁判断方法就一句:看环路上有没有状态量。有状态量,这一拍就可以用上一拍的值先算,等待被打断,并行成立;没有状态量,就只能等着对方这一拍算完。
2.5 仿真参数:定步长是硬要求
实时仿真要求每一步的耗时是确定的,所以只能用定步长(fixed-step)解算器。变步长解算器平时用着方便,它会自动算采样时间,但下一步要跑多久谁也说不准,这在实时系统里叫不确定(DETERMINISM 不成立),不能用。
配置面板里要改的就四项:
Configuration Parameters
├─ Solver
│ ├─ Type ................ Fixed-step ← 必须
│ ├─ Solver .............. ode4 / ode1 等任一定步长解算器
│ ├─ Fixed-step size ..... 按秒填,例如 1e-4
│ └─ Stop time ........... inf ← 一直跑,直到手动停止Stop time 写 inf,模型就会一直运行,由人来停,而不是跑到某个时刻自己结束。
2.6 先在 Simulink 里跑通,再上实时机
顺序别倒过来:先在 Simulink 里离线运行模型,确认没有任何报错,再去 RT-LAB 里编译、加载。离线都跑不动的模型,在实时系统里一定跑不动,而且那边报错更难查。
三、RT-LAB 界面
3.1 启动
主程序是 MetaController.exe,位置在 {RTLAB_ROOT}\Common\bin\。它以服务器的形式跑着,负责展示控制应用和控制器登录,界面从这里打开。
3.2 工作区的三层结构
Workspace 模型存放的文件夹
└─ Workbench 工作台,可以开一个或多个
└─ Perspective 构图界面
├─ View 列表导航(如 Project Explorer)或显示当前编辑器的属性
└─ Editor 编辑或浏览资源,可以是文本,也可以是图形View 是「看目录、看属性」的地方,Editor 是「改东西」的地方,一个 Perspective 里两者可以自由摆放。
3.3 建工程、加模型
建工程有三种入口:工具栏图标、菜单 File > New > RT-LAB Project、Project Explorer 里右键。输入名字之后,Next 可以把示例模型一起带进来,Finish 则是建一个空工程自己往里加。工作集(Working sets)用来把工程筛选、分组,工程多了不至于乱。
示例模型在 C:\OPAL-RT\RT-LABx.x.x\Examples。
已有的 .mdl 模型加进工程有两种方式,区别只在原件动不动:
| 方式 | 行为 | 什么时候用 |
|---|---|---|
| Link | 工程里放的是链接,改的就是原模型 | 模型只有一个工程在用 |
| Import | 复制一份到工作区文件夹 | 一处改坏不影响原件 |
打开模型也有两种:Edit 用默认版本的 MATLAB/Simulink,Edit with 指定版本——机器上装了好几个 MATLAB 时用得上。
3.4 目标机
添加目标机可以手填 IP,也可以点 Discover targets 自动搜同一网段在线的设备。加进来以后,右键编辑目标机,几组设置:
| 分组 | 内容 |
|---|---|
| Overview | General Information(通用信息)、Operations(运行) |
| Diagnostic | Operating System & Hardware、Tools |
| Simulation Settings | Multi-model、Embedded Mode、Date & Time |
| Software | 下位机软件版本:Install / Set as default / Uninstall |
3.5 编译:一条五段的流水线
点下 Build 之后,事情是按顺序走的:
flowchart LR
A["选下位机平台<br/>+ 软件版本"] --> B["模型分解<br/>每个 SM/SS/SC 生成一个 .mdl"]
B --> C["生成 C 代码<br/>调 MATLAB 代码生成器"]
C --> D["传输到目标机<br/>OpalD 负责搬文件"]
D --> E["目标机编译器<br/>编译并链接到实时处理器"]
E --> F["编译产物传回上位机<br/>等待加载"]几点值得留意:
- 分解是按顶层子系统切的,一个子系统一份
.mdl,各平台有自己的模板; - 传输由 RT-LAB 内部的 OpalD 完成,代码生成器产出的文件一并带走;
- 链接是在目标机上做的,不是在上位机;
- 编译通过不等于能跑,还要分配节点、加载。
3.6 分配子系统
同一个模型可以摊在一台目标机的多个核上,也可以摊在多台目标机上,上限是核数。
2 个子系统 / 1 台目标机 2 个子系统 / 2 台目标机
┌────────────────────┐ ┌──────────┐ ┌──────────┐
│ CPU0: SM_controller│ │ CPU0: SM │ │ CPU0: SS │
│ CPU1: SS_plant │ └──────────┘ └──────────┘
└────────────────────┘ 一个模型,两台机器各跑一个核3.7 运行
运行模式有三种:仿真(Simulation)、软件同步、硬件同步。选完之后依次是 Load(加载)、Execute(运行)、Reset(停止)。
工程浏览器里的图标会跟着状态变:目标图层显示当前平台,模型图层除了平台还带后缀,显示当前状态和目标机名,出错和警告也在这一列体现。
3.8 两个附加功能
嵌入式仿真:把模型烧进目标机,目标机一上电就自动跑,不用再开 RT-LAB。做法是选中模型、加载并运行,打开模型编辑器选中分配节点,在 Target Utilities 里点 Set as Embedded。之后在工程浏览器里展开目标机就能看到正在跑的嵌入式仿真,右键刷新可以更新列表。
偏好设置:Others… 菜单只有在高级性能(Advanced Capability)打开后才出现,从这里进 Preference Page,做更细的自定义。
四、高级功能
4.1 OpMonitor:看清每一步花了多久
OpMonitor 模块在 RT-LAB / Monitoring 库里,用来取模型的时间信息。它输出五个量,输入一个「重置超时」。
一个固定步长内部是这样切开的:
│←── 计算时间 ──→│←──── 冗余时间(同步等待)────→│
├───────────────────────────────────────────────┤
│◄────────────── 实际步长 ──────────────────────►│
步长起点 步长终点| 指标 | 含义 |
|---|---|
| 计算时间 | 这一拍真正算模型花掉的时间 |
| 冗余时间 | 算完之后空着、等同步的时间 |
| 实际步长 | 实际的这一拍总长度,与设定的步长比对 |
| 超时次数 | 实际步长超过设定值、导致跳步的次数 |
| 用户时间 | 用户自定义的计时 |
界面上这些量是微秒级的,单次监测看一拍,持续监测看一段。模型必须在运行中才能看。
4.2 超时与抖动
超时:某一拍没在步长内算完,这一拍会被跳过,模型的时间轴继续往前,数据上就出现一个空洞。一个子系统超时,往往带着下游一起超时(连锁超时)——比如 ss_plant1 超时,sm_controller 跟着超时一次。
抖动:步长实际长度的随机波动。用 RedHat 这类实时系统,正常抖动在 7 微秒上下。如果模型的计算时间已经贴着步长上限,这点抖动就足以造成随机超时,表现是隔三差五报一次超时,而不是稳定报错。
判断标准很简单:算出来的余量要明显大于抖动,别贴着跑。
4.3 工作台设置、变量表格、变量观测
- 工作台设置:给每组工程打标签、管理工程,配置存在工作区文件夹里。
- 变量表格:一个表里放一个或多个模型参数,支持静态采样和动态采样,运行中可以直接改值。改完可以立即生效(Apply change immediately),也可以攒着一起应用或丢弃。列上会标出「未应用的新值」。
- 变量观测:工程浏览器里选中变量,右键
Show In > Variable Viewer,单独开窗看值。
信号可以从模型里直接拖进变量表格,表格本身能存成工作区设置,下次直接读回来。
4.4 快照与参数保存
快照能在某个时刻把模型的状态存下来:数值、状态、参数、输入、输出都包含在内,之后可以整体重载回那一刻。调试一段故障前后的过程时,比反复重跑省事。
保存 / 加载参数只针对参数,不动状态。调 PID 这类系数时用它,改一组、存一组、随时换回来。
4.5 探针控制:数据是怎么从核里搬到界面上的
采样不是「每一步都往界面上发一个数」。核里有一组寄存器(缓冲),按帧装,装满了才发。
步长 1 2 3 4 5 6 7 8 9 10 11 12 13 ...
寄存器A ▓▓ ▓▓ ▓▓ ▓▓ ▓▓ ▓▓ ▓▓ ▓▓ ▓▓ ▓▓ ▓▓ ▓▓ ──► 发送(第 1 帧)
寄存器B ▓▓ ▓▓ ...
↑ 第 12 步开始装下一帧装满一帧,就通知发送端搬运;同时另一个寄存器接着装。发送端在后台跑,装帧和发送交替进行,界面上看到的就是一帧一帧刷新的曲线。
三个参数决定这件事的粒度,它们按采样组(Acquisition group)分别设定。一个 OpComm 模块(在界面侧)就是一个采样组。
采样因子(Decimation factor):隔多少步采一个点。
Decimation = 1 : |×|×|×|×|×|×|×| 每步都采
Decimation = 2 : |×| |×| |×| |×| 隔一步采一个每个信号的采样数(N/s):一个寄存器装多少个点才发。N/s = 2、Decimation = 2、步长 1 ms 时,一帧的时长就是 4 ms。
N/s = 1 : [x][发送][x][发送] 一帧一点,刷得勤,数据碎
N/s = 2 : [x x][发送][x x][发送] 两帧一点
N/s = 2, Decimation = 2: 覆盖 4 ms这套参数只影响界面,不影响模型运行。但传多了界面会一顿一顿地刷,传少了上位机扛不住会丢数据,只能折中。用同步运行模式时,通信节奏的协调尤其要紧。
4.6 丢包:为什么曲线会断
丢包的成因不复杂:A 寄存器满了在等发送,发送端因为某种原因没动,这期间 B 寄存器也装满了,B 的数据被覆盖,几个点就没了。
发送端: ───────────────────── 停滞 ─────────────────►
寄存器A: ▓▓▓▓▓▓▓▓ 满,等发送 ─────────────── 终于发出
寄存器B: ▓▓▓▓▓▓▓▓ 满 → 被覆盖 → 数据丢失RT-LAB 只发装满了的帧,丢包在界面上表现为接收帧号跳号。对策按瓶颈对号入座:
| 瓶颈 | 处理 |
|---|---|
| 目标机太忙 | 加大仿真步长、换更强的处理器、用更大的寄存器 |
| 网络带宽不够 | 加大采样因子或寄存器大小、上千兆 / 光纤 |
| 控制台 CPU 太忙 | 用更大的寄存器、换更快的机器、减界面负载 |
丢包之后曲线会明显错位:Simulink 用它收到的数据来标时间,丢 2 秒数据,界面时钟就比实时时钟慢 2 秒。RT-LAB 会拿填充数据把缺失的时间段补上(丢包小于阈值时),也可以选择在断点前后插一段平滑曲线——数据本身是假的,只是让画面连续。想看真实时刻,在 Console 侧的 OpComm 上勾一个输出为 time 的口,界面上的时间就以它为准。
4.7 数据获取:不经过网络的录波
除了往界面上送,数据也可以直接落盘。两种做法:
采样组录播(组 1–25):复用 Console 的采样组,在探针控制界面勾上 Write to file。检测后每个计算节点上会各自生成一个 .mat,记录分配到该节点的子系统发到这个组的信号。
文件名把信息全写进去了:
Myfile_Gr1_controller_1.mat
└──┬─┘ └┬┘ └───┬────┘ └┬┘
文件名 采样组 子系统名 系统索引(在编辑器里设定)一个 .mat 里有 N 路信号时,就是 N+1 行:第一行永远是仿真时间,后面按进入 OpComm 的顺序排列各信号。
模块录播(组 26–30):用 OpWriteFile 模块,只做录波。一个模型最多 5 个,每个单独起文件名。数据结构一样——首行时间,其余按进模块的顺序。勾上 Write to Simulink mode 还能离线记录。多路信号可以先用 Mux 合成矢量再进。
两种方式的取舍:
| 采样组录播 | OpWriteFile 模块录播 | |
|---|---|---|
| 不用重新编译 | 是 | 否 |
| 能记的范围 | 只能记采样信号 | 模型里任何数据都可记 |
| 数量上限 | 25 个采样组 | 5 个模块,单文件大小不限 |
| 其他 | 受 TCP/IP 包限制;不同子系统落到不同 .mat | Console 关了照样录;不受包限制 |
触发:默认采样组是连续采集的,OpTrigger 可以让它按条件采。触发一次,一个采样组收一帧,然后等下一次触发。用 offset 参数能精确指定触发点之前或之后多少个步长开始取,offset 可以是正也可以是负(1 或 -1,代表前后各一步)。OpTrigger 不光能触发 SC 里的 OpComm,也能触发 OpWriteFile。
动态信号:模型跑起来之后,还能临时挑几个信号送到界面上看。前提是这些信号已经在某个采样组里,并在对应的 OpComm 里勾上 Dynamic signals output,模块会多出几路输出。加载之前要先设定动态信号的最大数量,因为寄存器空间得提前分配好。运行中从列表里挑信号、点 Apply,界面上立刻出现曲线。信号名跟原模型一致,起名时注意可读性。
另外,Simulink 代码生成默认会做优化,某些模块的输出可能因此不可选。遇到这种情况,把高级设置里的 Signal Storage Reuse 关掉,别让输出结构被复用。
五、硬件与 I/O
5.1 三款常用机箱
| OP5600 | OP5700 | OP4510 | |
|---|---|---|---|
| 形态 | 机架式 | 机架式 | 2U |
| CPU | 最高 32 核 Intel @3.0 GHz | 最高 32 核 Intel @3.0 GHz | 3.3 GHz 四核 |
| 操作系统 | Linux RedHat | Linux RedHat | Linux RedHat |
| FPGA | Spartan-3 或 Virtex-6 | Virtex-7 | Kintex-7 |
| I/O 板卡 | 最多 8 块 | 最多 8 块 | 共 4 块 |
| 通道规模 | 128 路模拟 或 256 路数字 | 128 路模拟 或 256 路数字 | 16 AI / 16 AO / 32 DI / 32 DO |
| 光纤 | — | 可选 5 Gbps SFP | 4 个可选 5 Gbps SFP |
| 其他 | 后面板 DB37、前面板监测口、最多 4 个 PCI 槽 | 同左,加同步接口 | 后面板 DB37、同步连接器 |
PCI 槽的意义是可以插第三方的 I/O 板卡,不必只用原厂。
5.2 FPGA 的 I/O 分组
FPGA 决定 I/O 怎么切块,每块叫一个「组」(设置组)。
| FPGA | 组数 | 每组 | 最大数字 I/O | 采样频率 |
|---|---|---|---|---|
| Spartan-3 | 8 | 32 路数字 或 16 路模拟 | 256 | 100 MHz |
| Virtex-6 | 6 | 32 路数字 或 16 路模拟 | 192 | 100 / 200 MHz |
| Virtex-7 | 8 | 32 路数字 或 16 路模拟 | 256 | 200 MHz |
| Kintex-7 | 4 | 32 路数字 或 16 路模拟 | 132(OP4510 实为 96) | 200 MHz |
同一块 FPGA 上可以混搭数字和模拟,这是「高度灵活」的实际含义。Virtex-6 及以后的板卡除了管 I/O,还能承担一部分模型运算。
5.3 机箱里面是什么
flowchart TB
subgraph CH["机箱"]
P["供电电源"]
CPU["CPU:跑模型"]
RAM["内存"]
DISK["硬盘:模型与录波文件"]
subgraph IO["I/O 层"]
A["模拟量层<br/>OP5330 / OP5340"]
D["数字量层<br/>OP5360 / OP5353"]
FPGA["FPGA 板<br/>+ 供电板"]
end
end
CPU --- RAM
CPU --- DISK
CPU --- FPGA
FPGA --- A
FPGA --- D拆开看就是一台工控机加一组插卡:计算、存储、供电在上半层,I/O 调理和 FPGA 在下半层。
5.4 前后两面板
前面板是监测用的。每个 RJ45 口带 4 路信号,接 Mini-BNC/BNC 线就能上示波器,一个口对应 4 个 BNC 端子。它只做观测,不参与模型。
后面板是接外部硬件的。一个 DB37 口带 16 路信号,现场设备从这里接进来、送出去。
前面板: RJ45 ×N ──(每口 4 路)──► BNC ×4 仅监测
后面板: DB37 ×N ──(每口 16 路)──► 外部设备 实际回路5.5 随机文档
每套系统发货时带一份系统描述文档,写的是这一台的实际配置,不是通用手册。里面有三样东西必须看:
- 原理图:I/O 端口怎么分配到各个组;
- 引脚分配:每一路信号在 DB37 上的脚位,以及前面板、后面板的观测位置;
- 数据与模型的对应关系:哪几路通道对应模型里的哪个模块的哪个端口。
另外还有目标机用户手册和 I/O 板文件。文档里的 .CONF 和 .BIN 不是摆设——.CONF 定端口,.BIN 定 FPGA 配置,模型里的模块参数要跟它们对上。
5.6 Simulink 里的 I/O 术语
┌─ 机箱 ─────────────────────────────────────┐
│ 组(Slot) │
│ ├─ 单元(I/O 层) │
│ │ ├─ A 层 ┐ 8 路 = 1 个模块 │
│ │ └─ B 层 ┘ │
│ └─ 一层 8 路为一单元: │
│ 2 个模块 → ch 0-7、8-15 │
│ 4 个模块 → ch 0-7、8-15、16-23、24-31 │
└────────────────────────────────────────────┘换算关系记住「组 = Slot、单元 = 层、模块 = 8 路」这一条就够用了。
5.7 I/O 端口在模型里是怎么体现的
flowchart LR
E1["电信号"] --> AI["AnalogIn 模块<br/>Slot 0 / Module 0"]
AI --> M["用户环境、模型、算法"]
M --> AO["AnalogOut 模块<br/>Slot 1 / Module 0"]
AO --> E2["电信号"]
E3["电信号"] --> DI["DigitalIn 模块<br/>Slot 2 / Module 0"]
DI --> M
M --> DO["DigitalOut 模块<br/>Slot 2 / Module 1"]
DO --> E4["电信号"]机箱是框,模型在中间,信号从两边进出。模型看到的永远是模块的端口号,看不到物理引脚,两者靠 .CONF 和文档对应起来。
5.8 OpCtrl 与 OpLnk
FPGA 板卡要有模块去管它,管事的模块是 OpCtrl,它负责同步、设定内部参数。每一块实际存在的 FPGA 板卡,模型里都必须有一个对应的 OpCtrl。
OpCtrl 要填的几项:
| 参数 | 取值 |
|---|---|
| 管理模块名称 | 自定义,其他 I/O 模块的 Controller Name 要与它一致 |
| BIN 文件 | 从系统交互文档里选对应的 .BIN |
| Board ID | 从 Get I/O Infos 命令取,见下 |
| 同步模式 | 默认 Master;板上已有别的 Master 时改成 Slave |
| FPGA 型号 | 选对,型号写错板卡不认 |
取 Board ID 的办法:RT-LAB 里右键目标机 → Tools → Get I/O Infos,控制台窗口里会打出 Board index,填进去。
多子系统共用一块 FPGA:一块 OP5142 / ML605 / VC707 可以被多个子系统驱动,做法是一个 OpCtrl 加若干个 OpLnk,两者共享同一个 Board ID。同一 Board ID 的 OpCtrl 默认设为 Master,模型里有多块 FPGA 时可以改成 Slave。
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ SM_controller│ │ SS_plant1 │ │ SS_plant2 │
│ OpCtrl │ │ OpLnk │ │ OpLnk │
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
└────────────── 同一块 FPGA ──────────┘注意一个限制:模型目前不支持多速率运行,几个子系统得用同一个步长。
各类 I/O 模块在 RT-LAB I/O > Opal-RT > Common 库里,按用途分:
| 类型 | 库里的模块名 | 备注 |
|---|---|---|
| 模拟量输入 | AnalogIn | 16 路差分,±20 V,16 bit,0.5 或 2.5 µs |
| 模拟量输出 | AnalogOut | 16 路单端,±16 V,16 bit,1 µs |
| 静态数字量 | Digital In (DI) / Digital Out (DO) | 32 路,光耦隔离 |
| PWM 数字量 | PWM In (DI) / PWM Out (DO) | 可设相位偏移 |
| 带时间戳数字量 | EventDetector (DI) / EventGenerator (DO) | 一个步长内的逻辑跳变,最多 255 个事件,可做高频 PWM |
数字量输出要外部供电,电压 5–30 V 可设,单通道最大 ±50 mA;数字量输入 4–50 V 自适应,驱动电流 3.6 mA。三类数字 I/O 可以同时存在于一块板卡上。
Event Detector / Generator 的参数里,除了通用的名字、端口号、通道数,还多一项「每步长内可侦测 / 产生的事件数」,这个数字表征一个仿真步长里逻辑状态变化了几次,做高频 PWM 时靠它。
5.9 从模型到实时运行:按顺序做
- 建工程,创建 / 添加 / 拷贝 / 链接模型,确认模型所在文件夹;
- 把对应的
.BIN和.CONF复制到模型目录,MATLAB 的当前文件夹也要切到这里; - 加
OpCtrl,填管理名、BIN 文件名(带后缀)、Board ID、同步模式; - 加各个 I/O 模块:Controller Name 与 OpCtrl 一致,通道数按 Mux 数量填,Port number 按
.CONF填; - 建 SM / SC 子系统,加 OpComm,设定步长解算器和仿真步长;
- 离线跑一遍,确认无报错;
- 在 RT-LAB 里 Build;
- 选运行模式
Hardware synchronized,分配节点时使能 XHP,然后 Load、Execute。
XHP(eXtra High Performance)模式是给高速运算用的:调度开销压到 1 微秒以内,单独留一个核只跑 RTOS 的基础应用,保证实时装置的处理器状态和内存空间不被别的进程抢。
5.10 测量信号:确认采到的对不对
引脚定义必须看,接错线是最常见的故障。模拟量输入是差分信号,模拟量输出是单端信号——这一点在接线时差别很大:输入通道 0 的正端在引脚 1,负端在引脚 20。
| 标识 | 含义 |
|---|---|
| INxx | 模拟量输入第 xx 路 |
| OUTxx | 模拟量输出第 xx 路 |
| DINxx | 数字量输入第 xx 路 |
| DOUTxx | 数字量输出第 xx 路 |
| Vuser | 用户外部供电的参考电压,仅数字输出板卡用 |
| Vrtn | 接地脚 |
验证信号有没有采对,两条路可以并用:
Loopback 自回环:把输出通道和输入通道对接,下位机发出去的信号原路回到控制台,界面上一看就知道通不通。模拟量用 loopback 板卡加 40PIN 电缆连两个 DB37,不需要另做线,注意红线要接到板卡的 0 脚,保证各路对齐。数字量同样连 40PIN,但数字输出板要外部供电,得先把 4-pin 白色电源口接上(由下位机供电)。
I/O Group 4 Group 3 Group 2 Group 1
┌──────────┬──────────┬─────────┬─────────┐
│ Digital │ Digital │ Analog │ Analog │
│ in │ out │ in │ out │
└────▲─────┴────┬─────┴────▲────┴────┬────┘
└── loopback ─────────┘ │
└────────── loopback ───────────┘外部示波器:前面板的 RJ45 口每个带 4 路信号,用 RJ45 转 4 个 BNC 的线接到示波器上,直接看波形。这里只能观测,别指望从这儿往回送信号。
评论 (0)