函数句柄和后模拟函数
为了帮助用户,我终于花时间在我的头脑中揭开了神秘的面纱,并决定今天与你分享我学到的东西。
在Si金宝appmulink中,我最常碰到的需要函数句柄的用例是:
- 定义pre-simulation而且post-simulation功能sim卡而且parsim
- 定义外部输入而且输出回调的金宝app仿真软件的编译器
在今天的文章中,我将使用一个后模拟回调
sim卡
举个例子。
这个例子
mdl =“massSpringDamper”;
in = 金宝appSimulink.SimulationInput(mdl);
Out = sim(in);
out.yout
一个简单的后模拟回调
在最简单的形式中,配置模拟后回调非常简单。以下是文档的截图:
输入
函数
是接收原始函数的句柄吗
SimulationOutput
对象作为输入,并返回一个结构,其中的字段将包含在new
SimulationOutput
对象。例如,我定义了这个函数:
函数newout = myPostSim(out)
myssignal = out.you .get(“x”) . values;
newout。mean = mean(我的信号);
newout。max = max(mySignal);
newout。min = min(myssignal);
结束
然后,为了指定该函数需要在模拟之后执行,我将传递给
setPostSimFcn
的句柄
myPostSim
使用“
@
性格:
mdl =“massSpringDamper”;
in = 金宝appSimulink.SimulationInput(mdl);
in = in. setpostsimfcn (@myPostSim);
Out = sim(in)
有一件事需要注意
SimulationOutput
在这种情况下返回的对象不包含原始信号
你
,它只包含在后期模拟函数中创建的新字段,以及
SimulationMedata
和
ErrorMessage
字段。如果你的模拟产生了大量数据,但你只对后处理的统计数据感兴趣,比如在这个例子中,平均值、最小值和最大值,这就特别有用。
如果希望保留原始数据,可以简单地将其重新分配给输出。对于上面的例子,如下所示:
函数newout = myPostSim2(out)
newOut = out;
myssignal = out.you .get(“x”) . values;
newout。mean = mean(我的信号);
newout。max = max(mySignal);
newout。min = min(myssignal);
结束
模拟时,SimulationOutput对象包含原始数据
你
和新计算的值
mdl =“massSpringDamper”;
in = 金宝appSimulink.SimulationInput(mdl);
in = in. setpostsimfcn (@myPostSim2);
Out = sim(in)
额外的输入参数
的文档时
setPostSimFcn
,我们还会看到这样的语法:
函数newout = myPostSim3(out,bias,gain)
myssignal = out.you .get(“x”) . values;
newout。meanWithBias = gain* (mean(mySignal) + bias);
结束
使用这些额外的输入,首先创建一个匿名函数,该函数将接收Simulation Output对象
出
作为输入,并将其传递给
myPostSim3
还有价值
偏见
而且
获得
:
mdl =“massSpringDamper”;
biasValue = 5;
gainValue = 10;
myAnonymousFcn = @(out) myPostSim3(out,biasValue,gainValue);
in = 金宝appSimulink.SimulationInput(mdl);
in = in. setpostsimfcn (myAnonymousFcn);
Out = sim(in)
功能上,这一行代码定义
myAnonymousFcn
是否相当于创建了一个包装器函数
myPostSim3
它看起来是这样的:
函数newout = myNotAnonymousFcn(out)
biasValue = 5;
gainValue = 10;
newout = myPostSim3(out,biasValue,gainValue)
结束
下面是一个附加的图像,我希望它能帮助区分在模拟结束时调用函数时将其值传递给函数的参数(指定使用
@ (argumentName)
在函数签名前面),而不是立即传递值的实参:
将App或MATLAB类的方法指定为回调函数
下面是我的简单类所做的:
- 在构造函数中,我存储了要模拟和使用的模型的名称rng初始化随机数生成器
- 在runSim方法,我定义一个随机值x0这将被用作所有模拟的相同初始位置
- 我定义不同的随机值半在每个模拟中使用
- 我定义了类方法thePostSimFcn作为后模拟回调,我传递给它的值x0而且半使用附加参数
- 在thePostSimFcn,我储存x0而且半在模拟输出对象中,以供将来使用
classdefmyClass
属性
mdl要模拟的模型的名称
结束
方法
函数obj = myClass(mdl)
rng (“洗牌”);
obj。mdl= mdl;
结束
函数out = runSim(obj,N)
X0 = rand;初始化相同位置的所有运行
in(1:N) = 金宝appSimulink.SimulationInput(obj.mdl);
为i = 1:N
V0 = 10*rand;初始化以不同的速度运行
in(i) = in(1).setVariable(“x0”, x0);
in(i) = in(1).setVariable(“半”v0);
in(i) = in(i).setPostSimFcn(@(out) obj.thePostSimFcn(out,x0,v0));
结束
Out = sim(in,“ShowProgress”,“关闭”);
结束
函数newOut = thePostSimFcn(obj,out,x0,v0)
newOut = out;
将ic存储在输出记录中
newOut。x0= x0;
newOut。半= v0;
结束
结束
结束
这里需要注意的是:
- 后模拟函数的第一个参数thePostSimFcn是obj即物体本身。
- 在配置模拟后回调时,我将其称为obj.thePostSimFcn因为它是这个类的一个方法。
然后我可以使用我的简单类与以下代码:
myObj = myClass(“massSpringDamper”);
out = myObj.runSim(2);
图;
为I = 1:长度(out)
次要情节(2,1,1);持有在;
情节((我).yout.get (“x”) . values);
次要情节(2,1,2);持有在;
情节((我).yout.get (“v”) . values);
legendTxt{i} = [“运行”num2str(我)' - x0='(我).x0 num2str ()' - v0='num2str((我).v0)];
结束
次要情节(2,1,1);传奇(legendTxt)
现在轮到你了
在Simulink上下文中,函数句柄和匿名函数还有其他用例吗?金宝app请在下面的评论中告诉我们。
- 类别:
- 命令,
- 并行仿真,
- 金宝app仿真软件提示
评论
如欲留言,请点击在这里登录您的MathWorks帐户或创建一个新帐户。