使用符号工具箱(R2016b,Windows)找到运动方程后,我得到以下形式:
M(q)*qddot = b(q,qdot) + u
使用 M
找到了
b
和 equationsToMatrix
。
现在,我需要将
b
分成科里奥利和势项,这样
M(q)*qddot + C(q,qdot)*qdot + G(q) = u
如果能申请的话就非常方便了
[C,G] = equationsToMatrix(b,qdot)
但不幸的是,当
qdot
是非线性时,它不会分解 b
。我不在乎(事实上这是必要的)C
是q
和qdot
的函数,即使在分解出向量qdot
之后也是如此。我已经尝试过coeffs
和factor
但没有结果。
谢谢。
发布我自己的解决方案,以便至少有一个答案...... 此功能有效,但未经严格测试。它的工作原理与我在原来的问题中所建议的完全一样。请随意重命名它,这样它就不会与 MATLAB 内置冲突。
function [A,b] = equationsToMatrix( eq, x )
%EQUATIONSTOMATRIX equationsToMatrix for nonlinear equations
% factors out the vector x from eq such that eq = Ax + b
% eq does not need to be linear in x
% eq must be a vector of equations, and x must be a vector of symbols
assert(isa(eq,'sym'), 'Equations must be symbolic')
assert(isa(x,'sym'), 'Vector x must be symbolic')
n = numel(eq);
m = numel(x);
A = repmat(sym(0),n,m);
for i = 1:n % loop through equations
[c,p] = coeffs(eq(i),x); % separate equation into coefficients and powers of x(1)...x(n)
for k = 1:numel(p) % loop through found powers/coefficients
for j = 1:m % loop through x(1)...x(n)
if has(p(k),x(j))
% transfer term c(k)*p(k) into A, factoring out x(j)
A(i,j) = A(i,j) + c(k)*p(k)/x(j);
break % move on to next term c(k+1), p(k+1)
end
end
end
end
b = simplify(eq - A*x,'ignoreanalyticconstraints',true); % makes sure to fully cancel terms
end
伙计,我衷心感谢您解决了您的问题。我需要用 6 个自由度的物体的运动方程来解决同样的问题,如果用手解决的话会很长。我将原始微分方程组划分为矩阵,然后再次相乘,所有内容都与原始矩阵匹配。
这是我获得每个矩阵时的步骤示例:
q = [x; y; z; phi; theta; psi]
qdot = [x_dot;y_dot;z_dot;phi_dot;theta_dot;psi_dot]
qddot = [x_ddot;y_ddot;z_ddot;phi_ddot;theta_ddot;psi_ddot]
% initial equations of motion
eqns = transpose([eqddx, eqddy, eqddz, eqddphi, eqddtheta, eqddpsi])
%Mass and inertia matrix (you can also use the matlab function)
[MM, zbytek] = equationsToMatrix(eqns, qddot)
%Coriolis force and drag force matrix
[C_G, zbytek2] = equationsToMatrix_abatea(-1*zbytek, qdot)
%my some inputs in differential equations
inputs = [Thrust; Tau_phi; Tau_theta; Tau_psi];
%Matrix for inputs L and gravity Q
[L, Q] = equationsToMatrix_abatea(-1*zbytek2, inputs)
Q = -1*Q;
乘法进行比较
vychozi = expand(eqns)
roznasobeni = expand( MM*qddot + C_G*qdot + Q == L*inputs)