Reputation: 81
After finding equations of motion using the Symbolic Toolbox (R2016b, Windows), I have the following form:
M(q)*qddot = b(q,qdot) + u
M
and b
were found using equationsToMatrix
.
Now, I need to separate b
into Coriolis and Potential terms such that
M(q)*qddot + C(q,qdot)*qdot + G(q) = u
It would be extremely convenient if I could apply
[C,G] = equationsToMatrix(b,qdot)
but unfortunately it will not factor out qdot
when b
is nonlinear. I do not care (and in fact it is necessary) that C
is a function of q
and qdot
, even after factoring out the vector qdot
. I have tried coeffs
and factor
without results.
Upvotes: 1
Views: 1448
Reputation: 1
Dude, I would like to thank you from the bottom of my heart for your solution to your problem. I needed to solve the same problem with the equations of motion of a body with 6 degrees of freedom, by hand it would have been very long. I divided the system of original differential equations into matrices and then multiplied again and everything matches the original ones.
Here is an example of my steps as I obtained each matrix:
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;
Multiplication for comparison
vychozi = expand(eqns)
roznasobeni = expand( MM*qddot + C_G*qdot + Q == L*inputs)
Upvotes: -1
Reputation: 81
Posting my own solution so there can be at least one answer... This function works, but it is not heavily tested. It works exactly as I suggested in my original question. Feel free to rename it so it doesn't conflict with the MATLAB builtin.
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
Upvotes: 2