Войти
ПрограммированиеФорумФизика

Как получить углы ейлера , в собственом базисе кватерниона ?

Страницы: 1 2 3 Следующая »
#0
20:42, 10 фев. 2019

И так у нас есть твердое тело "квадрокоптер" , эго ориентациия в пространстве задаеться его собственым кватернионом . То есть квадрокоптер он как-то  , как угодно может быть повернутый в пространстве . Эти повороты описует эго собственый кватернион ориентации  .
А теперь вопрос , как получить углы Эйлера из кватерниона , например можно так :
Изображение
Но проблема в том что эти углы в базисе (XYZ) , а мне нужно сделать виртуальный гироскоп над телом кватерниона  , а значит углы ейлера должны быть в собственом базисе кватерниона ?
( Q *  XYZ )
Другими словами мне нужны углы Ейлера вокруг осей (XYZ) поворнутых на тот самый кватернион с которого мы берем даные . Как это сделать ?
P.S: Если кто не понял , мне просто нужно сделать виртуальный гироскоп , на основи даных кватерниона .!


#1
22:03, 10 фев. 2019

См. http://padaread.com/?book=28008&pg=44 , http://padaread.com/?book=28008&pg=47 (активная и пассивная точка зрения).

#2
1:11, 11 фев. 2019

FordPerfect
А как разложить кватернион на отдельные матрицы поворота M_Yaw , M_Pitch , M_Rool .?
В принципе  если я знал как получить эти матрицы , то я 100500 вариантов мог придумать как это сделать .
С кватернионом манипулировать я не могу , им управляет физика твердого тела !

#3
21:28, 12 фев. 2019

Это вообще возможно , получить углы поворотов Yaw Pitch Rool в самой системе координат кватерниона ...? Как сделать грёбаный виртуальный гироскоп ...?

#4
(Правка: 6:54) 6:53, 13 фев. 2019

Вот на одном форуме https://forum.unity.com/threads/roll-pitch-and-yaw-from-quaternion.63498/ человек задавал такой же вопрос , и он вроде как нашел ответ .
Вот код

  float getPan(Transform t){
        return t.localEulerAngles.z;
    }
   
    float getRoll(Transform originalTransform){
        GameObject tempGO = new GameObject();
        Transform t = tempGO.transform;
        t.localRotation = originalTransform.localRotation;
       
        t.Rotate(0,0, t.localEulerAngles.z * -1);
       
        GameObject.Destroy(tempGO);
        return t.localEulerAngles.x;
    }
   
    float getTilt(Transform originalTransform){
        GameObject tempGO = new GameObject();
        Transform t = tempGO.transform;
        t.localRotation = originalTransform.localRotation;
       
        t.Rotate(0,0, t.localEulerAngles.z * -1);
        t.Rotate(t.localEulerAngles.x * -1,0,0);
       
        GameObject.Destroy(tempGO);
        return t.localEulerAngles.y;
    }

Только у меня это не работает ! Вопрос правильный ли этот код ....?

#5
11:37, 13 фев. 2019

werasaimon
> Только у меня это не работает ! Вопрос правильный ли этот код ....?
а ты понимаешь что тут на юнити происходит? ты насколько помню на крестах сидишь

#6
13:17, 13 фев. 2019

Mira
> а ты понимаешь что тут на юнити происходит? ты насколько помню на крестах
> сидишь
Та я шарю в кватернионах , я все переписал на кристы 100% правильно !
Там же все очевидно !!

#7
(Правка: 16:00) 15:46, 13 фев. 2019

werasaimon
> Та я шарю в кватернионах
Эм... localEulerAngles и Rotate это все углы Эйлера. localRotation используется только для копирования поворота.

getPan - это прямое преобразование кватерниона в углы Эйлера где берется Z.

getRoll - здесь исходный поворот разворачивается обратно по значению от getPan и опять берется угол Эйлера для X.

getTilt - тоже самое что и getRoll с дополнительным шагом обратного поворота от getRoll для угла Y.

Вычисляется ли это все на кватернионе, на матрице или на том же Эйлере неизвестно.

Аналог для кватерниона

Vector3 getRollTiltPan(Transform originalTransform)
{
  Vector3 rez;
  Quaternion rotation = originalTransform.localRotation
  rez.z = rotation.eulerAngles.z;
  rotation = rotation * Quaternion.Euler(0, 0, -rez.z);
  rez.x = rotation.eulerAngles.x;
  rotation = rotation * Quaternion.Euler(-rez.x, 0, 0);
  rez.y = rotation.eulerAngles.y;
  return rez;
}

#8
18:32, 13 фев. 2019

foxes
Да правильно ! Только это не работает , я сделал точно также !

#9
(Правка: 2:27) 1:32, 14 фев. 2019

werasaimon
А что именно не работает? По условиям задачи у тебя совсем другое требуется. Нужно просто взять обратный поворот или обратную матрицу вращения и от этого получить Эйлера - вот это решение. Про это тебе еще в начале FordPerfect написал. Но явно не то что ты привел как вариант решения - это просто альтернативная последовательность как Y X Z вместо X Y Z Эйлера.

