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)
另一种方法是使用Modelica.Blocks.Noise以避免自己编写外部代码(在 2016 年 4 月 3 日发布的 Modelica 标准库 3.2.2 中添加;即,当提出原始问题时,它不会有帮助)。
其好处之一Modelica.Blocks.Noise是解决了采样、多种子等棘手问题。