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

Modelica 如何在没有分析雅可比矩阵的情况下从FMU或Dymola访问模型雅可比矩阵,modelica,dymola,fmi,Modelica,Dymola,Fmi,我试图找到一种方法,通过编译的FMU或从导出的dymola源代码访问dymola中模型的雅可比矩阵 最终目标是使用相同的程序访问更复杂的多体车辆模型(205个状态)的雅可比矩阵 使用FMI标准中的FMI2GetDirectionalDiversitive()似乎很有希望,因此我制作了一个简单的线性车辆模型来测试这一点 model Vehicle "Single-track Linear bicycle vehicle model" extends Modelica.Blocks.Icons.

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

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

使用FMI标准中的
FMI2GetDirectionalDiversitive()
似乎很有希望,因此我制作了一个简单的线性车辆模型来测试这一点

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;
这种模式有:

  • 状态-
    v
    r
  • 输入-
    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
因为这是一个线性模型,所以在整个仿真过程中,雅可比矩阵应该是一个常数值。对于这个模型,当我设置标志
Advanced.GenerateAnalyticJacobian=true
时,我得到了从
fmi2GetDirectionalDiversitive()
计算的模型雅可比矩阵的以下值,用于已知和未知的所有组合。在所有情况下,
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      |
+--------------+----------+
但是,如果我设置标志
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无法计算大型模型的分析雅可比矩阵,因此我无法使用该选项。我读到的所有文献都指向
fmi2getdirectionaldivative()

如果您能提供有关如何将模型雅可比矩阵从FMU中取出的任何信息,我将不胜感激


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

无法评论,因此这里有一个不是答案的答案:

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


请Dymola检查他们的
fmi2GetDirectionalDerivation()
Advanced.GenerateAnalyticJacobian=false

相结合的实施情况,以供将来参考,我能够部分解决此问题

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


我猜这是Dymola的联合仿真实现w.r.t数值雅可比矩阵中的某种缺陷。

我怎么能调用
fmi2GetDirectionalDerivative()
?在Dymola中还是在MATLAB中?你能给我一个提示吗?这是一个编译过的C函数。您必须使用某种包装器来调用该函数。检查输入和输出的文档。如果您熟悉python,还可以使用FMPy,因为它们为这些函数提供了包装。