Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android API Guides---Motion Sensors

Android API Guides---Motion Sensors

編輯:關於Android編程

Motion Sensors

Android平台提供了多種感應器,讓你監控設備的運動。這些傳感器的兩個總是基於硬件的(加速度計和陀螺儀),並且可以要麼基於硬件或基於軟件的這三個傳感器(重力,線性加速度和旋轉矢量傳感器)。例如,在某些設備上的基於軟件的傳感器從加速度計和磁力計獲得它們的數據,但在其他裝置也可以使用陀螺儀來導出他們的數據。大多數Android設備有一個加速度計,現在許多人包括陀螺儀。基於軟件的傳感器的可用性是更加可變的,因為它們通常依賴於一個或一個以上硬件傳感器來導出他們的數據。


運動傳感器用於監視設備的運動,比如傾斜,搖動,旋轉或搖擺有用。運動通常是直接用戶輸入的反射(例如,用戶在游戲或控制在游戲中球的用戶操縱汽車),但它也可以是在該裝置所坐的物理環境的反射(例如,與你動,而你開你的車)。在第一種情況下,您正在監視相對於參考設備的框架或引用您的應用程序框架的議案;在第二種情況下,你正在監測相對於參考世界幀運動。本身運動傳感器通常不用於監控設備的位置,但它們可以與其他傳感器,例如地磁場傳感器中使用,以確定設備的相對於參考世界幀位置(更多信息參見位置傳感器)。


所有的運動傳感器返回傳感器值的多維數組每個SensorEvent。例如,一個單一的傳感器事件期間加速度返回加速度力數據為三個坐標軸,和陀螺儀返回旋轉數據的速率為三個坐標軸。這些數據值與其他SensorEvent參數一起float數組(值)返回。表1總結了可用的Andr??oid平台上的運動傳感器。


所支持的Andr??oid平台上表1.運動傳感器。

