Dymola/Modelica - 如何仅在稳定状态下计算信号的平均值?

Dymola/Modelica - How can I calculate the mean of a signal only in the steady state?

我正在努力计算我的 Modelica 模型中连续信号的平均值。问题是我只对计算稳态的平均值感兴趣。例如,在所附模型(最小、可重现示例)中,我想计算 40 到 60 秒之间的平均值。因此,我首先尝试使用 Modelica.Blocks.Math.ContinuousMeant_0 是受保护的,所以我在我的个人库中写了一个类似的代码(它也是附件)。 但是,有一个错误,我无法弄清楚发生了什么。有人可以阐明这个简单的问题吗?提前致谢!!!

型号:

model MeanExampleWhosebug

  parameter Modelica.SIunits.Time period=3;
  final parameter Real angularFrecuency=(2*Modelica.Constants.pi)/period;
  parameter Real amplitude=2;
  Real signal;
  Real mean;

  PersonalLibrary.Utilities.ContinuosMeanStartTime meanBlock(t_0=40);

equation 

  signal = amplitude*sin(angularFrecuency*time) + log(time*100 + 1);
  meanBlock.u = signal;
  meanBlock.y = mean;

end MeanExampleWhosebug; 

块保存在个人图书馆:

block ContinuosMeanStartTime "Similar block as Continuos Mean in MSL but with unprotected Start time (t_0)"
  extends Modelica.Blocks.Icons.Block;
  parameter Modelica.SIunits.Time t_eps(min=0.0) = 1e-7 "Mean value calculation starts at startTime + t_eps";
  parameter Modelica.SIunits.Time t_0(min=0.0) = 0 "Start time";

  Modelica.Blocks.Interfaces.RealInput u "Noisy input signal";
  Modelica.Blocks.Interfaces.RealOutput y "Expectation (mean) value of the input signal";
protected 
  Real mu "Internal integrator variable";
initial equation 
  mu = u;
equation 
  der(mu) = noEvent(if time >= t_0 + t_eps then (u - mu)/(time - t_0) else 0);
  y = noEvent(if time >= t_0 + t_eps then mu else u);

end ContinuosMeanStartTime; 

最后,这里有一些显示我想要实现的结果(已经用其他软件编辑结果)。 最好的问候。

注意:顺便问一下,有没有其他方法可以访问MSL中的受保护参数而不是写入新块?

目前不能用t_eps实现,只是为了防止被零除。

如果 t_0 被曝光,可能会改变它。

当我 运行 你的代码时,我收到一个错误,指出奇点出现在 t=40.

我认为你基本上在 t= t_0 + t_eps 处遇到了一个数值问题,因为你突然在 mu 上有了一个具有特征值的微分方程time-t_0,在 if 条件变为真之后是 t_eps,因此非常小,是求解器的问题。

这里有一些解决方法:

  • 使用另一个求解器(对我来说 DASSL 没有 运行 通过,但 LSODAR 有效),有些求解器可能更适合您的特定数值挑战
  • 增加 t_eps(对我来说 t_eps > 1e-6 的模型 运行s 左右),所以时间的特征值= t_0 + t_eps 变大
  • 删除 noEvent(我不太确定为什么这会解决问题,我的猜测是,然后事件触发 DASSL 的重置,并减小其步长, 因此可以处理快速特征值。这也可以解释为什么原始模型 Modelica.Blocks.Math.ContinuousMean 在时间 = t_0 + t_eps 起作用,因为这里的 if 语句在开始后立即变为真的模拟,其中 DASSL 处于与事件发生后相似的状态并且使用非常小的步长。但这些只是有根据的猜测。)

你的代码的另一件事是,如果你想创建绿线,你必须将 ContinuosMeanStartTime 块的输出更改为

y =  mu;

否则你会得到 信号 作为你在 time= 40 + t_eps.

之前的平均值