2013-07-04 1 views
0

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

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

Самое смешное, что Dymola будет работать нормально, если вы создадите Ctest = 0, но если вы сделаете Ctest = 0 в if-loop, это покажет много ошибок, которые выглядят примерно так: Неподдерживаемый: функция 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; 

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

ответ

1

Unsupported: In function Modelica_LinearSystems2.Math.Matrices.dare variable AT was declared with dimension ":"

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

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

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

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

I подумайте, что одна из проблем в вашей заявке на то, что

if abs(x) == 0.0 then

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

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

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

Я надеюсь, что это помогает, Marco

+0

Спасибо за ваш ответ! Я изменил условие if и объявил все измерения, но все равно получаю ошибки. Проблема заключается в том, что переменные в сообщениях об ошибках (например, AT) не объявлены мной, а Dymola. Мое подозрение заключалось в том, что Дымола превратил мою модель в свою государственную космическую систему, попытался дифференцировать уравнения для уменьшения индекса и таким образом ввел новые переменные. Я не понимаю, почему делать что-то настолько тривиальное, как раскол «tether_l = 151.61;» внезапно заставит Dymola объявить свои переменные по-разному. У вас есть идеи? Спасибо! – user2549651

0

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

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

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

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

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

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

+0

Спасибо за вход! Я использую Dymola 2014, который возвращает тот же список предупреждений для меня. Я изменил код так, чтобы все матрицы были объявлены с размером (только K_cat, который в этом случае должен быть размером [2,4]) и защитил все Reals, но не повезло. И поскольку все переменные, отображаемые в списке предупреждений, объявлены Dymola, я также не могу жестко задавать их размеры. Но даже изменения, которые, похоже, не имеют ничего общего с матрицами, вызывают ошибки (см. Первый тестовый пример в оригинальной публикации). Из-за этого меня действительно путают эти ошибки, поэтому любая дополнительная помощь будет принята с благодарностью! :) – user2549651

+0

Если вы опубликуете этот код, я посмотрю на него (возможно, только на следующей неделе когда-нибудь) – user2024223

+0

Конечно, размещен ниже! Большое спасибо :) – user2549651

0

Это код после изменения в соответствии с двумя ответами (объявлять размеры всех матриц, защитить 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. Некоторые изменения заставляют его работать, но эти изменения не связаны с матрицами.

Поблагодарили бы за любые идеи или советы! :)

Thanks

 Смежные вопросы

  • Нет связанных вопросов^_^