傳感器傳感器事件數據說明測量單位
TYPE_ACCELEROMETER SensorEvent.values?? [0]沿x軸(包括重力)加速力。米/秒2
沿y軸(包括重力)SensorEvent.values?? [1]加速力。
沿z軸(包括重力)SensorEvent.values?? [2]加速力。
TYPE_GRAVITY SensorEvent.values?? [0]沿x軸的重力的力。米/秒2
SensorEvent.values?? [1]沿y軸的重力的力。
SensorEvent.values?? [2]沿著z軸的重力的力。
TYPE_GYROSCOPE SensorEvent.values?? [0]速率圍繞x軸的旋轉。弧度/秒
SensorEvent.values?? [1]速率繞y軸的旋轉。
SensorEvent.values?? [2]速率圍繞z軸的旋轉。
型陀螺儀無標定傳感器Event.values?? [0]速率旋轉(無漂移補償)的繞x軸。弧度/秒
SensorEvent.values?? [1]速率繞y軸的旋轉(無漂移補償)的。
SensorEvent.values?? [2]速率圍繞z軸的旋轉(無漂移補償)的。
SensorEvent.values?? [3]圍繞x軸的估計漂移。
SensorEvent.values?? [4]繞y軸的估計漂移。
SensorEvent.values?? [5]圍繞z軸的估計漂移。
TYPE_LINEAR_ACCELERATION SensorEvent.values?? [0]沿x軸(不包括重力)加速力。米/秒2
SensorEvent.values?? [1]加速沿y軸(不包括重力)的力。
沿z軸(不包括重力)SensorEvent.values?? [2]加速力。
沿x軸TYPE_ROTATION_VECTOR SensorEvent.values?? [0]旋轉矢量分量(X * SIN(θ/ 2))。無單位
沿y軸(y * SIN(θ/ 2))SensorEvent.values?? [1]旋轉矢量分量。
沿z軸SensorEvent.values?? [2]旋轉矢量成分(Z * SIN(θ/ 2))。
旋轉向量的SensorEvent.values?? [3]標量成分((COS(θ/ 2))。1
TYPE_SIGNIFICANT_MOTION N / A N / A N / A
TYPE_STEP_COUNTER SensorEvent.values?? [0],而傳感器被激活自上次重啟用戶采取步數。腳步
TYPE_STEP_DETECTOR N / A N / A N / A

1標量分量是可選的值。


旋轉矢量傳感器和重力傳感器是用於運動檢測和監測中最常用的傳感器。旋轉矢量傳感器是特別通用,可用於廣泛范圍的運動相關的任務,如檢測的手勢,監測的角度變化,和監測的相對定向的改變。例如,如果你正在開發一個游戲,增強現實應用,二維或三維羅盤,或相機穩定應用的旋轉矢量傳感器是理想的。在大多數情況下,使用這些傳感器比使用加速度計和地磁傳感器或方位傳感器更好的選擇。


Android開源項目的傳感器


Android開源項目(AOSP)提供了三個基於軟件的運動傳感器:重力傳感器,線性加速度傳感器和旋轉矢量傳感器。這些傳感器中的Andr??oid 4.0更新和現在使用的裝置的陀螺儀(除了其他傳感器),以改善穩定性和性能。如果你想嘗試這些傳感器,可以通過使用getVendor()方法和getVersion()方法識別它們(供應商是谷歌公司;版本號為3)。由供應商和版本號識別這些傳感器是必要的,因為Android系統認為這些三個傳感器是次要傳感器。例如,如果一個設備制造商提供了其自身的重力傳感器,則AOSP重力傳感器示出了作為輔助重力傳感器。所有這三個傳感器依靠一個陀螺儀:如果一個裝置不具有一個陀螺儀,這些傳感器沒有顯示出來,並且不能使用。


使用加速度計


加速度傳感器測量施加到該裝置的加速度,包括重力的力。下面的代碼展示了如何獲得默認加速度傳感器的一個實例:

 

private SensorManager mSensorManager;
private Sensor mSensor;
 ...
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
概念上,加速度傳感器確定是通過測量被施加到使用以下關系傳感器本身(FS)的力施加到一個裝置(廣告)的加速度:


AD = - ΣFs/質譜
然而,在重力的作用根據以下關系總是影響所測量的加速度:


AD =-g - ΣF/質譜
因為這個原因,當裝置坐在一個表(而不是加速)時,加速計讀取g的大小=9.81米/秒2。類似地,當設備處於自由下落,並在9.81米/秒2朝向接地因此迅速加快,其加速度計讀出G =0米/ s2的大小。因此,測量設備的實際加速度,在重力的力的貢獻必須來自加速度計的數據被刪除。這可以通過應用高通濾波器來實現。相反,一個低通濾波器可以用來在重力的作用隔離。下面的例子演示了如何做到這一點:

 

 

public void onSensorChanged(SensorEvent event){
 // In this example, alpha is calculated as t / (t + dT),
 // where t is the low-pass filter's time-constant and
 // dT is the event delivery rate.

 final float alpha = 0.8;

 // Isolate the force of gravity with the low-pass filter.
 gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0];
 gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1];
 gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2];

 // Remove the gravity contribution with the high-pass filter.
 linear_acceleration[0] = event.values[0] - gravity[0];
 linear_acceleration[1] = event.values[1] - gravity[1];
 linear_acceleration[2] = event.values[2] - gravity[2];
}
注意:您可以使用許多不同的技術來過濾傳感器數據。上面的代碼示例使用一個簡單的過濾器常數(阿爾法)來創建一個低通濾波器。此濾波器常數從一個時間常數(t)的,它是延遲的粗略表示該濾波器增加了傳感器事件,並且傳感器的事件傳遞率(DT)的。該代碼示例使用的0.8用於演示的alpha值。如果使用這種過濾方法可能需要選擇不同的alpha值。


加速度計使用標准的傳感器坐標系。在實踐中,這意味著,當一個設備是在其自然取向的表平放以下條件適用:


如果按下設備上的左側(所以它移動到右側)中,x加速度值是正的。
如果按下設備上的底部(因此它移動遠離您),在y加速度值是正的。
如果按下該設備朝向天空具有A米/秒2的加速度,則Z加速度值等於A + 9.81,其對應於該裝置的加速度(+ A米/秒2)減去重力( - 9.81米/秒2)。
該固定設備將具有9.81的加速度值,其對應於該裝置的加速度(0米/秒2減去重力的作用,這是-9.81米/秒2)。
一般來說,加速度計,如果要監視設備的運動一個很好用的傳感器。幾乎每一個Android平台的手機和平板電腦有一個加速度計,它使用較少的約10倍的功率比其它運動傳感器。一個缺點是,你可能必須實現低通和高通濾波器來消除引力,降低噪音。


