Разложение матрицы вращения (x, y', z'') - декартовы углы

Разложение матрицы вращения (x, y', z'') - декартовы углы

В настоящее время я работаю с матрицами вращения, и у меня есть следующая проблема: даны три системы координат (O0,x0,y0,z0; O1,x1,y1,z1; O2,x2,y2,z2), которые совпадают. Сначала вращаем кадр №1 относительно кадра №0, затем кадр №2 относительно кадра №1.

Порядок вращения: R = Rx_alpha * Ry_beta * Rz_gamma, то есть сначала около x, затем y', затем < em>z'', которые также известны как декартовы углы. Если R1 обозначает 1-й, а R2 — 2-й поворот, мы ищем углы 2-го кадра по отношению к начальному кадру (#0) после обоих поворотов. Это можно сделать, разложив матрицу вращения R (где: R = R1*R2 ). Существует много доступной литературы о том, как это можно сделать с помощью углов Эйлера и RPY, но я не нашел ни одной, как решить эту проблему в случае декартовых углов.

У меня есть функция Matlab, которая работает только с простыми вращениями. Если все углы имеют значения, отличные от 0 (пример ниже), то результат становится действительно нестабильным.

Ориентация 1-го кадра относительно кадра №0:

    alpha1 = 30*pi/180;
    beta1 = 10*pi/180;
    gamma1 = 0*pi/180;

Ориентация 2-го кадра относительно кадра №1

    alpha2 = 10*pi/180;
    beta2 = 10*pi/180;
    gamma2 = 0*pi/180;

Функция Matlab, которую я использовал для решения проблемы:

function [q] = cartesian_angles(R)

beta = asin(R(1,3));

*% Catching the numerical singularty*
if abs(abs(beta)-pi/2) > eps;
    *% singulartiy of acos*
    gamma1 = acos(R(1,1) / cos(beta));
    gamma2 = asin(-R(1,2) / cos(beta));
    if gamma2<0
        gamma=2*pi-gamma1;
    else
        gamma=gamma1;
    end
    alpha1 = acos(R(3,3) / cos(beta));
    alpha2 = asin(-R(2,3) / cos(beta));
    if alpha2<0
        alpha = 2*pi-alpha1;
    else
        alpha = alpha1;
    end
else
    fprintf('beta=pi/2 \n')
    gamma = 0;
    alpha = 0;
    beta  = 0;
end;

alpha = alpha*180/pi;
beta = beta*180/pi;
gamma = gamma*180/pi;

q = [alpha; beta; gamma];

Спасибо за любую помощь! Если у вас есть вопросы, не стесняйтесь спрашивать!

Марси


person Marton    schedule 24.08.2016    source источник
comment
Во-первых, в Matlab есть функция atan2(), которая избавит вас от головной боли. Во-вторых, я думаю, что углы Эйлера - это то же самое, что вы пытаетесь использовать здесь. Я ошибся?   -  person willpower2727    schedule 24.08.2016
comment
Я знаю о функции atan2, но, честно говоря, я пока не очень уверен в ее использовании, я не знаю, как включить ее в приведенный выше код. По углам Эйлера ось первого и последнего поворота всегда одна и та же (например: Z,X',Z''). По углам Кардана мы делаем один оборот вокруг каждой оси (например: X,Y',Z''), однако порядок поворотов может меняться (по этой ссылке: kwon3d.com/theory/euler/euler_angles.html). В моем понимании это означает, что углы Roll-Pitch-Yaw (Z, Y', X'') - это просто особый вид углов Кардана. Что я ищу: X,Y',Z''   -  person Marton    schedule 25.08.2016


Ответы (2)


Во-первых, я собираюсь предположить, что вы передаете в свою функцию хорошо обусловленную матрицу правостороннего вращения. Я собираюсь использовать ту же последовательность вращения, которую вы указали выше, X Y 'Z''

Если вы знаете символическую конструкцию матрицы поворота, из которой пытаетесь извлечь углы, математика довольно проста. Ниже приведен пример кода Matlab для определения построения матрицы вращения порядка X-Y'-Z''

a = sym('a');%x
b = sym('b');%y
g = sym('g');%z

Rx = [1 0 0;0 cos(a) -sin(a);0 sin(a) cos(a)];
Ry = [cos(b) 0 sin(b);0 1 0;-sin(b) 0 cos(b)];
Rz = [cos(g) -sin(g) 0;sin(g) cos(g) 0;0 0 1];

R = Rz*Ry*Rx

Вывод выглядит следующим образом:

R =

[ cos(b)*cos(g), cos(g)*sin(a)*sin(b) - cos(a)*sin(g), sin(a)*sin(g) + cos(a)*cos(g)*sin(b)]
[ cos(b)*sin(g), cos(a)*cos(g) + sin(a)*sin(b)*sin(g), cos(a)*sin(b)*sin(g) - cos(g)*sin(a)]
[       -sin(b),                        cos(b)*sin(a),                        cos(a)*cos(b)]

Вот тот же результат в более красивом формате:

введите здесь описание изображения

Теперь давайте пройдемся по математике, чтобы извлечь углы из этой матрицы. Сейчас самое время освоиться с функцией atan2().

Сначала найдите угол бета (кстати, альфа — это вращение вокруг оси X, бета — это вращение вокруг оси Y’, а гамма — это угол вокруг оси Z’’):

beta = atan2(-1*R(3,1),sqrt(R(1,1)^2+R(2,1)^2))

Написано более официально,

введите здесь описание изображения

Теперь, когда мы решили для бета-угла, мы можем более просто решить для двух других углов:

alpha = atan2(R(3,2)/cos(beta),R(3,3)/cos(beta))
gamma = atan2(R(2,1)/cos(beta),R(1,1)/cos(beta))

Упрощенный и в более приятном формате,

введите здесь описание изображения

введите здесь описание изображения

Приведенный выше метод является довольно надежным способом получения углов Эйлера из вашей матрицы вращения. Функция atan2 действительно делает это намного проще.

Наконец, я отвечу, как решить углы поворота после серии поворотов. Сначала рассмотрим следующие обозначения. Вектор или матрица вращения будут обозначаться следующим образом:

введите здесь описание изображения

Здесь «U» представляет собой универсальную систему координат или глобальную систему координат. «Fn» представляет собой n-ю локальную систему координат, отличную от U. R означает матрицу вращения (это обозначение также можно использовать для однородных преобразований). Верхний индекс с левой стороны всегда будет представлять родительскую систему отсчета матрицы вращения или вектора. Нижний индекс слева указывает на дочернюю систему отсчета. Например, если у меня есть вектор в F1, и я хочу знать, что он эквивалентен в универсальной системе отсчета, я бы выполнил следующую операцию:

введите здесь описание изображения

Чтобы получить вектор, разрешенный в универсальной системе отсчета, я просто умножил его на матрицу вращения, которая преобразует вещи из F1 в U. Обратите внимание, как нижние индексы «отменяются» верхним индексом следующего элемента в уравнении. Это умная нотация, чтобы помочь кому-то не запутаться. Если вы помните, особым свойством хорошо обусловленных матриц вращения является то, что обратная матрица является транспонированной матрицей, которая также будет обратным преобразованием, подобным этому:

введите здесь описание изображения

Теперь, когда детали обозначений убраны, мы можем приступить к рассмотрению сложных серий вращений. Допустим, у меня есть "n" количество координатных кадров (другой способ сказать "n" различных поворотов). Чтобы определить вектор в «n-м» кадре универсального кадра, я бы сделал следующее:

введите здесь описание изображения

Чтобы определить углы Кардана/Эйлера, возникающие в результате «n» поворотов, вы уже знаете, как разложить матрицу, чтобы получить правильные углы (также известные как инверсная кинематика в некоторых областях), вам просто нужна правильная матрица. В этом примере меня интересует матрица вращения, которая берет объекты в «n-й» системе координат и переводит их в универсальную систему координат U:

введите здесь описание изображения

Вот он, я объединил все вращения в интересующее, просто перемножив в правильном порядке. Этот пример был легким. Более сложные случаи возникают, когда кто-то хочет найти систему отсчета одного твердого тела, разрешенную в системе отсчета другого, и единственное, что объединяет два твердых тела, это их измерение в универсальной системе отсчета.

Хочу также отметить, что эти обозначения и метод можно использовать и с однородными преобразованиями, но с некоторыми ключевыми отличиями. Обратной матрицей вращения является ее транспонирование, это неверно для однородных преобразований.

person willpower2727    schedule 25.08.2016
comment
Спасибо за ответ @willpower2727! Мой комментарий превысил бы лимит символов, поэтому я отреагировал на ваш ответ в новом ответе. Марси - person Marton; 25.08.2016
comment
Спасибо за ваш измененный комментарий, он действительно хорошо детализирован и прямолинеен! Мой комментарий снова занял бы слишком много времени, поэтому я должен написать ответ. Поскольку SO говорит мне использовать ответы только для настоящих ответов, а не для вопроса, я предпочитаю не добавлять новый, а просто редактирую/обновляю свой предыдущий ответ. Кстати, во время вычислений я использую правило правой руки, я связываю вращения в правильной последовательности вместе и выполняю вычисления в радианах. Так что будем надеяться, что проблема в чем-то другом. Еще раз спасибо за терпение и подробные ответы! - person Marton; 27.08.2016
comment
@Marci.P Надеюсь, все получилось. Если вы считаете, что мой ответ был полезен, пожалуйста, проголосуйте и выберите, чтобы другие, читающие этот вопрос, знали, где искать. - person willpower2727; 02.09.2016

Спасибо за ваш ответ willpower2727, ваш ответ был действительно полезен!

Но я хотел бы отметить, что показанный вами код полезен для декомпозиции матриц вращения, которые строятся следующим образом:

R = Rz*Ry*Rx

Что я ищу:

R = Rx*Ry*Rz

Что приводит к следующей матрице вращения:

Вращательная матрица

Однако это не проблема, так как, следуя методу расчета углов альфа, бета и гамма, было легко изменить код, чтобы он разлагал матрицу, показанную выше.

Углы:

beta = atan2(  R(1,3), sqrt(R(1,1)^2+(-R(1,2))^2) )
alpha = atan2( -(R(2,3)/cos(beta)),R(3,3)/cos(beta) )
gamma = atan2( -(R(1,2)/cos(beta)),R(1,1)/cos(beta) )

Хотя одно до сих пор не ясно. Метод совершенно полезен, но только если я вычисляю углы после одного поворота. Поскольку есть больше вращений, связанных друг с другом, результаты ложны. Тем не менее, я думаю, это все еще решаемо, если рассматривать следующим образом: допустим, у нас есть два вращения, связанные друг за другом (R1 и R2). q1 показывает углы R1, q2 R2. после разложения одиночных матриц. Общий угол поворота матрицы R=R1*R2можно легко вычислить, просуммировав ранги до: q=q1+q2

Нет ли способа, как вычислить углы полного поворота, не суммируя парциальные углы, а разложив матрицу R=R1*R2?

ОБНОВИТЬ:

Рассмотрим следующий базовый пример. Вращения связаны друг с другом:

a1 = 10*pi/180
b1 = 20*pi/180
g1 = 40*pi/180
R1 = Rx_a1*Ry_b1_Rz_g1

a2 = 20*pi/180
b2 = 30*pi/180
g2 = 30*pi/180
R2 = Rx_a2*Ry_b2*Rz_g2

Разложение отдельных матриц R1 и R2 дает прямые углы. Проблема возникает, когда я связываю повороты друг за другом и пытаюсь определить углы последнего кадра в инерциальной системе отсчета. Теоретически это можно было бы сделать, разложив произведение всех вращательных матриц цепочки преобразований.

R = R1*R2

Разложение этой матрицы дает следующий ложный результат, показанный в градусах:

a = 0.5645
b = 54.8024
g = 61.4240

Марси

person Marton    schedule 25.08.2016
comment
Да, есть правильный способ рассчитать окончательный или общий набор вращений. Я отредактирую свой ответ, чтобы включить эту информацию - person willpower2727; 25.08.2016
comment
В будущем, когда у вас будет более 20 очков репутации на SO, вы сможете использовать службу чата вместо того, чтобы отвечать другим ответом. просто к вашему сведению - person willpower2727; 25.08.2016
comment
Также будьте очень осторожны с порядком, в котором вы умножаете матрицы вращения, RxRyRz не совпадает с RzRyRx, и правильный порядок зависит от вашего приложения. - person willpower2727; 25.08.2016
comment
Согласно литературным данным, которые я читал, повороты RzRyRx более распространены, однако в этом случае я должен использовать повороты RxRyRz. - person Marton; 27.08.2016