如何在没有分析雅可比的情况下从 FMU 或 Dymola 访问模型雅可比

How to access model jacobian from FMU or Dymola without analytical jacobian

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

最后 objective 是使用相同的过程来访问更复杂的多体车辆模型(205 个状态)的雅可比矩阵。

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

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;

这个模型有:

对于这个测试,

由于这是一个线性模型,所以雅可比在整个模拟过程中应该是一个常数值。对于这个模型,当我设置标志 Advanced.GenerateAnalyticJacobian = true 时,我得到了从 fmi2GetDirectionalDerivative() 计算的模型 jacobian 的以下值,用于已知和未知的所有组合。在所有情况下,dvKnown = 1 用于函数。

根据状态 space 等式,这些值是正确的:

+--------------+----------+
| 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      |
+--------------+----------+

但是,如果我设置标志 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.AllowNumericDifferentiationAdvanced.AutomaticDifferentiation)并将求解器更改为 CVODE、DASSL 等,但值仍然不正确。

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

对于如何从 FMU 中获取模型 jacobian 的任何意见,我将不胜感激。

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

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

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

请 Dymola 检查他们对 fmi2GetDirectionalDerivative()Advanced.GenerateAnalyticJacobian = false 的实施情况。

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

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

我猜这是 Dymola 的协同仿真实现中的某种错误 w.r.t 数值雅可比矩阵。