關於Android 傳感器座標與讀數的進一步討論

 之前一些相關的討論見:

   Android Sensors (3) 傳感器座標系統

   Android Sensors (5) 運動傳感器 Motion Sensors 

   Android Sensors (6) 位置傳感器 Position Sensors 

 

傳感器分類

  總體來說,傳感器分爲運動傳感器和位置傳感器兩種。(此處忽略了一些溫度、光照等環境傳感器)。

  運動傳感器用來監測設備的運動,比如傾斜、震動和搖擺。運動傳感器包括:加速度計、陀螺儀、重力感應器、線性加速度計、旋轉向量傳感器。

  位置傳感器用來監測設備的位置,即相對於世界座標系的位置。包括地磁場傳感器、接近傳感器和方向傳感器。

  (方向傳感器是基於軟件的,根據加速度計和地磁場傳感器導出)。

  可以看出,手機的上述傳感器讀數,需要涉及到兩個座標系,一個是相對於手機自身,一個是相對於世界位置。

  上面很多傳感器是測量手機自身姿態的,那麼它們讀出的數是相對於手機座標系的;

  另一些傳感器和方法,目的是測量手機在世界座標系中的位置,那麼它們的讀數就是相對於世界座標系的。

 

手機的自然座標系

  當一個設備被放在其默認的方向上時,X軸是水平指向右的,Y軸是垂直向上的,Z軸是指向屏幕正面之外的,即屏幕背面是Z的負值。

  

 

  當設備運動或者旋轉的時候,這些座標軸是不會改變的,即它們是跟隨手機的。

  即是說,手機座標系是跟隨設備的自然方向的(但是請記住自然方向不一定是豎直,比如平板它的自然方向就很有可能是橫向)。

  使用這個座標系的傳感器:

  即是說它們的度數顯示了在手機的這三個軸上的數字大小。 

 

屏幕旋轉

  常常要考慮屏幕的旋轉,即屏幕畫面相對於自然方向的旋轉。

  於是就需要使用 getRotation()方法來獲取屏幕的旋轉值。

  這個方法是Display類中的,跟傳感器不相關。

  這個方法的返回值只對應0,90,180,270四種旋轉情況,它說明屏幕顯示區域的旋轉情況。

 

世界座標系

  有一些傳感器和方法使用相對於世界的座標系,因爲它們返回的數據反映設備相對於地球及真實環境的位置信息。

  請見getOrientation() 方法,getRotationMatrix() 方法,Orientation Sensor, 和 Rotation Vector Sensor。下面各自介紹。

 

getRotationMatrix()

  getRotationMatrix()方法說明中,定義的世界座標系如下:

    

  X軸平行於地面,指向東方。

  Y軸平行於地面,指向北極方向。

  Z軸垂直於地面,指向天空。

 

getOrientation()

  getOrientation() 方法中所用的座標系與上面的不同:

    

  X軸平行於地面,指向西方;

  Y軸平行於地面,指向地磁場北極。

  Z軸垂直於地面,指向地心。

  getOrientation方法的返回值表示:

  values[0]: azimuth, rotation around the Z axis.

  values[1]: pitch, rotation around the X axis.

  values[2]: roll, rotation around the Y axis.

  並且這三個角度值都是以弧度做單位,逆時針方向爲正。

 

方向傳感器的返回值說明

 

  方向傳感器是利用加速度計和地磁場傳感器得到自己的數據。

  方向傳感器比較特殊,因爲它的數值是相對於絕對方向的。它得到的是手機設備的絕對姿態值。

  一個方向傳感器得到的三維數據如下:

  (參見http://developer.android.com/guide/topics/sensors/sensors_position.html#sensors-pos-orient

 

  方向傳感器返回的都是角度值,以度數爲單位。

  注意下面說的x、y、z軸均是手機自身的座標軸。

  第一個角度:Azimuth (degrees of rotation around the z axis).

  表示手機自身的y軸與地磁場北極方向的角度,即手機頂部朝向與正北方向的角度。

  (This is the angle between magnetic north and the device's y axis. )

  當手機繞着自身的z軸旋轉時,該角度值將發生改變。

  例如該角度值爲0時,表示手機頂部指向正北;該角度爲90度時,代表手機頂部指向正東;該角度爲180度時,代表手機頂部指向正南;該角度爲270度時,代表手機頂部指向正西。

 

  第二個角度:Pitch (degrees of rotation around the x axis).

  表示手機頂部或尾部翹起的角度。

  當手機繞着自身的x軸旋轉,該角度會發生變化,值的範圍是-180到180度。

  當z軸正向朝着y軸正向旋轉時,該角度是正值;當z軸正向朝着y軸負向旋轉時,該角度是負值。

 

  假設將手機屏幕朝上水平放在桌子上,如果桌子是完全水平的,該角度應該是0。

  假如從手機頂部擡起,直到將手機沿x軸旋轉180度(屏幕向下水平放在桌面上),這個過程中,該角度值會從0變化到-180。

  如果從手機底部開始擡起,直到將手機沿x軸旋轉180度(屏幕向下水平放在桌面上),該角度的值會從0變化到180。

 

  第三個角度:Roll (degrees of rotation around the y axis).

  表示手機左側或右側翹起的角度。

  當手機繞着自身x軸旋轉時,該角度值將會發生變化,取值範圍是-90到90度。

  當z軸正向朝着x軸正向旋轉時,該角度是負值;

  當z軸正向朝着x軸負向旋轉時,該角度是正值。

 

  (這裏跟官方文檔的說法有點不太一致,即第三個角度的正負號正好相反,我不知道是文檔寫錯了,還是它用了別的什麼座標系)。

  因爲通過真機測試,結果如下:

  將手機屏幕朝上水平放在桌子上,如果桌子是完全水平的,該角度應該是0。

  假如將手機左側逐漸擡起,直到將手機沿Y軸旋轉90度(手機與桌面垂直),在這個旋轉過程中,該角度會從0變化到-90。

  如果從手機的右側開始擡起,直到將手機沿Y軸旋轉90度(手機與桌面垂直),該角度的值會從0變化到90度。

 

 

 

其他說明:

  由於需要計算,所以方向傳感器的準確度和精度都會受到影響。

  官方文檔上說,只有當第三個roll的角度值爲0的時候得到的值比較可靠。

  specifically, this sensor is only reliable when the roll component is 0。

  所以從Android 2.2 (API level 8)開始,不建議使用方向傳感器。

  建議使用 getRotationMatrix()getOrientation() 結合來計算方向值。

  也可以利用 remapCoordinateSystem()方法來進行一些方向值向其他座標系的轉換。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章