Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate white noise in Modelica (SystemModeler)

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?

like image 824
sebnil Avatar asked Feb 18 '13 19:02

sebnil


2 Answers

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 );
}
like image 79
Mikael Forsgren Avatar answered Nov 08 '22 22:11

Mikael Forsgren


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.

like image 3
Hans Olsson Avatar answered Nov 08 '22 22:11

Hans Olsson