0

Modelica/Dymola でビルトイン コントロール アルゴリズム (LQR) を実装する際に問題が発生しています。私が抱えていた問題を示す、より単純なモデルを作成しました。

基本的に、LQR を外部で呼び出し、タイム ステップごとに変化するエントリ (Ctest という名前) を含む行列を渡します。この Ctest は、findC という名前の外部関数によっても検出されます。

面白いことに、Ctest = 0 にすると Dymola は問題なく動作しますが、if ループで Ctest = 0 にすると、次のような多くのエラーが表示されます。 .dare 変数 AT は次元 ":" で宣言されました。これは dsmodel.c ではまだサポートされておらず、モデルで呼び出された場合、関数は失敗します。

たとえば、次のコードで 3 つの異なるケースを実行しました。2.代わりに、C が 0 のままの if ループを作成すると、モデルはシミュレートされません。以下の if ループをコピーしてコメントアウトしました。3. ケース 1 のように findC を保持し、「Real tether_l = 151.61;」のコメントを外すだけで、ケース 2 と同じエラーが発生します。

どんな助けでも大歓迎です!

model SimplerModel
import Utilities;

Modelica.Mechanics.MultiBody.Joints.FreeMotion freeMotion(
 useQuaternions=false,
 angles_fixed=true,
r_rel_a(start={1,0,0}, fixed=true),
v_rel_a(start={0,0,0}, fixed=true),
a_rel_a(start={0,0,0}),
    angles_start={0,0,0},
    w_rel_a_fixed=true,
    w_rel_a_start={0,0,0},
    z_rel_a_fixed=false)
    annotation (Placement(transformation(extent={{-50,60},{-30,80}})));

  Modelica.Mechanics.MultiBody.Parts.BodyShape bodyShape(
    r={0,0,1},
    m=600,
    I_11=100,
    I_22=100,
    I_33=500,
    angles_start={0,0,0},
    sequence_start={1,2,3},
    w_0_start={0,0,0},
    z_0_start={0,0,0},
    r_0(start={0,0,0}),
    v_0(start={0,0,0}),
    a_0(start={0,0,0}),
    angles_fixed=false,
    w_0_fixed=false,
    z_0_fixed=false,
    r_CM={0,0,0.5})
    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
      inner Modelica.Mechanics.MultiBody.World world
    annotation (Placement(transformation(extent={{-80,60},{-60,80}})));

 Real[6,6] restMat=
 [276533.0, 0.0, 0.0, 0.0, 0.0, 0.0;
 0.0, 276533.0, 0.0, 0.0, 0.0, 0.0;
 Ctest, 0.0, 319160000.0, 0.0, 0.0, 0.0;
 0.0, 0.0, 0.0, 86086300000.0, 0.0, 0.0;
 0.0, 0.0, 0.0, 0.0, 86086300000.0, 0.0;
 0.0, 0.0, 0.0, 0.0, 0.0, 146286000.0];

 Real Ctest = Utilities.findC(bodyShape.frame_a.r_0[1]);
 Real K_cat[:,:] = Utilities.findK(restMat);

equation 
  connect(freeMotion.frame_b, bodyShape.frame_a) annotation (Line(
      points={{-30,70},{-20,70},{-20,0},{-10,0}},
      color={95,95,95},
      thickness=0.5,
      smooth=Smooth.None));
  connect(world.frame_b, freeMotion.frame_a) annotation (Line(
      points={{-60,70},{-50,70}},
      color={95,95,95},
      thickness=0.5,
      smooth=Smooth.None));
  annotation (uses(Modelica(version="3.2")), Diagram(coordinateSystem(
          preserveAspectRatio=false, extent={{-100,-100},{100,100}}), graphics));
end SimplerModel;

関数 findK

function findK

  import Modelica_LinearSystems2;
  input Real[6,6] restoring;

