我正在模拟具有质量弹簧和双摆的(有些奇怪的)系统的运动方程,我有一个质量矩阵和函数 f(x),并调用 ode45 来求解
M*x' = f(x,t);
我有 5 个状态变量,q= [ QDot, phi, phiDot, r, rDot]'; (删除了 Q,因为没有任何东西依赖它,QDot 是当前的。)现在,为了计算一些力,我还想保存 rDotDot 的计算值,ode45 会为每个积分步骤计算该值,但是 ode45 不会返回这个值。我搜索了一下,但我发现的唯一两个解决方案是 a) 将其转换为 3 阶问题并将 phiDotDot 和 rDotDot 添加到状态向量中。我想尽可能地避免这种情况,因为它已经是非线性的,这确实使事情变得更糟,并增加了计算时间。
b) 扩充状态以直接计算函数,如此处所述。但是,在示例中,他说要在质量矩阵中添加一行零。这是有道理的,因为否则它将集成导数,而不仅仅是在某一点上对其进行评估,另一方面它会使质量矩阵变得奇异。似乎对我不起作用...
这似乎是一个基本的事情(想要状态向量的导数值),有什么我没有想到的非常明显的事情吗?(或者不那么明显的东西也可以....)
哦,全局变量不是很好,因为 ode45 在优化它的步骤时多次调用 f() 函数,所以全局变量的大小和返回的状态向量 q 根本不匹配。
如果有人需要,代码如下:
%(Initialization of parameters are above this line)
options = odeset('Mass',@massMatrix);
[T,q] = ode45(@f, tspan,q0,options);
function dqdt = f(t,q,p)
% q = [qDot phi phiDot r rDot]';
dqdt = zeros(size(q));
dqdt(1) = -R/L*q(1) - kb/L*q(3) +vs/L;
dqdt(2) = q(3);
dqdt(3) = kt*q(1) + mp*sin(q(2))*lp*g;
dqdt(4) = q(5);
dqdt(5) = mp*lp*cos(q(2))*q(3)^2 - ks*q(4) - (mb+mp)*g;
end
function M = massMatrix(~,q)
M = [
1 0 0 0 0;
0 1 0 0 0;
0 0 mp*lp^2 0 -mp*lp*sin(q(2));
0 0 0 1 0;
0 0 mp*lp*sin(q(2)) 0 (mb+mp)
];
end