How can I find eigenvectors of a matrix in Simulink?

12 views (last 30 days)
Hi,
I need to go from Euler angles to one vector describing the axis of rotation and the magnitude of rotation about that axis (angle in radians). To solve this I need to find the real eigenvector of the rotation matrix (3 by 3 matrix). The angle is the trace of the matrix. ( Rotation Matrix)
I am currently using this code which I have put in a Matlab Function Block in Simulink:
function rot = fcn(R)
% Takes in rotation matrix (R) and returns one vector where the three first elements
% denote the axis of rotation and the last element is the angle of rotation
% about the axis.
rot = zeros(4,1);
[V,~] = eig (R);
for i = 1:3
if isreal(V(:,i))
rot(1:3,1) = V(:,i);
rot(4,1) = trace(R);
end
end
end
When running the Simulink model, the output is always
rot = [0;0;0;0]
The transformation matrix changes all the time, but at one point it is
R =
0.9998 0.0002 -0.0181
-0.0005 0.9998 -0.0189
0.0181 0.0189 0.9997
Running the code through the command window gives
rot =
0.7232
-0.6905
-0.0130
2.9993
which is the correct eigenvector.
I looked at this page: Functions and Objects Supported for C and C++ Code Generation — Alphabetical List. It only seems like the difference for the eig function should be the normalization of the eigenvectors.
Thank you, Erlend

Accepted Answer

Stefan Raab
Stefan Raab on 30 Nov 2015
Hi, if you execute "eig" from Simulink, all the output eigenvectors will be complex, as you can see at the page you already found. The eigenvectors are still valid, as you can multiply each eigenvector by a scalar (which can also be complex). But as you check the eigenvectors for being real or not, the part
if isreal(V(:,i))
rot(1:3,1) = V(:,i);
rot(4,1) = trace(R);
end
is never true and therefore the variable rot remains at
rot = zeros(4,1);
which explains why your output is always 0. I would recommend to check the eigenvalues of R for the real eigenvalue as this will not change. You can get the output for the eigenvalues with
[V,D] = eig (R);
and then you have only to check the diagonal elements of D. So instead of
if isreal(V(:,i))
try the following:
if imag(D(ind,ind))<0.0000000001
or something like that. I would not use "isreal" because even if you have the slightest imaginary part (from numerical errors), this will not give the right answer. You also have to think of the complex eigenvector you will get, so you have to extend an "abs". The absolute of the elements of the eigenvector should not change i think.
I hope this might help you.
Kind regards, Stefan

More Answers (0)

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!