Внедрение средств управления с помощью Dymola

У меня возникли проблемы с реализацией встроенного алгоритма управления (LQR) в Modelica / Dymola. Я создал более простую модель, которая показывает мои проблемы.

По сути, я вызываю LQR извне и передаю ему матрицу с записью (с именем Ctest), которая изменяется на каждом временном шаге. Этот Ctest также можно найти с помощью внешней функции с именем findC.

Забавно то, что Dymola будет работать нормально, если вы сделаете Ctest = 0, но если вы сделаете Ctest = 0 в цикле if, он покажет множество ошибок, которые выглядят примерно так: Unsupported: в функции Modelica_LinearSystems2.Math.Matrices Переменная .dare AT была объявлена ​​с размером ":". Это еще не поддерживается в dsmodel.c, и функция завершится ошибкой, если будет вызвана в модели.

Например, я запустил 3 разных случая со следующим кодом: 1. в функции findC, если вы определяете C как 0 (как скопировано ниже), все работает нормально. 2. если вместо этого вы создадите цикл if, в котором C будет по-прежнему равным 0, модель не будет имитироваться. Я скопировал цикл if ниже и закомментировал его. 3. Если вы оставите findC как в случае 1, но просто раскомментируете «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;

Большое спасибо! :)


person user2549651    schedule 04.07.2013    source источник


Ответы (3)


Не поддерживается: в функции Modelica_LinearSystems2.Math.Matrices.dare была объявлена ​​переменная AT с размером ":"

означает, что вы должны объявить размер ваших входных данных, например:

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

потому что это, если оно скомпилировано, приведет к ошибке:

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

Я думаю, что одна проблема в вашем if-выражении заключается в том, что

если abs (x) == 0.0, то

следует заменить на

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

потому что вы не можете сравнить равенство двух действительных чисел в Modelica.

Надеюсь, это поможет, Марко

person Marco Romanoni    schedule 05.07.2013
comment
Спасибо за Ваш ответ! Я изменил условие if и объявил все размеры, но все равно получаю ошибки. Проблема в том, что переменные в сообщениях об ошибках (например, AT) объявляются не мной, а Димолой. Я подозревал, что Димола преобразовал мою модель в свою собственную систему пространства состояний, попытался дифференцировать уравнения для уменьшения индекса и, таким образом, ввел новые переменные. Я не понимаю, зачем делать такую ​​тривиальную вещь, как раскомментирование tether_l = 151.61; внезапно заставит Димолу объявить свои переменные по-другому. Есть ли у вас какие-нибудь идеи? Спасибо! - person user2549651; 08.07.2013

Я думаю, что Марко прав, проблема в том, что используемые вами функции содержат переменные неизвестных размеров, и Димола не может справиться с этим в модели. Например, функция dare имеет:

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

Попробуйте переписать код так, чтобы все: были заменены размерами. В некоторых случаях вам может потребоваться создать функции для вычисления этих размеров.

Какую версию Dymola вы используете? Я поместил код как есть в Dymola 2014, и он вернул длинный список «переменная? Была объявлена ​​с размером«: »».

Также я думаю, что все переменные Real в функциях должны быть защищены.

Надеюсь, это решит проблему.

person user2024223    schedule 11.07.2013
comment
Спасибо за вклад! Я использую Dymola 2014, который возвращает мне тот же список предупреждений. Я изменил код так, чтобы все матрицы объявлялись с размером (только K_cat, который должен иметь размер [2,4] в данном случае) и защищал все вещественные числа, но безуспешно. И поскольку все переменные, которые отображаются в списке предупреждений, объявлены Dymola, я также не могу жестко запрограммировать их размеры. Но даже изменения, которые, кажется, не имеют ничего общего с матрицами, вызывают ошибки (см. 1-й тестовый пример в исходной публикации). Из-за этого я действительно сбит с толку этими ошибками, поэтому будет очень признателен за любую дополнительную помощь! :) - person user2549651; 11.07.2013
comment
Если вы опубликуете этот код, я посмотрю на него (хотя, вероятно, только на следующей неделе) - person user2024223; 12.07.2013
comment
Конечно, размещено ниже! Огромное спасибо :) - person user2549651; 12.07.2013
comment
Хорошо, я думаю, что ваш код сейчас в порядке, что нужно изменить, так это код Modelica_LinearSystems2. Для этого есть два разных подхода: - person user2024223; 12.07.2013
comment
1. Попросите группу, отвечающую за библиотеку, изменить код, чтобы вы больше не получали эти ошибки. 2. Дублируйте библиотеку и измените ее (найдите, где в коде требуется модификация, посмотрев, куда указывают сообщения об ошибках). Затем, когда вы добьетесь его компиляции без ошибок, отправьте его группе Modelica_linearSystem2 и предложите им реализовать ваши изменения. Я бы выбрал второй метод. - person user2024223; 12.07.2013
comment
Хм, я этого боялся. Что ж, сделаю и обновлю вас, если что-нибудь интересное появится. Огромное спасибо! - person user2549651; 15.07.2013

Это код после модификации в соответствии с двумя ответами (объявить размеры всех матриц, защитить Reals в функциях, изменить условие):

model SimplerModel
import OnWind.Components.Substructure.Utilities;

Modelica.Mechanics.MultiBody.Joints.FreeMotion freeMotion(
 useQuaternions=false,
 angles_fixed=true,
r_rel_a(start={0.5,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
    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
      inner Modelica.Mechanics.MultiBody.World world
    annotation (Placement(transformation(extent={{-80,60},{-60,80}})));

 //input Integer hi = 1;
 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_b.r_0[1]);
 Real K_cat[2,4] = 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;

protected 
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;

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[2,4];

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;

algorithm 
 C:=0;

/* if Modelica.Math.isEqual(abs(x),0,1e-15) then
 C := 0;
 else C := 0;
 end if;  
 */
end findC;

Это должно работать как есть. Но я закомментировал необходимые части функции findC, чтобы она работала. В findC раскомментирование либо объявления неиспользуемой переменной tether_l (которая требуется в моем фактическом коде), либо оператора if (также необходимого в моем коде, но написанного здесь как тривиальный оператор только для этого более простого примера) приведет к его сбою.

Подводя итог, Dymola создает длинный список «Не поддерживается: в функции _ _ переменная __ была объявлена ​​с размером«: »». Но все эти переменные на самом деле объявлены Dymola в функциях Dymola. Некоторые изменения заставляют его работать, но эти изменения не связаны с матрицами.

Буду признателен за любые идеи или советы! :)

Спасибо

person user2549651    schedule 12.07.2013