3

Je cherche la manière correcte d'appliquer un décalage à un ensemble de rotations d'Euler. Je voudrais avoir une transformation avec un ensemble spécifique d'angles d'Euler (x1, y1, z1), si je les transforme, j'obtiendrais une séquence d'Euler de (0,0,0). Toutes les autres séquences d'Euler (xi, yi, zi) transformées agiraient alors comme si (x1, y1, z1) étaient (0,0,0).Décalage des angles d'Euler à l'aide de la matrice de rotation

Contexte:

J'utilise Oculus DK2 HMD pour afficher un environnement virtuel (Vizard 5, Python 2.7.5) tout en utilisant un système de capture de mouvement Vicon (Nexus 2) pour mettre à jour la position et l'orientation. Je peux obtenir les angles d'Euler du HMD (à partir d'un groupe de marqueurs, pas le gyroscope DK2) du système Vicon, mais en faisant face à mon orientation désirée (0,0,0) le HMD a une séquence de rotation non nulle.

Problème:

Je vais avoir du mal à penser à ce que la transformation (? Matrice de rotation) je pouvais trouver qui pourrait prendre une séquence comme (-105, 110, -30) et de le rendre (0, 0,0) sans être une matrice inutile de zéros. Si la matrice de rotation était toute zéros, n'importe quelle séquence serait transformée en (0,0,0)). La formule que j'ai en tête est (veuillez ignorer la syntaxe):

[0,0,0] = (3x3) R * (3x1) [- 105,110, -30] qu'est-ce que R? R ne peut pas être une matrice zéro 3x3.

Tentative:

Je bêtement essayé de soustraire simplement les angles euler de offest comme ceci:

import viz 
viz.go() 
navigationNode = viz.addGroup() #create node 
viewLink = viz.link(navigationNode, viz.MainView) #link it to the main view 

#I am not showing how I get variables HMDX HMDY HMDZ but it's not important for this question 
navigationNode.setEuler(HMDRZ-90,HMDRX+180,-1*(HMDRY)+30) #update the view orientation 

Hélas,

enter image description here

Je suis sûr que cela est possible, en En fait, j'ai fait des choses semblables dans le passé où je devais transformer des grappes de marqueurs dans le cadre d'un corps rigide à une position d'étalonnage. Mais je ne peux tout simplement pas contourner la solution triviale dans ce cas (matrice des zéros). Si par hasard quelqu'un pouvait l'expliquer en utilisant des quaternions, je peux aussi les utiliser.

+0

me manque probablement quelque chose de très fondamental ici, mais disons que vous avez '[-105110, -30] 'et que nous voulons transformer en [0,0,0]' en utilisant une matrice 'R'. Pourriez-vous alors ne pas simplement utiliser par ex. '[0, 1, 110/30]' dans chaque rangée de 'R' !? Si oui, alors il y a apparemment beaucoup de solutions à ce problème; sinon je ne comprends pas vraiment ta question. – Cleb

+0

Ok, pourriez-vous alors expliquer plus en détail ce que vous recherchez? Je n'ai donné qu'un exemple arbitraire; vous pourriez également choisir '[-1, 1, 43/6]' qui ne retournerait alors apparemment pas '(0, 0, 0)' pour '(-105 + 45,110, -30)'. Donc, si vous pouviez expliquer les propriétés souhaitées de 'R' plus en détail, ce serait génial! Vous pouvez également essayer [ici] (http: //math.stackexchange.com/questions) si vous êtes capable de définir les propriétés de 'R' d'une manière détaillée. – Cleb

+0

@Cleb Désolé pour la confusion, je pense que ce que vous décrivez est la transformation d'un vecteur en le multipliant avec la matrice de rotation. Il y a beaucoup de matrices R qui peuvent transformer un vecteur en zéros. Cependant, avec les angles d'Euler, vous ne pouvez pas simplement multiplier les angles d'Euler par la matrice de rotation. Cela n'aurait aucun sens. Au lieu de cela, vous multipliez avec une autre matrice de rotation et utilisez une cinématique inverse pour obtenir les nouveaux angles d'Euler. J'espère que j'ai un sens. merci pour votre réponse – willpower2727

Répondre

1

La meilleure façon de procéder consiste à déterminer la transformation entre l'orientation hmd et l'orientation de la vue souhaitée à un point souhaité. J'appelle cette fois zéro, même si le temps y est pour quelque chose, vraiment c'est l'orientation "à la maison". Une fois la transformation connue, elle peut être utilisée pour déterminer l'orientation de la vue en utilisant les données du hmd, car les trames de coordonnées du hmd et de la vue peuvent être considérées comme montées sur le même corps rigide (leur transformation relative ne changera pas) avec le temps).

Voici le calcul: enter image description here

Voici comment je codé (il fonctionne!):

import numpy as np 
import math 

#setup the desired calibration transformation (hmd orientation that will result in looking straight ahead 

#Euler angles for the hmd at desired "zero" orientation 
a0 = -177.9*math.pi/180 
b0 = 31.2*math.pi/180 
g0 = 90.4*math.pi/180 

#make the matrices 
Ra0 = np.matrix([[1,0,0],[0, float(math.cos(a0)),float(-1*math.sin(a0))],[0,float(math.sin(a0)),float(math.cos(a0))]],dtype=np.float) 
Rb0 = np.matrix([[math.cos(b0),0,math.sin(b0)],[0,1,0],[-1*math.sin(b0),0,math.cos(b0)]],dtype=np.float) 
Rg0 = np.matrix([[math.cos(g0),-1*math.sin(g0),0],[math.sin(g0),math.cos(g0),0],[0,0,1]],dtype=np.float) 

#the hmd rotation matrix in the "zero" orientation 
global RhmdU0 
RhmdU0 = Ra0*Rb0*Rg0 
#the view orientation when the hmd is in the "zero" orientation (basically a zero degree turn about the Z axis) 
global RdU0 
RdU0 = np.matrix([[1,0,0],[0,1,0],[0,0,1]],dtype=np.float) 

#this can be called in a loop, inputs are Euler angles of the hmd 
def InverseK(at,bt,gt): 
    global RdU0 
    global RhmdU0 

    #given 3 Euler sequence of the hmd in universal space, determine the viewpoint 
    Rat = np.matrix([[1,0,0],[0, float(math.cos(at)), float(-1*math.sin(at))],[0,float(math.sin(at)),float(math.cos(at))]],dtype=np.float) 
    Rbt = np.matrix([[math.cos(bt),0,math.sin(bt)],[0,1,0],[-1*math.sin(bt),0,math.cos(bt)]],dtype=np.float) 
    Rgt = np.matrix([[math.cos(gt),-1*math.sin(gt),0],[math.sin(gt),math.cos(gt),0],[0,0,1]],dtype=np.float) 

    RhmdUt = Rat*Rbt*Rgt 

    RdUt = RhmdUt*RhmdU0.transpose()*RdU0 

    #do inverse K to get euler sequence out: 
    beta = math.atan2(RdUt[0,2],math.sqrt(RdUt[1,2]**2+RdUt[2,2]**2)) 
    alpha = math.atan2(-1*RdUt[1,2]/math.cos(beta),RdUt[2,2]/math.cos(beta)) 
    gamma = math.atan2(-1*RdUt[0,1]/math.cos(beta),RdUt[0,0]/math.cos(beta)) 

    return(alpha,beta,gamma)