问题
Following this question, I'm trying to generate two time-dependent random functions omega1
and tau
using this example. The difference is that I need to have two different sample periods of 0.05
and 0.17
for omega1
and tau
respectively. I just duplicated the parts I thought would do the job:
model testData
extends Modelica.Icons.Example;
import Modelica.Math.Random.Generators;
import Modelica.Math.Random.Utilities;
parameter Real k = 50.0;
parameter Real J = 0.001;
Real theta1;
Real theta2;
Real omega2;
parameter Modelica.SIunits.Period samplePeriod1 = 0.05;
parameter Integer globalSeed1 = 30020;
parameter Integer localSeed1 = 614657;
output Real omega1;
parameter Modelica.SIunits.Period samplePeriod2 = 0.17;
parameter Integer globalSeed2 = 30020;
parameter Integer localSeed2 = 614657;
output Real tau;
protected
discrete Integer state1024[33](each start=0, each fixed = true);
algorithm
when initial() then
state1024 := Generators.Xorshift1024star.initialState(localSeed1, globalSeed1);
omega1 := 0;
elsewhen sample(0, samplePeriod1) then
(omega1, state1024) := Generators.Xorshift1024star.random(pre(state1024));
omega1 := (omega1 - 0.5) * 13;
end when;
when initial() then
state1024 := Generators.Xorshift1024star.initialState(localSeed2, globalSeed2);
omega1 := 0;
elsewhen sample(0, samplePeriod2) then
(tau, state1024) := Generators.Xorshift1024star.random(pre(state1024));
tau := (tau - 0.5) * 3;
end when;
public
parameter Integer id1 = Utilities.initializeImpureRandom(globalSeed1);
discrete Real rImpure1;
Integer iImpure1;
parameter Integer id2 = Utilities.initializeImpureRandom(globalSeed2);
discrete Real rImpure2;
Integer iImpure2;
algorithm
when initial() then
rImpure1 := 0;
iImpure1 := 0;
elsewhen sample(0, samplePeriod1) then
rImpure1 := Utilities.impureRandom(id=id1);
iImpure1 := Utilities.impureRandomInteger(
id=id1,
imin=-1234,
imax=2345);
end when;
when initial() then
rImpure2 := 0;
iImpure2 := 0;
elsewhen sample(0, samplePeriod2) then
rImpure2 := Utilities.impureRandom(id=id2);
iImpure2 := Utilities.impureRandomInteger(
id=id2,
imin=-1234,
imax=2345);
end when;
initial equation
theta1 = 0;
theta2 = 0;
der(theta2) = 0;
equation
der(theta1) = omega1;
der(theta2) = omega2;
J * der(omega2) = tau + k * (theta1 - theta2);
annotation(experiment(StartTime = 0, StopTime = 10, Tolerance = 1e-6, Interval = 0.02));
end testData;
however I get the error messages:
Symbolic Error
The given system is mixed-determined. [index > 3]
Please checkout the option "--maxMixedDeterminedIndex".
Translation Error
No system for the symbolic initialization was generated
I would appreciate if you could help me know what is the problem and how I can solve it.
P.S. considering that this code is apparantly compiling fine on Dymola, this could be a problem with OpenModelica. So I'm adding th JModelica tag in the case those guys can help me know if this compiles over there or not.
回答1:
You have omega1 := 0;
in two when initial()
statements. Replace it by tau := 0;
in the second one and the example will work.
I recommend to cleanup your code a bit. I found various smaller issues and needless code lines.
- everything related to the impure random numbers can be removed
localSeed2
andglobalSeed2
are useless when they are initialized like the other seed variablesstate1024
is initialized at 3 different places (even though it works with OpenModelica): withstart
values andfixed=true
and in two differentwhen initial()
statementsomega2
andtau2
don't need to be outputs. The Tool determines by itself what it has to compute.- And finally: Modelica models are a lot easier to debug and understand if existing blocks and physical components are used instead of writing lengthy code in a single class. Your model can also be built graphically with blocks from
Modelica.Blocks.Noise
and components fromModelica.Mechanics.Rotational
.
Below is an updated version of your code with units, only one section for initialization and removed algorithm section (not necessary anymore due to the additional variables rand_omega
and rand_tau
).
model testData2
extends Modelica.Icons.Example;
import Modelica.Math.Random.Generators;
import Modelica.Math.Random.Utilities;
import SI = Modelica.SIunits;
parameter SI.RotationalSpringConstant k = 50.0;
parameter SI.Inertia J = 0.001;
parameter SI.Period samplePeriod_tau = 0.17;
parameter SI.Period samplePeriod_omega = 0.05;
parameter Integer globalSeed = 30020;
parameter Integer localSeed_tau = 614657;
parameter Integer localSeed_omega = 45613;
SI.Angle theta1, theta2;
SI.AngularVelocity omega1, omega2, rand_omega;
SI.Torque tau, rand_tau;
protected
discrete Integer state1024_tau[33];
discrete Integer state1024_omega[33];
initial equation
state1024_omega = Generators.Xorshift1024star.initialState(localSeed_omega, globalSeed);
state1024_tau = Generators.Xorshift1024star.initialState(localSeed_tau, globalSeed);
theta1 = 0;
theta2 = 0;
der(theta2) = 0;
equation
when sample(0, samplePeriod_omega) then
(rand_omega, state1024_omega) = Generators.Xorshift1024star.random(pre(state1024_omega));
end when;
when sample(0, samplePeriod_tau) then
(rand_tau, state1024_tau) = Generators.Xorshift1024star.random(pre(state1024_tau));
end when;
der(theta1) = omega1;
der(theta2) = omega2;
omega1 = (rand_omega - 0.5) * 13;
tau = (rand_tau - 0.5) * 3;
J * der(omega2) = 0 + k * (theta1 - theta2);
annotation(experiment(StartTime = 0, StopTime = 10, Tolerance = 1e-6, Interval = 0.02));
end testData2;
来源:https://stackoverflow.com/questions/57886368/generating-two-random-time-depedant-veariables-with-different-sample-periods