当前位置:首页 > scilab模块开发 - 图文
数据结构
每一个scilab模块都是用以下形式的数据结构描述的:
list(‘block’, graphics, model, unused, GUI_function)
这里比较重要的就是model对象,其主要用于标识模块内部各参数、变量的取值,比如: model.in, model.out model.evtin, model.evtout
model.dstate = zeros(num,0)
model.state = zeros(num,0) model.ipar
model.rpar
model.sim
定义模块的输入输出端口个数及大小,这里端口的
大小由向量的取值决定,端口的个数由矩阵的行数决定,例如[5]表示端口的大小为5,也就是说输入量应该是一个5*1的矩阵形式。再比如[5;2]表示输入端口有两个,大小分别为5和2,即两个输入量分别为5*1和2*1的矩阵形式。
定义模块的输入输出事件端口。对应模块上下的红色输入输出端口。 定义离散状态变量dstate,初始化为num维0向量
这里定义的离散状态变量对应于计算函数的block.z。
定义连续状态变量state,初始化为num维0向量
这里定义的连续状态变量对应于计算函数的block.x。
注意:连续状态变量和离散状态变量一定要在interface functional中实现分配.如果没有分配,在computational function中就不能应用这些变量,如果用了SCICOS就会 报错。
整数型参数, 多个参数可以用向量来表示 [x1,x2,…xn]。
这里定义的model.ipar对应于计算函数的block.ipar。
实数参数
这里定义的model.rpar对应于计算函数的block.rpar。
指定模块的computational function类型、计算函数 名 例:
model.sim = list(‘hilbertTransformer_com’,5) 计算函数是类型为5的(即由 SCILAB语言编写的函数,其他数字分别对应不同语言,4和5比较常用,4代表c语言),名为 hilbertTransformer_com。
model.dep_ut 定义模块输出是否与输入、时间直接有关。如果模 块输出和输入时间都有关,model.dep_ut=[%t %t];
如果模块输出与输入不直接相关(输出可能由内部 状态决定,输入改变内部状态)只与时间相关,则 model.dep_ut=[%f %t]。
PS:通过以上定义可以看出model的数据结构是用struct函数来定义的。
模块参数的修改(set)
当job==’set’时我们可以利用对话框对参数进行修改。 其编写格式为:
case 'set' then //双击模块的时候,block接口函数将以
//job==’set’被调用
x=arg1; //定义返回值初始值,这里x为block函 //数的一个返回值,它是模块的一个数据结构 graphics=arg1.graphics;exprs=graphics.exprs; //查看 //Scicos数据结构 model=arg1.model;
while %t do //while循环,其中%t表示true
[ok,x1,x2,x3,…xn,expers]= getvalue(['对话框上显示的说 明信息'],['对话框上第一行参数名';'第二行参数名
'],list('vec',-1,'vec',-1),exprs);//绘制对话框,其中
//list用来设置参数类型 if ~ok then break,end; //如果用户没有在对话框上点击ok, //退出while循环 if then //一般编写if语句用于判断所设置的参 ok=%f //数是否不符合要求
else if then ok=%f end
if ok then //如果参数设置成功则更新模块内部参数 //如更改model.ipar的值等
x.graphics=graphics;x.model=model;//返回被设置后的状态 break; //退出while循环 end end
说明:
1、这里 x = arg1 是用来保存参数修改前模块的数据结构的(从后面的代码中可以看出这句话其实可以不要,但是为了保证编程的严谨性我们将其保留),
graphics=arg1.graphics,exprs=graphics.exprs,model=arg1.model,则用来获取当前数据结构中一些将要用到的数据或数据结构。
2、我们用while %t do, end 设置了一个死循环。该循环设置的目的在于,当参数
设置不符合要求时,对话框能够再次被调用,以免使用者需要重新双击模块打开对话框。 3、通过调用getvalue函数,我们可以定义并打开一个对话框。该函数各参数的意义详见上文的注释,如想对该函数有更多了解可以在scilab帮助里查询。对于该函数的具体用法,读者也可以在scilab主窗口中输入如下代码来查看调用结果:
labels=[\
[ok,mag,freq,ph]=getvalue(\ list(\ 4、在修改模块参数时,我们一定要用if语句来对修改后的参数加以判别,以判断其是否符合当前计算的要求,如频率值应该非负等等,否则当计算函数使用这些参数时可能产生错误。
5、最后,当调用getvalue修改参数成功后,我们需要将其更新到模块的数据结构中 去,以便计算函数能够调用新的参数。对应的语句为x.graphics=graphics,x.model=model。
模块参数的初始状态定义(define)
当job==’define’时,我们可以定义模块各参数的初始值,并定义模块的外观。 其编写格式为:
case 'define' then //当将模块放置到scicos图形仿真窗口中时, // block接口函数将以job==‘define’被 //调用
x1 = …; x2 = …; . . .
xn = …; //设定各参数的初始值 //
//下面就是设定初始模块的各参量值,并将其更新这数据结构。具体//都设置哪些,由编者根据模块的要求决定。下面是一些常用的设置。
//
exprs=[string(x1);string(xm)]; //将可能需要修改的参数 //的初始值的字符串形式 //存入exprs,以便将来修 //改参数时,对话框里能够正 //确显示当前的参数初始值, //这里的exprs就是 //getvalue里的参数exprs model=scicos_model(); //定义model为scicos里的//标准数据结构形式
model.sim=list('计算函数名',函数类型用数字(1~5表示)) //用model.sim绑定计算函数
model.in=[…]; //设定输入端口大小 model.out=[…]; //设定输出端口大小
model.ipar=[x1,x2,…,xm]; //将各参数更新到model数 //据结构里 model.evtin = […]; //设定事件输入端口 model.dstate = […];
model.blocktype='d' //连续变化的模块,blocktype=’c’, //离散模块blocktype=’d’ model.dep_ut=[%t %f] //输出和当前输入有关,和时间无关 gr_i=['txt=[''模块上面的显示文字
''];';'xstringb(orig(1),orig(2),txt,sz(1),sz(2),''fill'')'];
x=standard_define([2.5 2.5],model,exprs,gr_i) //用standard_define函数更新模块
//的总的数据结构,其中第一个参数表 //示模块的大小即一个2.5*2.5的方块, //最后一个参数表征模块的外观、颜色
说明:这里我们define的设定过程相对简单,主要就是将编程者将来需要在计算函数中里用到得参数值进行初步定义(由model.ipar完成),并为计算函数的变量分配空间(由model.dstate完成),以及其他所必须的设置。最后就是用standard_define函数将模块的数据结构进行更新,有必要说明的是,编程者若想将模块外观改为自己定义的图片而不单单是文字,则需将gr_i 中txt部分置为空字符即””,并将所需修改的图片放在在scilab\\modules\\xcos\\images\\palettes下,图片名应为编程者定义的接口函数名。
2、计算函数
在scilab中计算函数既可以用scilab语言编写,也可以用C或fortran语言编写。在本文中仅介绍采用scilab语言编写的方式。对于其他编写方式由于编写起来较为复杂,这里就不过多介绍了,感兴趣的读者可以参考《Scilab/Scios在建模与仿真中的应用》。
基本框架
function block=block_com(block, flag)
if flag==1 then
... elseif flag==2 then ... end
endfunction
或者:
function block=block_com(block, flag) select flag case 1 then block.outptr(1)(1) = ... block.outptr(1)(2) = ...
共分享92篇相关文档