2012-06-17 8 views
16

Ich werde Android-Anwendung entwickeln, die x, y, z-Koordinaten des Telefons auf 3D-Raum lesen muss.Lesen x y z Koordinaten von Android-Handy mit Beschleunigungsmesser

Ich mag würde einen einfachen Code und Test auf dem Gerät schreiben ..

I Ingwer Brot bin mit sowohl auf das Gerät und Emulator.

+0

Mögliche Kopie von [Verwendung von Beschleunigungsmesser, Gyroskop und Kompass zur Berechnung der Bewegung des Geräts in der 3D-Welt] (http://stackoverflow.com/questions/8264518/using-accelerometer-gyroscope-and-compass-to-calculate-devices- Bewegung-in-3d) Obermenge, die auch nach dem Rotationszustand fragt. –

Antwort

16

Um die Position aus der Beschleunigung zu erhalten, müssen Sie sie zweimal integrieren.

Integration Beschleunigung gibt Ihnen Geschwindigkeit und die Integration der Geschwindigkeit gibt Ihnen die Position.

Denken Sie daran, dass die Integration von Rauschen Drift und integrierende Drift schafft eine Menge Drift, die Android-Sensoren neigen dazu, ziemlich viel Lärm zu erzeugen.

Auf meinem Galaxy S3 konnte ich mit dem linearen Beschleunigungssensor von Google in 5 Sekunden die Driftposition auf 0,02 m senken.

Ich bin mir nicht sicher, ob Sie den linearen Beschleunigungssensor auf Lebkuchen verwenden können. Wenn Sie nicht können, müssen Sie die Schwerkraft vor der Integration entfernen.

Wenn Sie nicht bereits haben, lesen Sie hier alles http://developer.android.com/guide/topics/sensors/sensors_motion.html

Eine große Rede über die Bewegungssensoren in android

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

Code:

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

Jetzt haben Sie Die Position im 3D-Raum, bedenken Sie, dass das Telefon stationär ist, wenn es sta rts Probenahme.

Wenn Sie die Schwerkraft nicht entfernen, wird es bald sehr weit weg sein.

Dies filtert die Daten überhaupt nicht und erzeugt eine Menge Drift.

+1

Nicht nur Sensorrauschen erzeugt Drift. Die Hauptbeschränkung dieses Ansatzes besteht darin, dass es im Prinzip unmöglich ist, eine konstante Geschwindigkeit mit einem Beschleunigungsmesser zu erfassen.So könnte das Integrieren scheinbar vernünftige Ergebnisse bringen, wenn Sie Ihr Telefon nur ein bisschen schütteln, aber für andere Arten von Bewegung, zum Beispiel beim Fahren oder Radfahren, wird die Drift sehr groß sein. – Junuxx

+0

Sie haben absolut Recht. Ich benutze den Beschleunigungsmesser, um ein Auto zu verfolgen, und dafür habe ich einen Kalman-Filter implementiert, um die Drift weiter zu reduzieren. Ich berechne auch die Genauigkeit des Beschleunigungsmessers, indem ich das Geräusch im Stillstand vermesse, um die Daten im Filter zu gewichten. Ich bekomme bisher ziemlich gute Ergebnisse. – spontus

+0

Hier bekommen Sie auch eine Menge "Drift", wie Sie es nennen, weil Sie all dies mit newtonscher Physik berechnen, was ungenau ist. Machen Sie Runge-Kutta oder eine andere genauere Art der Berechnung der Position, um bessere Ergebnisse zu erzielen. – Automatico

7

Gelesen this tutorial.

kurze Zusammenfassung der oben angegebenen Tutorial ::

zuerst eine Instanz von SensorManager und Sensor bekommen.
Innen onCreate() ::

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

nach diesem, außer Kraft setzen onSensorChanged(SensorEvent event) und verwenden event.values[] die Koordinaten zu erhalten.

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