alternative to sample function with varying sampling range

298 views Asked by At

Is there an alternative to the sample function in Openmodelica, which accepts arguments which are not of type parameter? That is, the alternative should permit the sampling of a variable range of values during a simulation.

The end goal is to create a class with which I can measure the RMS value of a real signal during a simulation. The RMS value is used as a control variable. The real signal has a continuously changing frequency so in order to have better measurements, I want to either be able to varry the sampling range continuously during simulation or discretely in some sections/periods of the oscillation.

Is it also possible to have a "running RMS" function so that the output is continuous?

In short, I would like to calculate the RMS value over a variable sampling range and the sample should only have one new term or value per iteration and not a completely new set of values.

1

There are 1 answers

1
sjoelund.se On BEST ANSWER

Some possible solutions (you probably should check my math and just use them for inspiration; also check the RootMeanSquare block in the standard library which for some reason samples the Mean block):

Running RMS from beginning of time (no frequency).

model RMS
  Real signal = sin(time);
  Real rms = if time < 1e-10 then signal else sqrt(i_sq / time /* Assume start-time is 0; can also integrate the denominator using der(denom)=1 for a portable solution. Remember to guard the first period of time against division by zero */);
  Real i_sq(start=0, fixed=true) "Integrated square of the signal";
equation
  der(i_sq) = signal^2;
end RMS;

With a fixed window, f:

model RMS
  constant Real f = 2*2*asin(1.0);
  Real signal = sin(time);
  Real rms = if time < f then (if time < 1e-10 then signal else sqrt(i_sq / time)) else sqrt(i_sq_f / f);
  Real i_sq(start=0, fixed=true);
  Real i_sq_f = i_sq - delay(i_sq, f);
equation
  der(i_sq) = signal^2;
end RMS;

With a variable window, f (limited by f_max):

model RMS
  constant Real f_max = 2*2*asin(1.0);
  constant Real f = 1+abs(2*asin(time));
  Real signal = sin(time);
  Real rms = if time < f then (if time < 1e-10 then signal else sqrt(i_sq / time)) else sqrt(i_sq_f / f);
  Real i_sq(start=0, fixed=true);
  Real i_sq_f = i_sq - delay(i_sq, f, f_max);
equation
  der(i_sq) = signal^2;
end RMS;

Variable time for sampling in synchronous Modelica: https://trac.modelica.org/Modelica/ticket/2022

Variable time for sampling in older Modelica:

when time>=nextEvent then
  doSampleStuff(...);
  nextEvent = calculateNextSampleTime(...);
end when;