我在 Modelica/Dymola 中实现内置控制算法 (LQR) 时遇到问题。我创建了一个更简单的模型来显示我遇到的问题。
基本上,我在外部调用 LQR 并向其传递一个矩阵,其中包含一个在每个时间步都发生变化的条目(名为 Ctest)。这个 Ctest 也可以通过一个名为 findC 的外部函数找到。
有趣的是,如果您使 Ctest = 0,Dymola 将运行良好,但是如果您在 if 循环中使 Ctest = 0,它会显示许多看起来像这样的错误: Unsupported: In function Modelica_LinearSystems2.Math.Matrices .dare 变量 AT 用维度“:”声明。这在 dsmodel.c 中尚不支持,如果在模型中调用该函数将失败。
例如,我使用以下代码运行了 3 个不同的案例: 1. 在函数 findC 中,如果您将 C 定义为 0(如下所示),一切运行正常。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;
非常感谢!:)