2012-06-17 5 views
16

私はを必要とするAndroidアプリケーションを開発するつもりです。3D空間の携帯電話のx、y、z座標を読み取ります。加速度計を使用してAndroid携帯電話のxyz座標を読み取る

私はデバイス上の単純なコードやテストを書きたい

..私は、デバイスとエミュレータの両方でジンジャーブレッドを使用しています

+0

[3D世界でのデバイスの動きを計算するために加速度センサー、ジャイロスコープ、コンパスを使用する]の可能な複製(http://stackoverflow.com/questions/8264518/using-accelerometer-gyroscope-and-compass-to-calculate-devices-また、回転状態を求めるスーパーセットもあります。 –

答えて

16

加速度から位置を取得するには、2回積分する必要があります。

加速度を積分すると速度が得られ、速度を積分すると位置が得られます。

ノイズを積分するとドリフトが発生し、ドリフトを積分するとドリフトが多く発生することに注意してください。アンドロイドセンサーはかなりのノイズを生成する傾向があります。

私のGalaxy S3では、Googleのリニア加速度センサー複合センサーを使用して、ドリフトを0.02mまで5秒で得ることができました。

ジンジャーブレッドでリニア加速度センサーを使用できるかどうかわかりません。あなたができない場合は、統合する前に重力を取り除く必要があります。

あなたがまだの場合は、 アンドロイド

でここにすべて http://developer.android.com/guide/topics/sensors/sensors_motion.html

モーションセンサーについての素晴らしい話を読ん

http://www.youtube.com/watch?v=C7JQ7Rpwn2k

コード:あなたが持っている今

static final float NS2S = 1.0f/1000000000.0f; 
float[] last_values = null; 
float[] velocity = null; 
float[] position = null; 
long last_timestamp = 0; 

@Override 
public void onSensorChanged(SensorEvent event) { 
    if(last_values != null){ 
     float dt = (event.timestamp - last_timestamp) * NS2S; 

     for(int index = 0; index < 3;++index){ 
      velocity[index] += (event.values[index] + last_values[index])/2 * dt; 
      position[index] += velocity[index] * dt; 
     } 
    } 
    else{ 
     last_values = new float[3]; 
     velocity = new float[3]; 
     position = new float[3]; 
     velocity[0] = velocity[1] = velocity[2] = 0f; 
     position[0] = position[1] = position[2] = 0f; 
    } 
    System.arraycopy(event.values, 0, last_values, 0, 3); 
    last_timestamp = event.timestamp; 
} 

3D空間内の位置は、電話が静止していると仮定していることに留意してくださいrtsサンプリング。

重力を取り除かないとすぐに非常に遠くになります。

これはデータをまったくフィルタリングせず、多くのドリフトを生成します。

+1

ドリフトを発生させるのはセンサーノイズだけではありません。このアプローチの主な制限は、加速度計で一定速度を検出することは基本的に不可能であるということです。あなたの携帯電話をちょうど振るだけで、積分すると合理的な結果が出るかもしれませんが、運転やサイクリングのような他のタイプの動きでは、ドリフトが大きくなります。 – Junuxx

+0

あなたは絶対に正しいです。私は車を追跡するために加速度計を使用しており、そのためにドリフトをさらに減らすためにカルマンフィルタを実装しました。また、静止時にノイズを測定して加速度計の精度を計算し、これを使用してフィルタ内のデータに重みを付けます。私は今のところかなり良い結果を得ています。 – spontus

+0

ここでは、ニュートンの物理学を使ってこれをすべて計算するので、あなたはそれを呼び出すときに「ドリフト」をたくさん得ますが、これは不正確です。 Runge-kuttaや、より良い結果を得るために位置を計算する他のより正確な方法を行います。 – Automatico

7

this tutorialを読んでください。上記のチュートリアル::

簡単な要約は、最初SensorManagerSensorのインスタンスを取得します。この後
onCreate()インサイド ::

mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); 
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL); 

onSensorChanged(SensorEvent event)をオーバーライドして、座標を取得するためにevent.values[]を使用しています。

@Override 
public void onSensorChanged(SensorEvent event) { 
    float x = event.values[0]; 
    float y = event.values[1]; 
    float z = event.values[2]; 
} 
関連する問題