在Modelica中生成白噪声(SystemModeler)

seb*_*nil 7 modelica systemmodeler

我正在尝试将测量噪声添加到模拟中.这可以在例如Simulink中进行,但在Modelica和SystemModeler中似乎更难.

关于如何做到这一点的任何想法?

小智 8

您可以通过外部C代码在Wolfram SystemModeler中添加白噪声.

Modelica代码(我已从代码中删除了图表注释,因此可能更容易阅读):

package WhiteNoise "Package for generating white noise"
  extends Modelica.Icons.Library;

  block NoiseNormal "Normally distributed random noise"
    parameter Real mean=0 "Mean value of random noise";
    parameter Real stdev=1 "Standard deviation of random noise";
    parameter Real tSample=0.01 "Noise sample time";
    Modelica.Blocks.Interfaces.RealOutput y;
  equation 
    when initial() then
      WhiteNoise.initRandomNormal();
    end when;
    when sample(0, tSample) then
      y=mean + stdev*WhiteNoise.RandomNormal(time);
    end when;
  end NoiseNormal;

  function initRandomNormal
    external "C" ext_initRandomNormal()   annotation(Include="#include \"ext_initRandNormal.c\"");
  end initRandomNormal;

  function RandomNormal
    output Real y;
    input Real u;
    external "C" y=ext_RandomNormal(u)   annotation(Include="#include \"ext_RandNormal.c\"");
  end RandomNormal;

end WhiteNoise;
Run Code Online (Sandbox Code Playgroud)

外部代码:

ext_intRandNormal.c

#include <math.h>
#include <limits.h>

void ext_initRandomNormal()
{
    srand(time(NULL));
}
Run Code Online (Sandbox Code Playgroud)

ext_RandNormal.c

#include <math.h>
#include <limits.h>
double ext_RandomNormal(double timein)

{
    unsigned int seed = 0;
    double v1, v2, r;

    timein /= 100;
    seed = (timein - floor(timein)) * UINT_MAX;

    do
    {
        v1 = 2 * ((double) rand()) /((double) RAND_MAX) - 1;
        v2 = 2 * ((double) rand()) /((double) RAND_MAX) - 1;
        r = v1 * v1 + v2 * v2;
    } while((r >= 1.0) || (r == 0.0));

    return v1 * sqrt( - 2.0 * log(r) / r );
}
Run Code Online (Sandbox Code Playgroud)

  • 为了更加严谨,您可能希望使用保留状态的`ExternalObject`.如果您使用上述代码必须使用不同的`WhiteNoise`源,它们将彼此"交互"(一个会影响另一个). (4认同)
  • 我将添加一个替代`ext_initRandomNormaWithSeed`函数,以允许用户传入种子值.这样,您可以重现噪声信号.`ext_RandomNormal`中`seed`变量的意义是什么?我错过了什么吗?它似乎是计算但从未使用过. (2认同)

Han*_*son 3

另一种方法是使用Modelica.Blocks.Noise以避免自己编写外部代码(在 2016 年 4 月 3 日发布的 Modelica 标准库 3.2.2 中添加;即,当提出原始问题时,它不会有帮助)。

其好处之一Modelica.Blocks.Noise是解决了采样、多种子等棘手问题。