2014-01-05 49 views
7

我非常驚訝,在Android 4.0+版本中,他們決定從可用軟件傳感器中刪除LINEAR ACCELERATION傳感器,並將其放入硬件傳感器中,這是在普通手機中很少使用的陀螺儀。我不知道他們爲什麼這麼做,但想象一下,當我交付在一部便宜的2.3手機上測試過的軟件時,我感到驚訝,並且在2個月大的手機上顯示無法實例化線性加速度傳感器。他們爲什麼要這樣做?如何使用Android中的AcceleroMeter正確計算線性加速度

爲了保存我的皮膚,我檢查了手機中是否有加速度計,它是否可用。基於this article,我應該能夠使用來自加速度計的數據計算線性加速度。我檢查了代碼,發現一個沒有聲明的變量。

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; 
    float[] gravity=new float[]{0.0f,0.0f,0.0f}; //should it be here??? 

    // 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]; 
} 

重力數組在第一次運行中包含什麼? 我是否應該像

float[] gravity=new float[]{0.0f,0.0f,0.0f}; 

還是應該包含可以通過重力傳感器獲得的真實重力數據(在常規設備中也不可用)?

計算結果是否爲正確的線性加速度數據?是否可以通過減少傳入傳感器數據中的數字來計算?

+0

根據http://developer.android.com/guide/topics/sensors/sensors_motion.html在Android 4.0及以後,線性加速度傳感器是僅在具有陀螺儀的設備可用。「如果設備沒有陀螺儀,這些傳感器不會顯示出來,並且不能使用。」 – Jerry101

+1

爲什麼他們決定取下2.3手機中的傳感器?所以他們認爲4.0手機中的一半(沒有陀螺儀)比2.3手機可以測量線性加速度的專業性要差一些。偉大的創新.... – Nestor

+0

是的,它很臭。嘗試將應用程序的uses-sdk'android:targetSdkVersion'設置爲9(Android 2.3)或13(Android 3.2)。 *應該*使新操作系統與早期版本兼容。記錄該實驗的結果會很棒。 – Jerry101

回答

1

我沒有一個很好的答案,但我知道的是,acelerometer的實際初始讀數很難(0,0,0),因爲當設備不移動時它不是0,因爲該值取決於3軸的位置,而不是在運動中(通過位置的差異,我們可以推斷出運動)。因此,要獲取任何相關數據,您必須比較不同的讀數。爲此,我希望在開始時讀取acelerometer的數值(在第一次撥打onsensorchanged時),然後開始計算第二次調用函數

實際上,當他們談到重力時,不需要重力傳感器,因爲acelerometer實際上就是這樣。它是測量每個軸的重力值,從0到1

+0

那麼我不明白爲什麼Google會告訴上述代碼計算線性加速度?根據你的回答,它缺乏初始重力讀數。 – Nestor

+0

我認爲這個例子並不像其他的那樣完整,因爲你不能讀取所有的東西,正如你所說的,它們沒有初始化所有的變量。如果你用全零初始化它(這可能是他們默默提出的),代碼將起作用,並且在第一次測量中它可能不會有點不準確。我會做的,就是開始編寫其中的一種方法,測試它,並且如果你不認爲結果是好的,那麼準備好一個小的因素。代碼中的差異不會很大,並且可能通過一些數據更易於理解 –

+0

並且您會驗證上面代碼中計算出的線性加速度值多少有點不準確嗎?我們使用了代碼,當手機放在背後時,它顯示7.5爲Z軸線性加速度。如果上面的代碼可以糾正重力效應,那麼它應該在每個軸上顯示0.0左右。它不是。如果我站在手機上,Y軸顯示7.5。 – Nestor

1

您需要計算重力矢量。基本上你的加速度計測量總重量+加速度,所以你需要消除它的重力。在您提供的同一篇文章中有關於如何使用重力傳感器的信息。因此,傾聽該傳感器並從中更新您的重力矢量全局變量。

+1

正如我在我的第一篇文章中提到的,重力感應器在大多數設備中也是一個缺失的傳感器,所以我無法用它來計算。 – Nestor

1

實際上,在該文檔中提供的代碼片段是,它們從加速度計(包含重力和線性加速度)中獲取數據並對其進行過濾。因此,它如何基本工作,我們採取原始數據,並假設重力矢量是恆定的,不能很快改變,與線性加速度相反,而線性加速度的變化非常快。因此,讓我們假設如果我們使用過去80%的重力矢量並添加20%的原始數據,我們會過濾快速線性加速度峯值並獲得重力矢量。如果我們從原始數據中刪除重力矢量,我們可以得到沒有重力的線性加速度。谷歌進行指數篩選以獲取更多信息。在這裏你可以玩它http://copterpilot.ru/custom-app/exponential/。 因此,您可以輕鬆地初始化全局重力浮點數組,並等待一些過濾數據。下面是代碼段

public class MainActivity extends AppCompatActivity implements SensorEventListener { 
private float[] gravity = new float[3]; 
private float[] linear_acceleration = new float[3]; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    SensorManager mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); 
    Sensor mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 
    mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL); 
} 

@Override 
public void onSensorChanged(SensorEvent event) { 
    // alpha is calculated as t/(t + dT) 
    // with t, the low-pass filter's time-constant 
    // and dT, the event delivery rate 

    final float alpha = 0.8f; 

    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]; 

    linear_acceleration[0] = event.values[0] - gravity[0]; 
    linear_acceleration[1] = event.values[1] - gravity[1]; 
    linear_acceleration[2] = event.values[2] - gravity[2]; 
} 
} 
相關問題