目录
1 应用场景
在大型建模中,大系统会有许多同样的模块,且这些模块是根据一个或者两个参数表中的参数进行赋值(会出现大量相同参数或不同参数的模块,且这些参数调整无法在建模的时候预料到),那么,该系统的参数赋值将会是一个非常繁琐的事情,可以通过以下方法进行。
2 基础函数
2.1 利用try catch功能进行赋值
由于赋值中有需要跳过的参数名,或者由于参数格式错误而赋值失败的情况。在一部分情况中,我们需要忽略这些错误,在赋值中使用“try,catch”功能可以满足我们的需求。
2.2 获取参数变量名称
为了获取参数变量的名称,需得到想要赋值模块的句柄,有两种方法可以选取该模块。
- 应用函数gcb获得模块名称和层次
- 手动定义模块名称和其层次,输入到BlockName中。
在我的案例中,我将这个赋值模块功能化,通过手动输入模型名称,该模型层次和相应的模块名会通过赋值用文件模板自动获得。该内容之后会详细说明。
然后,使用下列函数获得该模块可被赋值的变量名。
hG=getSimulinkBlockHandle(BlockName,true);
BlockDialogParameters = get_param(hG,'DialogParameters');
a=fieldnames(BlockDialogParameters);
第一个函数会得到所需模块的句柄hG,句柄是一个已建模块的唯一代号,通过对这个代号操作,我们可以做到只调整该模块。
第二个函数可以得到该模块的所有被设定的参数,然而这个函数的返回值是一个“structure”结构体,变量名称是这个结构体里面的子结构,需要第三个函数“fieldnames”获得这些子结构体的名字。
这样,我们就得到了所有需要赋值的变量名,这些变量名会以胞数组“cell"的型式存在于变量a中,方便与我们的赋值。
2.3 参数模板的创建
参数模板我们希望达成以下功能:
- 通用性:对于哪种模块都可以运行且按照所需的顺序和结构提取出所需参数。
- 简洁:只把有用的结果作为输出,中间参数只作为局部变量用于计算。
第一时间想到是使用function函数建立这个参数模板,然而这个有违通用性,因为文件名称必须与函数名称对应,不然的话没法运行。如果作为脚本运行,所有的中间变量都会输出为全局变量,污染内存,同时这些定义的变量还会影响到其他脚本的运行,使得错误排查更加困难。
一个有效的解决方式是使用Matlab脚本中的局部函数功能。首先介绍一下局部函数,这个自定义function函数只在这个脚本中有效,且这个函数不会和Matlab自带函数冲突,优先运行这个局部函数。这就代表着,我们可以在使用function函数功能的同时,脱离文件名同步的条件捆绑,使其更加灵活。
举个例子。
P = fac(a);
function P = fac(a)
P = a*2;
end
这样,我们可以在这里引用函数fac,只需要改变全局变量a的值,就可以得到我们想要的结果,同时,文件名字的限制也会被去掉。对应不同模块,我们建立不同的参数模板,取各种各样的名字,都不会影响这个函数的正常运行,我们只需要保证,在运行这个脚本的时候,全局变量的值是对应这个脚本所需的即可。
2.4 将参数放入胞数组
在上文中,我们将一个模块的变量名以一定顺序放入变量a中。作为对应,我们也要将所有参数以同样的顺序放入胞数组中,便于赋值模块。为了相互对应未赋值的参数和待赋值的变量在胞数组的位置,我们利用函数**“eval(a{i})”这个函数去以变量a中的参数顺序提取参数值,这里需要注意需要将数值转换成String**格式储存。
方式如下
for i=1:len