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