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.
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