3

我正在尋找應用的偏移一組Euler旋轉的正確途徑。我想有一個變換,其中給定的一組特定的歐拉角(X1,Y1,Z1),如果我改變他們,我會得到的(0,0,0)歐拉序列。所有其他歐拉序列(xi,yi,zi)轉化後的行爲如(x1,y1,z1)爲(0,0,0)。偏移歐拉角使用旋轉矩陣

背景:

我使用Oculus公司DK2 HMD顯示虛擬環境(面頰5,Python的2.7.5),同時使用威康運動捕捉系統(2的Nexus)來更新的位置和取向。我能得到HMD的歐拉角(從標記集羣,而不是DK2陀螺儀)從威康系統,但面對我的期望(0,0,0)方向時,HMD具有非零的輪轉順序。

問題:

我有一個堅硬的時間思考什麼變換(?旋轉矩陣),我能找到的,可以採取像序列(-105,110,-30),並使其(0, 0,0)而不是無用的零矩陣。如果旋轉矩陣全爲零,則任何序列都將被轉換爲(0,0,0))。式I心目中的(請忽略語法):

[0,0,0] =(3×3)R *(3×)[ - 105,110,-30]什麼爲R? R不能是3x3零矩陣。

嘗試:

我愚蠢地試圖簡單地減去offest歐拉角,像這樣:

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 

唉,

enter image description here

我敢肯定,這是可能的,事實上我過去做過類似的事情,我不得不在標定位置將標記簇轉換成剛體框架。但在這種情況下我無法繞過這個簡單的解決方案(零矩陣)。如果偶然的話,任何人都可以用四元數解釋這一點,我也可以使用這些。

+0

我可能會錯過一些很基本的這裏,但是讓我們假設你有'[-105,110, -30]'並且想用矩陣'R'把它變成'[0,0,0]'。那麼你可不只是使用例如'R'的每一行中的[0,1,110/30]'!?如果是這樣,那麼顯然這個問題顯然有許多解決方案;如果不是,我真的沒有得到你的問題。 – Cleb

+0

好的,你能否更詳細地解釋你實際上在尋找什麼?我只給了一個任意的例子;你也可以選擇'[-1,1,43/6]',這樣''(-105 + 45,110,-30)'顯然不會返回'(0,0,0)'。所以如果你能夠更詳細地解釋'R'的理想屬性,那將會很棒!你也可以嘗試[這裏](http://math.stackexchange。com/questions),如果你能夠詳細定義'R'的屬性。 – Cleb

+0

@Cleb對不起,我認爲你所描述的是通過將矢量乘以旋轉矩陣來轉換矢量。有許多矩陣R可以將矢量變爲零。但是,對於歐拉角,您不能簡單地將歐拉角乘以旋轉矩陣。這沒有意義。相反,您可以乘以另一個旋轉矩陣,並使用逆運動學來獲得新的歐拉角。我希望我有道理。謝謝你的回覆 – willpower2727

回答

1

做到這一點的合適的方法是確定在期望的點處的HMD取向和所需的視圖方向之間的轉換。我把這個時間稱爲零,即使時間與它無關,實際上這是「家庭」的方向。一旦轉換是已知的,它可以被用來確定使用從HMD上的數據的視圖方向,由於座標HMD的幀和視圖可以被認爲是安裝在相同的剛體的(意味着它們的相對轉化不會改變隨着時間的推移)。

這裏是數學: enter image description here

這是我如何編碼它(它的工作原理!):

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)