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()
方法來進行一些方向值向其他座標系的轉換。