Кстати, я тут ни когда в вики не заглядывал, а тут решил посмотреть что про Эйлера пишут. Либо я из параллельной вселенной вывалился, либо что то случилось, но я всегда думал что это последовательное вращение по осям X Y Z, а оказалось что по осям Z X Z - о как!
Это что за математика такая?

Может как раз в этом проблема, что математико-механический Эйлер не соответствует матрично-движковому Эйлеру.

#10
(Правка: 4:32) 4:20, 14 фев. 2019

foxes
> Кстати, я тут ни когда в вики не заглядывал, а тут решил посмотреть что про
> Эйлера пишут. Либо я из параллельной вселенной вывалился, либо что то
> случилось, но я всегда думал что это последовательное вращение по осям X Y Z, а
> оказалось что по осям Z X Z - о как!
> Это что за математика такая?
Там может быть 12-разных последовательностей вращений (zyx, zyz, zxy, zxz, yxz, yxy, yzx, yzy, xyz, xyx, xzy,xzx),

foxes
> А что именно не работает? По условиям задачи у тебя совсем другое требуется.
> Нужно просто взять обратный поворот или обратную матрицу вращения и от этого
> получить Эйлера - вот это решение. Про это тебе еще в начале FordPerfect
> написал. Но явно не то что ты привел как вариант решения - это просто
> альтернативная последовательность как Y X Z вместо X Y Z Эйлера.

Он все правильно написал! например если мы вращаем M = XYZ то нам нужно вращать в обратной последовательности и каждый раз на новый угол образованный предыдущей матрицей 
M2 = M * Euler(0,0,-M.EulerAngle.z)
float ResultAnglePitch = M.EulerAngle.x
и теперь уже с этой новой матрицы берем
M3 = M2 * Euler(0,0,-M2.EulerAngle.z)
M3 = M3 * Euler(-M3.EulerAngle.x,0,0)
float ResultAnglePitch = M3.EulerAngle.y
.и,т,д .....! И это должно работать , но кого то  черта не работает ,,!?

Вот псевдокод , тут все основные функции ,,,, !

+ Показать

P.S: Короче я вижу один путь запустить Юнити , и сделать как автора , и если это работает перенести в С++ .
Только вопрос в том , можно ли смотреть весь код в Юнити ?

КАКОГО ЧЕРТА ОНО НЕ РАБОТАЕТ WTF АААА....??

#11
4:37, 14 фев. 2019

foxes
> Кстати, я тут ни когда в вики не заглядывал, а тут решил посмотреть что про Эйлера пишут. Либо я из параллельной вселенной вывалился, либо что то случилось, но я всегда думал что это последовательное вращение по осям X Y Z, а оказалось что по осям Z X Z - о как!
http://padaread.com/?book=28008&pg=25

#12
(Правка: 14:32) 14:09, 14 фев. 2019

werasaimon
> Он все правильно написал!
Он писал для аналога
werasaimon
> Но проблема в том что эти углы в базисе (XYZ)
а не для
werasaimon
> а мне нужно сделать виртуальный гироскоп над телом кватерниона

werasaimon
> например если мы вращаем M = XYZ
Если мы берем XYZ то обратно вращать ни чего не надо, EulerAngle уже выдают именно эту последовательность. Но для последовательности YXZ значение Y не соответствует, поэтому так как Z была последней то и обратное вращение делается первым на Z для того чтобы остались только XY. но поскольку он берет YX то делается обратное вращение на X.

werasaimon
> M2 = M * Euler(0,0,-M.EulerAngle.z)
> float ResultAnglePitch = M.EulerAngle.x
> и теперь уже с этой новой матрицы берем
> M3 = M2 * Euler(0,0,-M2.EulerAngle.z)
> M3 = M3 * Euler(-M3.EulerAngle.x,0,0)
> float ResultAnglePitch = M3.EulerAngle.y
Вот тут у тебя не так.
M3 = M * Euler(0,0,-M.EulerAngle.z)
M3 = M3 * Euler(-M3.EulerAngle.x,0,0)

хотя это не принципиально потому что M2.EulerAngle.z после "M2 = M * Euler(0,0,-M.EulerAngle.z)" должна равняться нулю.

#13
15:55, 14 фев. 2019

foxes
> хотя это не принципиально потому что M2.EulerAngle.z после "M2 = M *
> Euler(0,0,-M.EulerAngle.z)" должна равняться нулю.
Не нулю а единичной матрице , только когота черта не работает !

#14
(Правка: 18:55) 18:28, 14 фев. 2019

werasaimon
> Не нулю а единичной матрице , только когота черта не работает !
M2.EulerAngle.z - это конкретное значение угла, поэтому все таки нулю.

Надо попробовать вывести значение всех углов Эйлера на каждом шаге обратного поворота. Мне кажется что идея умножения матриц X*Y*(-X) изначально не верна и не дает вращение вокруг единственной оси.

Я бы начал плясать от имеющейся реализации IQuaternion::GetEulerAngles. Там по идеи надо "x и y" местами поменять чтобы получить требуемый результат. А чтобы проверить правильность работы соответственно поменять матрицы в IQuaternion::FromEulerAngles и заодно проверить тот алгоритм который работает с обратными поворотами. Потому как алгоритм которым ты проверяешь правильность работы остается не раскрытым.

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

Страницы: 1 2 3 Следующая »
ПрограммированиеФорумФизика