Android SDK中提供了一個示例應用程序,展示了如何使用加速度傳感器(加速度計播放)。


使用重力感應


重力傳感器提供指示的方向和重力的大小的三維矢量。下面的代碼展示了如何獲得默認重力感應的一個實例:

 

 

private SensorManager mSensorManager;
private Sensor mSensor;
...
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
單位是相同的那些由加速度傳感器(米/秒2)中使用,和坐標系是與由加速度傳感器所使用的。


注:當設備處於靜止,重力傳感器的輸出應該是相同的加速度計的。


使用陀螺儀

 

陀螺儀測量圍繞一個設備的x,y和z軸中弧度/秒的速率或旋轉。下面的代碼展示了如何獲得默認陀螺儀的實例:

 

private SensorManager mSensorManager;
private Sensor mSensor;
...
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
傳感器的坐標系中是一樣的用於加速度傳感器中之一。旋轉是在反時針方向陽性;即,從在x一些積極的位置看的觀察者,在定位在原點的裝置y或z軸方向會如果設備出現逆時針方向被旋轉報告正轉。這是正轉的標准的數學定義,是不一樣的是,用於由方位傳感器的定義為輥。


通常情況下,陀螺儀的輸出對時間積分來計算描述角度在時間步長的變化的旋轉。 例如:

 

 

// Create a constant to convert nanoseconds to seconds.
private static final float NS2S = 1.0f / 1000000000.0f;
private final float[] deltaRotationVector = new float[4]();
private float timestamp;

public void onSensorChanged(SensorEvent event) {
 // This timestep's delta rotation to be multiplied by the current rotation
 // after computing it from the gyro sample data.
 if (timestamp != 0) {
  final float dT = (event.timestamp - timestamp) * NS2S;
  // Axis of the rotation sample, not normalized yet.
  float axisX = event.values[0];
  float axisY = event.values[1];
  float axisZ = event.values[2];

  // Calculate the angular speed of the sample
  float omegaMagnitude = sqrt(axisX*axisX + axisY*axisY + axisZ*axisZ);

  // Normalize the rotation vector if it's big enough to get the axis
  // (that is, EPSILON should represent your maximum allowable margin of error)
  if (omegaMagnitude > EPSILON) {
   axisX /= omegaMagnitude;
   axisY /= omegaMagnitude;
   axisZ /= omegaMagnitude;
  }

  // Integrate around this axis with the angular speed by the timestep
  // in order to get a delta rotation from this sample over the timestep
  // We will convert this axis-angle representation of the delta rotation
  // into a quaternion before turning it into the rotation matrix.
  float thetaOverTwo = omegaMagnitude * dT / 2.0f;
  float sinThetaOverTwo = sin(thetaOverTwo);
  float cosThetaOverTwo = cos(thetaOverTwo);
  deltaRotationVector[0] = sinThetaOverTwo * axisX;
  deltaRotationVector[1] = sinThetaOverTwo * axisY;
  deltaRotationVector[2] = sinThetaOverTwo * axisZ;
  deltaRotationVector[3] = cosThetaOverTwo;
 }
 timestamp = event.timestamp;
 float[] deltaRotationMatrix = new float[9];
 SensorManager.getRotationMatrixFromVector(deltaRotationMatrix, deltaRotationVector);
  // User code should concatenate the delta rotation we computed with the current rotation
  // in order to get the updated rotation.
  // rotationCurrent = rotationCurrent * deltaRotationMatrix;
 }
}
標准陀螺儀提供沒有經過任何過濾或更正噪聲和漂移(偏差)的原始數據旋轉。在實踐中,陀螺儀的噪聲和漂移將引入需要被補償的誤差。通常你確定通過監控其它傳感器,如重力傳感器或加速度計的漂移(偏差)和噪音。


使用未校准陀螺儀


未校正陀螺儀是類似於陀螺儀,除了不陀螺漂移補償被施加到旋轉速率。工廠校准和溫度補償仍施加到旋轉的速率。未校准陀螺儀是後處理和melding方向的數據是有用的。在一般情況下,gyroscope_event.values?? [0]將接近uncalibrated_gyroscope_event.values?? [0] - uncalibrated_gyroscope_event.values?? [3]。那是,


calibrated_x?= uncalibrated_x - bias_estimate_x


