Generate white noise in Modelica (SystemModeler)
Asked Answered
S

2

7

I am trying to add measurement noise to a simulation. This is possible to do in for example Simulink but seems to be more difficult in Modelica and SystemModeler.

Any ideas on how to do this?

Swashbuckling answered 18/2, 2013 at 19:34 Comment(0)
S
3

An alternative is to use Modelica.Blocks.Noise to avoid writing external code yourself (added in Modelica Standard Library 3.2.2 released April 3, 2016; i.e. it would not have helped when the original question was asked).

One benefit of Modelica.Blocks.Noise is that the tricky questions with sampling, multiple seeds, etc are solved.

Stavros answered 23/2, 2017 at 10:9 Comment(0)
H
8

You can add white noise in Wolfram SystemModeler via external C-code.

Modelica code (I've removed the diagram annotations from the code, so that it might be easier to read):

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;

External code:

ext_intRandNormal.c

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

void ext_initRandomNormal()
{
    srand(time(NULL));
}

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 );
}
Hege answered 19/2, 2013 at 9:51 Comment(2)
I would add an alternative ext_initRandomNormaWithSeed function to allow the user to pass a seed value in. This way, you can reproduce the noise signal. What is the point of the seed variable in ext_RandomNormal? Am I missing something? It seems to be computed but never used.Roulade
To be even more rigourous, you might wish to use an ExternalObject that preserves state. If you have to different WhiteNoise sources using the above code, they will "interact" with each other (one will affect the other).Roulade
S
3

An alternative is to use Modelica.Blocks.Noise to avoid writing external code yourself (added in Modelica Standard Library 3.2.2 released April 3, 2016; i.e. it would not have helped when the original question was asked).

One benefit of Modelica.Blocks.Noise is that the tricky questions with sampling, multiple seeds, etc are solved.

Stavros answered 23/2, 2017 at 10:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.