【发布时间】:2020-01-03 15:07:34
【问题描述】:
我正在尝试通过编译的 FMU 或导出的 Dymola 源代码找到一种方法来访问 dymola 中模型的 jacobian。
最终目标是使用相同的程序来访问 jacobian 以获得更复杂的多体车辆模型(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;
这个模型有:
- 状态 -
v和r - 输入 -
delta - 输出 -
ay
对于这个测试,
-
delta=amp*sin(2*Modelica.Constants.pi*freq*time)与amp = 1*Modelica.Constants.pi/180freq = 0.5
版本:Dymola 2020x
- 求解器:RKFIX2
- 时间步长:0.01s
- 协同仿真 FMU
由于这是一个线性模型,雅可比在整个模拟过程中应该是一个常数值。对于这个模型,当我设置标志 Advanced.GenerateAnalyticJacobian = true 时,对于已知和未知的所有组合,我得到了从 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 |
+--------------+----------+
但是,如果我设置标志 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 使用,那也可以,因为我们有源代码导出许可证。
【问题讨论】:
-
我怎么打电话给
fmi2GetDirectionalDerivative()?在 Dymola 中还是在 MATLAB 中?你能给我一个提示吗? -
它是一个编译的 C 函数。您将不得不使用某种包装器来调用该函数。检查输入和输出的文档。如果您对 python 感到满意,您也可以使用 FMPy,因为它们具有这些函数的包装器。 svn.modelica.org/fmi/branches/public/specifications/v2.0/…