Real cyl_mass = 8.21e6;
 Real[6,6] mass = [1.253e7, 0,0,0,-2.99e8,0;
 0,1.253e7,0,2.99e8,0,0;
 0,0,1.6746e6,0,0,0;
 0,2.99e8,0,9.549e9,0,0;
 -2.99e8,0,0,0,9.549e9,0;
 0,0,0,0,0,3.4728e7];

Real[6,6] damping = [1e5,0,0,0,0,0;
0,1e5,0,0,0,0;
0,0,1.3e5,0,0,0;
0,0,0,0,0,0;
0,0,0,0,0,0;
0,0,0,0,0,1.3e7];

Real Ipitroll = 384770000;
Real Iyaw = 291440000;

protected 
Real[6,6] addMassMat = [0,0,0,0,0,0;
0,0,0,0,0,0;
0,0,cyl_mass,0,0,0;
0,0,0,Ipitroll,0,0;
0,0,0,0,Ipitroll,0;
0,0,0,0,0,Iyaw];

Real[6,6] massMat = Modelica.Math.Matrices.inv(mass + addMassMat);

Real[4, 4] A_cat = cat(1, cat(2,zeros(2,2), identity(2)), cat(2, -restoring[4:5,:]*massMat[:,4:5],-damping[4:5,:]*massMat[:,4:5]));
Real[4, 2] B_cat = cat(1, cat(1,zeros(2,2), 23/cyl_mass*identity(2)));
Real[2, 4] C_cat = cat(2, identity(2), zeros(2,2));
Real[2, 2] D_cat = zeros(2, 2);

Real[4,4] Q = [1e8,0,0,0;
 0,1e8,0,0;
 0,0,1e-8,0;
 0,0,0,1e-8];
Real[2,2] R = [1e-9,0;
 0,1e-9];

output Real K_cat[6,6];

algorithm 
K_cat := Modelica_LinearSystems2.StateSpace.Design.lqr(Modelica_LinearSystems2.StateSpace(A_cat,B_cat,C_cat,D_cat), Q, R);

end findK;

関数 findC

function findC

input Real x;
output Real C;

   //Real tether_l = 151.61;
   //Real slope_ForceVsHeave = 3.1928e8;
   //Real intercept_ForceVsHeave = 0;
   //Real heave = tether_l - sqrt(tether_l^2 - x^2);

algorithm 
 //if abs(x) == 0.0 then
 //C := 0;
 //else C := 0;
 //end if;
    C:=0;
end findC;

どうもありがとう!:)

4

3 に答える 3

1

サポートされていません: 関数 Modelica_LinearSystems2.Math.Matrices.dare で、変数 AT がディメンション ":" で宣言されました

次のように、入力の次元を宣言する必要があることを意味します。

...
input Integer n;
input Real[n] C;
...

これをコンパイルすると、エラーが発生するためです。

...
input Real[:] C;
...

あなたのifステートメントの問題の1つは、それだと思います

abs(x) == 0.0 の場合

に置き換える必要があります

Modelica.Math.isEqual(abs(x),0,1e-15)

Modelica では 2 つの実数の等価性を比較できないためです。

これがお役に立てば幸いです、マルコ

于 2013-07-05T10:49:28.977 に答える
0

問題は、使用している関数に未知の次元の変数が含まれており、Dymola がモデルでこれを処理できないことです。たとえば、 dare 関数には次のものがあります。

Real AT[:, :]=transpose(A);

すべての : がサイズに置き換えられるようにコードを書き直してみてください。場合によっては、これらのサイズがどうなるかを計算するために関数を作成する必要があるかもしれません。

Dymola のどのバージョンを使用していますか? コードをそのまま Dymola 2014 に入れると、「変数 ? はディメンション ":" で宣言された」という長いリストが返されました。

また、関数内のすべての Real 変数を保護する必要があると思います。

うまくいけば、これを修正すると問題が解決します。

于 2013-07-11T06:48:06.610 に答える