Simulin金宝appk上的Guy

金宝appSimulink &基于模型的设计

函数句柄和后模拟函数

直到最近,我在处理MATLAB时总是遇到麻烦 函数处理 .我真的不能解释为什么,就是有些事情我无法理解。
为了帮助用户,我终于花时间在我的头脑中揭开了神秘的面纱,并决定今天与你分享我学到的东西。
在Si金宝appmulink中,我最常碰到的需要函数句柄的用例是:
在今天的文章中,我将使用一个后模拟回调 sim卡 举个例子。

这个例子

在这个例子中,我将使用输出信号的简单模型 x 而且 v 使用根级 外港 块:
我可以用a模拟这个模型 SimulationInput对象
mdl =“massSpringDamper”
in = 金宝appSimulink.SimulationInput(mdl);
Out = sim(in);
SimulationOutput 对象包含两个日志信号
out.yout
ans =
金宝app带有2个元素的Simulink.SimulationData.Dataset 'yout' 的名字 BlockPath ____ __________________1 [1x1 Signal] x massspring阻尼器/x 2 [1x1 Signal] v massspring阻尼器/v -使用大括号{}访问,修改或使用索引添加元素。

一个简单的后模拟回调

在最简单的形式中,配置模拟后回调非常简单。以下是文档的截图:
输入 函数 是接收原始函数的句柄吗 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)
了=
金宝app仿真软件。SimulationOutput: mean: [1x1 double] max: [1x1 double] min: [1x1 double] SimulationMetadata: [1x1 金宝appSimulink。SimulationMetadata] ErrorMessage: [0x0 char]
有一件事需要注意 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)
了=
金宝app仿真软件。SimulationOutput: yout: [1x1 金宝appSimulink.SimulationData.]数据集]mean: [1x1 double] max: [1x1 double] min: [1x1 double] SimulationMetadata: [1x1 Simul金宝appink。SimulationMetadata] ErrorMessage: [0x0 char]

额外的输入参数

的文档时 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)
了=
金宝app仿真软件。SimulationOutput: meanWithBias: [1x1 double] SimulationMetadata: [1x1 金宝appSimulink。SimulationMetadata] ErrorMessage: [0x0 char]
功能上,这一行代码定义 myAnonymousFcn 是否相当于创建了一个包装器函数 myPostSim3 它看起来是这样的:
函数newout = myNotAnonymousFcn(out)
biasValue = 5;
gainValue = 10;
newout = myPostSim3(out,biasValue,gainValue)
结束
下面是一个附加的图像,我希望它能帮助区分在模拟结束时调用函数时将其值传递给函数的参数(指定使用 @ (argumentName) 在函数签名前面),而不是立即传递值的实参:

将App或MATLAB类的方法指定为回调函数

为了说明这一点,我添加了两个变量 x0 而且 指定物体的初始位置和速度 二阶积分器 块。
为了简单起见,我将不使用App Designer应用程序,而是使用一个简单的类,用不同的初始值多次模拟模型。同样的原则也适用于在 程序设计师
下面是我的简单类所做的:
  • 在构造函数中,我存储了要模拟和使用的模型的名称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;
结束
结束
结束
这里需要注意的是:
  • 后模拟函数的第一个参数thePostSimFcnobj即物体本身。
  • 在配置模拟后回调时,我将其称为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请在下面的评论中告诉我们。
|

评论

如欲留言,请点击在这里登录您的MathWorks帐户或创建一个新帐户。