4

我正在尝试通过编译的 FMU 或导出的 Dymola 源代码找到一种方法来访问 dymola 中模型的 jacobian。

最终目标是使用相同的程序来访问更复杂的多体车辆模型(205 个状态)的雅可比。

使用fmi2GetDirectionalDerivative()FMI 标准似乎很有希望,所以我制作了一个简单的线性车辆模型来测试它。

model Vehicle "Single-track Linear bicycle vehicle model"
  extends Modelica.Blocks.Icons.Block;
  import SI = Modelica.SIunits;
  import MB = Modelica.Mechanics.MultiBody;

  // model parameters
  parameter SI.Velocity u = 10 "forward velocity";
  parameter SI.Inertia Iz = 2000 "yaw moment of inertia";
  parameter SI.Length L = 3 "wheel base";
  parameter SI.Mass Mf = 900 "front axle mass";
  parameter SI.Mass Mr = 600 "rear axle mass";
  parameter Real Cf(unit="N/rad") = 300000 "front axle cornering stiffness";
  parameter Real Cr(unit="N/rad") = 200000 "rear axle cornering stiffness";

  // calculated parameters
  final parameter SI.Mass M = Mf + Mr "mass";
  final parameter SI.Length a = Mr/Mf*L "CG position front";
  final parameter SI.Length b = L - a "CG position front";

  input SI.Angle delta "steering angle" annotation(Dialog(group="Inputs"));

public 
  SI.Velocity v "lateral velocity";
  output SI.Acceleration ay "lateral acceleration";
  SI.AngularVelocity r "yaw rate";

equation 

  ay = der(v) + u*r;
  M*(der(v) + u*r) = Cf*(delta-(v+a*r)/u) + Cr*(-(v-b*r)/u);
  Iz*der(r) = a*Cf*(delta-(v+a*r)/u) - b*Cr*(-(v-b*r)/u);

end Vehicle;

该模型具有:

  • 州 -vr
  • 输入 -delta
  • 输出 -ay

对于本次测试,

  • delta=amp*sin(2*Modelica.Constants.pi*freq*time)

    • amp = 1*Modelica.Constants.pi/180
    • freq = 0.5
  • 版本:Dymola 2020x

  • 求解器:RKFIX2
  • 时间步长:0.01s
  • 协同仿真 FMU

由于这是一个线性模型,所以雅可比在整个模拟过程中应该是一个恒定值。对于这个模型,当我设置 flag 时Advanced.GenerateAnalyticJacobian = true,我会得到以下模型 jacobian 的值,这些值是根据已知fmi2GetDirectionalDerivative()和未知的所有组合计算得出的。在所有情况下,dvKnown = 1对于功能。

根据状态空间方程,这些值是正确的:

+--------------+----------+
| Derivative   | Value    |
+--------------+----------+
| der(v)/delta | 200      |
+--------------+----------+
| ay/delta     | 200      |
+--------------+----------+
| der(r)/delta | 300      |
+--------------+----------+
| der(v)/v     | -33.3333 |
+--------------+----------+
| ay/v         | -33.3333 |
+--------------+----------+
| der(r)/v     | -20      |
+--------------+----------+
| der(v)/r     | -36.6667 |
+--------------+----------+
| ay/r         | -26.6667 |
+--------------+----------+
| der(r)/r     | -70      |
+--------------+----------+

但是,如果我设置 flag Advanced.GenerateAnalyticJacobian = false,我会得到以下完全垃圾值:

+--------------+-----------+
| Derivative   | Value     |
+--------------+-----------+
| der(v)/delta | -1.57E+11 |
+--------------+-----------+
| ay/delta     | -1.57E+11 |
+--------------+-----------+
| der(r)/delta | 1.52942   |
+--------------+-----------+
| der(v)/v     | -9.12E+08 |
+--------------+-----------+
| ay/v         | -9.12E+08 |
+--------------+-----------+
| der(r)/v     | 14999.8   |
+--------------+-----------+
| der(v)/r     | 5.47E+11  |
+--------------+-----------+
| ay/r         | 5.47E+11  |
+--------------+-----------+
| der(r)/r     | -2.25E+07 |
+--------------+-----------+

我希望该值与分析值不同,因为它是数值计算的,但我不明白为什么它完全错误。

我尝试启用其他一些标志(Advanced.AllowNumericDifferentiation, Advanced.AutomaticDifferentiation)并将求解器更改为 CVODE、DASSL 等,但值仍然不正确。

不幸的是,Dymola 无法为大型模型计算分析雅可比,因此我无法使用该选项。我读过的所有文献都指向fmi2GetDirectionalDerivative().

我将不胜感激有关如何将模型 jacobian 从 FMU 中取出的任何意见。

如果有其他方法可以通过 Dymola 使用,那也可以,因为我们有源代码导出许可证。

4

2 回答 2

0

无法评论,所以这是一个不是答案的答案:

结果不完全是垃圾:对于第一个表中的相同值(例如,前两行为 200),您在第二个表中得到相同的值(-1.57E+11)。一个例外是der(v)/ray/r,它们在第二个表中是相同的,但这可能是因为值被截断了。

要求 Dymolafmi2GetDirectionalDerivative()结合Advanced.GenerateAnalyticJacobian = false.

于 2020-01-10T11:04:49.513 回答
0

为了将来参考,我能够部分解决这个问题。

当我导出模型交换 FMU 时,我得到了数值雅可比的有意义的值(非常接近分析值)。

我猜这是 Dymola 的 Co-Simulation 实现 wrt numeric jacobians 中的某种错误。

于 2020-01-17T14:09:07.507 回答