注意:未校准傳感器,提供更多的原始結果和可能包括一些偏見,但他們的測量結果包含更正減少跳躍通過應用校准。一些應用可能更喜歡這些未校正結果更平滑,更可靠。例如,如果一個應用程序試圖自行進行傳感器融合,引入校准實際上可以扭曲的結果。


除了旋轉的速率,未校正陀螺儀還提供了圍繞每個軸線的估計漂移。下面的代碼展示了如何獲得默認未校准陀螺儀的一個實例:

 

 

private SensorManager mSensorManager;
private Sensor mSensor;
...
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE_UNCALIBRATED);

 

用線性加速度計


線性加速度傳感器提供使用表示沿每個設備軸加速度的三維向量,不含重力。下面的代碼演示如何得到默認的線性加速度傳感器的一個實例:

 

 

private SensorManager mSensorManager;
private Sensor mSensor;
...
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);
概念上,該傳感器根據以下的關系提供了加速度數據:
線性加速度=加速度 - 重力加速度
當你想獲得加速度數據沒有重力的影響,通常使用此傳感器。例如,你可以使用這個傳感器來看看你的車有多快。線性加速度傳感器總是有偏移,您需要刪除。要做到這一點最簡單的方法是建立一個校准步驟到應用程序中。在校准過程中,你可以要求用戶設置設備在桌子上,然後讀取偏移量所有三個軸。然後,您可以減去從加速度傳感器直接讀數偏差獲得實際的線性加速度。
該傳感器坐標系中是相同的由加速度傳感器中所使用的一樣,都是測量單位(米/秒2)。
使用旋轉矢量傳感器
旋轉矢量表示設備的方向作為角度和一個軸,其中該設備已通過旋轉角度θ繞軸(x,y或z)的組合。下面的代碼演示了如何獲取默認的旋轉矢量傳感器的一個實例:

 

 

private SensorManager mSensorManager;
private Sensor mSensor;
...
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
旋轉矢量的三個元素表示如下:

 

 

x*sin(θ/2)
y*sin(θ/2)
z*sin(θ/2)
於旋轉軸的方向。



\
圖1.通過坐標旋轉矢量傳感器使用的系統。


旋轉矢量的三個元素是等於一個單位四元數的最後三個組成部分(COS(θ/ 2)中,x * SIN(θ/ 2)中,y * SIN(θ/ 2)中,z * SIN(θ/ 2))。旋轉向量的元素是無單位的。在x,y和z軸都以相同的方式如加速度傳感器所定義。參照坐標系被定義為一個直接正交基(見圖1)。這個坐標系統具有以下特征:


X定義為向量積Y X Z的是在該裝置的當前位置相切於地面並指出約東。
Y是在該裝置的當前位置相切地朝向地磁北極指向。
朝向天空?點並垂直於地平面。
Android SDK中提供了一個示例應用程序,展示了如何使用旋轉矢量傳感器。示例應用程序位於API演示代碼(OS - RotationVectorDemo)。


利用重大運動傳感器


該顯著運動傳感器觸發檢測每次顯著運動事件,然後自行禁用。一個顯著運動,可能導致用戶的位置變化的議案;例如步行,騎自行車,或坐在行駛的汽車。下面的代碼演示了如何獲得默認顯著運動傳感器的一個實例,以及如何注冊一個事件監聽器:

 

 

private SensorManager mSensorManager;
private Sensor mSensor;
private TriggerEventListener mTriggerEventListener;
...
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION);

mTriggerEventListener = new TriggerEventListener() {
  @Override
  public void onTrigger(TriggerEvent event) {
    // Do work
  }
};

mSensorManager.requestTriggerSensor(mTriggerEventListener, mSensor);
欲了解更多信息,請參見觸發事件偵聽器。
使用步驟計數傳感器
步進計數器傳感器提供的,而在傳感器被激活自上次重啟由用戶所采取的步驟的數目。在步驟計數器有更多的等待時間(最長10秒),但更精確度高於所述步驟檢測器的傳感器。下面的代碼演示了如何獲得缺省步計數傳感器的一個實例:

 

 

private SensorManager mSensorManager;
private Sensor mSensor;
...
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
使用步驟檢測儀傳感器


步驟檢測儀傳感器觸發事件在用戶每次花費了一步。的等待時間預計為低於2秒。下面的代碼演示了如何獲得缺省步檢測傳感器的一個實例:

 

 

private SensorManager mSensorManager;
private Sensor mSensor;
...
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);

 

 
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved