S-Function 控制元件
本文档主要介绍自定义 S-Function 元件的创建和实现方法。为实现该功能,用户需提前准备封装好的二进制模型 .so
文件。本文档也将从白盒模型封装和黑盒模型封装两种实现方式介绍生成 .so
的具体步骤,并通过一个白盒模型实现的案例介绍 S-Function 元件的构建、调试方法。
功能定义
该功能支持将封装的二进制模型导入平台,构建自定义 S-Function 电磁暂态仿真元件。
功能说明
自定义 S-Function 元件具有以下几个功能特点:
-
控制模型构建方便、高效,可降低模型搭建和参数校验的时间成本。
-
控制策略与真实控制器的保持高度一致,仿真结果更接近实际情况。
-
控制器开发者不需要公开具体的控制策略和核心算法,可满足保密需求。
适用模型
需提前准备 Linux 64 位系统环境下编译生成的 .so
文件。
编译来源可以有以下两种:
-
MATLAB/Simulink 子系统编译生成 S-Function 时自动生成的代码文件。
-
用户自定义函数和接口的代码文件。
整体流程
用户可将 Simulink 白箱模型封装成 S-Function 子系统,利用 MATLAB 的自动代码生成功能,得到 *.c
和 *.h
文件,在 Linux 环境中编译生成 .so
文件;也可以将包含自 定义函数和接口的 .c
或 .cpp
、.h
文件,或 .a
二进制文件,在 Linux 环境中编译生成 .so
文件。
用户需要获取 Simulink 子系统或自定义代码文件的全局参数、输入/输出接口信息,并根据信息定义 S-Function 元件的参数和引脚,在平台导入 .so
文件,完成自定义 S-Function 元件的构建。
具体步骤
本文档根据白盒模型封装和黑盒模型封装两种方式介绍自定义 S-Function 元件实现的具体步骤。
若用户需要构建白盒模型的 S-Function 元件,.so
的编译来源为 MATLAB/Simulink 自动生成的代码,请参见白盒模型 S-Function 实现标签。
若用户需要构建黑盒模型的 S-Function 元件,.so
的编译来源为用户自定义的函数和接口代码,请参见黑盒模型 S-Function 实现标签。
- 白盒模型 S-Function 实现
- 黑盒模型 S-Function 实现
步骤 1. 将 Simulink 模型封装为 S-Function 并自动生成代码
-
a. 解算器设置
模型设置为固定步长,解算器设置为
discrete
,确保模型在当前设置下能正常运行。CloudPSS 中的系统均为离散系统,因此建议 S-Function 也使用离散解算器。
注意若 S-Function 子系统中存在难以离散化的连续状态,也可选用连续积分解算器,目前支持的有 ode1、ode2、ode3、ode4、ode5 和 ode8,不同的积分方式会影响仿真结果准确度和仿真计算时间。
-
b. 子系统封装
将控制模型封装为一个子系统。子系统中可以引用全局参数,若子系统的顶层有参数封装,并且希望这些参数在生成 S-Function 后可调,请将这些参数也通过全局参数定义,否则将被视为固定值而不可调。
例如上图中,Parameter1 与 Parameter2 分别用全局参数 a 和 b 定义,则在生成 S-Function 后,这两个参数仍可在子系统顶层设置,而 Parameter3 为固定值 0,在生成 S-Function 时将以固定值写入。
注意S-Function 参数必须以字母开头(不能是数字或下划线),目前仅支持 double 型,若是一个矩阵,在 CloudPSS 中对应表格型参数。
-
c. 生成 S-Function
右键子系统,依次选择 C/C++ Code、Generate S-Function 选项。
-
d. 设置 S-Function 参数
勾选列出的全局参数中需要可调的,未勾选的参数将以固定值写入。
-
e. S-Function 自动代码生成
自动代码生成,sfcn_rtw 文件夹中包含
*.c
与*.h
文件。提示若提示无编译器,则需下载并安装一个 MingGW64 编译器,流程可参考:https://zhuanlan.zhihu.com/p/359962279?ivk_sa=1024320u
步骤 2. 在 Linux 环境编译生成 .so 文件
-
a. 添加接口定义
在步骤 1 生成的 sfcn_rtw 文件夹中找到以 S-Function 名称命名的
.c
文件,在 #include 之后添加如下接口定义并保存:#define ssSetInputPortVectorDimension(S, port, d) \
(ssSetInputPortWidth(S, port, d))
#define ssSetOutputPortVectorDimension(S, port, d) \
(ssSetOutputPortWidth(S, port, d))注意此函数定义是为识别 S-Function 的输入输出引脚,若每个输入输出引脚 维数均为 1,则不用添加;若有引脚维数大于 1,则必须添加。
-
b. 运行编译指令
将 sfcn_rtw 文件夹复制到 Linux 环境,在其路径下输入以下编译命令:
gcc -Wall -DRT -DRT_MALLOC -fPIC -lm -shared *.c -o xxxx.so
其中,
xxxx
为用户自定义的.so
文件名,与内部函数名(S-Function 名)无关。Linux 环境必须是 64 位系统。若出现缺少
*.h
头文件的报错,需要手动添加相应文件。不同版本的 MATLAB 所调用的头文件不同,获取路径可参考:安装路径\MATLAB\Rxxxxx\simulink\include
安装路径\MATLAB\Rxxxxx\extern\include
安装路径\MATLAB\Rxxxxx\rtw\c\src其中,
xxxxx
为 MATLAB 版本。
步骤 3:根据全局参数和输入输出接口信息构建 S-Function 实现元件
-
a. 新建空白 S-Function 实现元件
在工作台点击新建按钮,新建一个空白普通电力系统模型。
选择总览标签页,将模型类型切换为元件。
此时,在实现标签页中将出现拓扑、电磁暂态等子标签页。选中电磁暂态子标签页,点击创建电磁暂态 - S-Function 实现按钮,即可创建自定义 S-Function 元件。
-
b. 参数引脚列表定义
选择接口标签页,在参数列表添加参数,在引脚列表添加引脚,并绘制元件图形。参数键名必须与 S-Function 引用的全局参数名一致;引脚键名不作要求,但顺序必须分别与 S-Function 的输入输出引脚对应。
-
c. 导入 .so 文件
在实现标签页导入步骤 2 生成的
.so
文件,并填写入口函数名。注意入口函数名是 S-Function 名称,不是
.so
的文件名。 -
d. 元件名称与权限设置
切换到总览标签页,输入元件的名称,并设置元件的权限和元件标签。
步骤 1. 在 Linux 环境编译生成 .so 文件
-
a. 运行编译指令
将代码文件
*.cpp
及其头文件*.h
复制到 Linux 环境,使用以下指令编译:gcc -Wall -fPIC -s -lm -shared -DRT xx1.cpp xx2.cpp -o xx.so
注意Linux 环境必须是 64 位系统
对于已经编译为
.a
的文件,使用以下指令编译:gcc -Wall -fPIC -s -lm -shared xx.a -o xx.so -u <entry_name>
其中,
<entry_name>
是入口函数名。
步骤 2:根据全局参数和输入输出接口信息构建 S-Function 实现元件
-
a. 新建空白 S-Function 实现元件
在工作台点击新建按钮,新建一个空白普通电力系统模型。
选择总览标签页,将模型类型切换为元件。
此时,在实现标签页