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?
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?
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.
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 );
}