生成两个具有不同采样周期的随机时间因变量

Generating two random time depedant veariables with different sample periods

关注 , I'm trying to generate two time-dependent random functions omega1 and tau using this example。不同之处在于,我需要分别为 omega1tau 设置两个不同的采样周期 0.050.17。我只是复制了我认为可以完成工作的部分:

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;

但是我收到错误消息:

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

如果您能帮助我了解问题所在以及如何解决,我将不胜感激。

P.S. 考虑到此代码显然在 Dymola 上编译良好,这可能是 OpenModelica 的问题。所以我添加了 JModelica 标签,以防那些人可以帮助我知道它是否在那里编译。

您在两个 when initial() 语句中有 omega1 := 0;。在第二个中将其替换为 tau := 0;,该示例将起作用。

我建议稍微清理一下您的代码。我发现了各种小问题和不必要的代码行。

  • 所有与不纯随机数有关的东西都可以去掉
  • localSeed2globalSeed2 与其他种子变量一样初始化时无用
  • state1024 在 3 个不同的地方初始化(即使它适用于 OpenModelica):使用 start 值和 fixed=true 以及两个不同的 when initial() 语句
  • omega2tau2 不需要输出。该工具自行确定它必须计算的内容。
  • 最后:如果使用现有模块和物理组件而不是在单个 class 中编写冗长的代码,Modelica 模型更容易调试和理解。您的模型也可以使用来自 Modelica.Blocks.Noise 的块和来自 Modelica.Mechanics.Rotational.
  • 的组件以图形方式构建

下面是您的代码的更新版本,其中包含单元,只有一个部分用于初始化并删除了算法部分(不再需要,因为有额外的变量 rand_omegarand_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;