2

Je suis suivi de 3 points (3D, x y z) sur un corps rigide, que j'utilise pour définir un système de coordonnées local. J'utilise l'orientation de ce système de coordonnées local (dans le référentiel global) pour définir l'orientation de la vue dans un programme VR. Pour ce faire, et éviter les verrous de cardan avec des angles d'Euler, j'essaye d'utiliser un quaternion pour définir l'orientation de la vue.Matrice de rotation à équivalence quaternaire

Je crée une matrice de rotation à partir des 3 points, puis j'utilise cette méthode décrite au Wikipedia pour extraire le quaternion supposé équivalent. Je définis alors simplement l'orientation de la vue comme étant le quaternion calculé. Cependant, ce que j'observe, c'est qu'il n'y a principalement qu'un seul degré de liberté (tangage) quand je devrais aussi être capable de voir simultanément les changements dans le lacet et le roulis. J'ai extrait les angles d'Euler de la matrice de rotation, et cela fonctionne bien sauf au cardan-lock. Donc je suis certain que la matrice de rotation est utilisable, bien que ce soit incorrect dans mon cas.

Ma question est la suivante: pourquoi le quaternion supposé équivalent ne semble-t-il que changer le degré de liberté de «hauteur»?

Je suis conscient qu'un quaternion est une rotation autour de 1 axe, mais je pensais que si elle était dérivée de la matrice de rotation, le résultat final serait le même que pour régler les angles d'Euler?

Voici mon code en python:

import viz 
import numpy as np 

vec1 = np.array([-0.96803,-0.25022,0.01751],dtype=float) 
vec3 = np.array([-0.024815,0.96553,0.07863],dtype=float) 
vec4 = np.array([-0.03655,0.07178,-0.99675],dtype=float) 
#normalize to unit length 
vec1 = vec1/np.linalg.norm(vec1) 
vec3 = vec3/np.linalg.norm(vec3) 
vec4 = vec4/np.linalg.norm(vec4) 

M1 = np.zeros((3,3),dtype=float) #rotation matrix 

#rotation matrix setup 
M1[:,0] = vec1 
M1[:,1] = vec3 
M1[:,2] = vec4 

#get the real part of the quaternion first 
r = np.math.sqrt(float(1)+M1[0,0]+M1[1,1]+M1[2,2])*0.5 
i = (M1[2,1]-M1[1,2])/(4*r) 
j = (M1[0,2]-M1[2,0])/(4*r) 
k = (M1[1,0]-M1[0,1])/(4*r) 

viz.MainView.setQuat(i,j,k,r) 

Toute aide ou des idées serait génial!

+0

Les maths me semblent OK. Je suis un peu confus. Comparez-vous la rotation de votre matrice avec votre rotation du quaternion? Si les résultats sont les mêmes, il semblerait que les degrés de liberté limités seraient un problème avec votre choix de matrice. –

+0

@ bob.sacamento Je cherche simplement à exprimer la matrice de rotation comme un quaternion. Je ne suis pas sûr à 100% que c'est la bonne façon de l'exprimer. Dans le code que je n'ai pas affiché, j'ai pu déterminer les angles d'Euler à partir de la matrice, donc je pense que je l'ai construit correctement. Y a-t-il d'autres façons de construire la matrice qui affecterait les choses? – willpower2727

+0

Ce n'est pas une matrice de rotation. Problème mineur: Les lignes ne sont pas orthogonales entre elles (mais elles sont proches). Gros problème: Le déterminant est -1 (ou proche de celui-ci). Comment avez-vous formé cette matrice? –

Répondre

2

Le problème principal ici est que vous avez appliqué un algorithme qui ne concerne que les matrices de rotation 3x3 appropriées à une matrice qui n'est pas orthogonale et qui est très proche d'une matrice de rotation incorrecte. C'est ce dernier qui est la source principale de vos problèmes.

Votre matrice M1 est

array([[-0.9994477 , -0.02887993, 0.0164005 ], 
     [-0.02958325, 0.99862763, -0.04323132], 
     [ 0.01513678, 0.0436899 , 0.99893047]]) 

Vous obtiendrez un non-sens lorsque vous appliquez correctement cet algorithme pour extraire un quaternion à partir d'une matrice de rotation propre à cette matrice non conforme. En particulier, parce que M[2,1] est approximativement égale à -M[1,2], M[0,2] est approximativement égale à M[2,0], et M[1,0] est approximativement égale à M[0,1], vous obtiendrez ce qui semble être le roulement presque pur. Remarque: Il en va de même pour les algorithmes d'extraction des angles d'Euler à partir d'une matrice. Ces algorithmes supposent tous que la matrice est une matrice de rotation appropriée. Lorsque vous les appliquez incorrectement à une matrice de rotation incorrecte, vous aurez un non-sens.

+0

Parfait! Oui, je viens de découvrir que je créais un système de coordonnées à gauche, obtenant la matrice de rotation incorrecte. J'ai changé pour une méthode droitière et maintenant je peux voir tous les 3 dof changer. Merci! Que Dieu bénisse les scientifiques des fusées! – willpower2727

+0

@ willpower2727 - En aparté, jusqu'à il y a sept mois, j'étais l'un de ces scientifiques de fusée bénis. Il y a plusieurs années, développé un algorithme robuste et générique pour extraire les angles d'Euler à partir d'une matrice de rotation (correcte). Il s'est avéré que je n'étais pas le premier; Ken Shoemake avait développé (et publié) un algorithme similaire des années auparavant. Mon code C++ a été converti en Java; vous pouvez voir ce code Java à http://uahuntsville-siso-smackdown.googlecode.com/svn-history/r3/trunk/ez/siso/smackdown/utilities/EulerAngles.java pour quelques mois de plus (jusqu'à ce que google arrête code google). –