Wie log-Daten von Android-Bewegungs-Sensoren mit einer festen rate
Lerne ich die Grundlagen der Android-Programmierung.
Habe ich eine einfache android-test-Anwendung, in der ich log den Beschleunigungsmesser,das magnetometer und die Ausrichtung der Daten in eine externe Datei, während auch die Anzeige. Ich initiieren die Protokollierung auf dem klicken einer Start - Taste (registerListener für die relevanten sensoren) durch den Aufruf der Methode initLogger.
Die sieht ungefähr so aus...
public void initLogger(View view)
{
boolean bFlag = false;
Button btnStart = (Button)findViewById(R.id.btnStartLog);
Button btnStop = (Button)findViewById(R.id.btnStopLog);
btnStart.setEnabled(bFlag);
btnStop.setEnabled(!bFlag);
bEnableLogging = true;
//Start reading the sensor values
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_UI);
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI);
//so on....
Gibt es auch eine Stop-Taste, die stop der Protokollierung (und schließlich aufheben der Registrierung durch aufrufen unregisterListener für jeden sensor)
Den Daten-retrieval-Prozess geschieht innerhalb der onSensorChanged handler, die Holen die Daten aus den entsprechenden sensoren, legt den Wert auf die jeweiligen UI-Elemente und schließlich melden die Daten an einen externen .csv-Datei.
onSensorChanged eventhandler sieht wie folgt aus ...
public void onSensorChanged(SensorEvent event) {
//TODO Auto-generated method stub
//accelerometer
TextView tAX = (TextView) findViewById(R.id.txtViewAxValue);
TextView tAY = (TextView) findViewById(R.id.txtViewAyValue);
TextView tAZ = (TextView) findViewById(R.id.txtViewAzValue);
//magnetic field
TextView tMX = (TextView) findViewById(R.id.txtViewMx);
TextView tMY = (TextView) findViewById(R.id.txtViewMy);
TextView tMZ = (TextView) findViewById(R.id.txtViewMz);
if (bEnableLogging) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
accelerometerdata = event.values.clone();
tAX.setText(Double.toString(accelerometerdata[0]));
tAY.setText(Double.toString(accelerometerdata[1]));
tAZ.setText(Double.toString(accelerometerdata[2]));
}
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
magneticmatrixdata = event.values.clone();
tMX.setText(Double.toString(magneticmatrixdata[0]));
tMY.setText(Double.toString(magneticmatrixdata[1]));
tMZ.setText(Double.toString(magneticmatrixdata[2]));
}
//so on ....
Obwohl ich Daten empfangen, die von allen konfigurierten sensoren, ich habe nicht die Kontrolle über die rate, mit der die Daten empfangen werden. ich.e
Ich weiß SensorChanged-Ereignis wird ausgelöst, wenn der Sensor-Daten geändert. Jedoch möchte ich dieses Ereignis ausgelöst werden, zu einem festen Zinssatz. Für ex: alle 40ms
Frage:
- Wie zur Gewährleistung der SensorChanged-Ereignis ausgelöst wird, bei konstanter Geschwindigkeit ?
- Ist die Klasse TimerTask, der in Java für jede Hilfe in diesem Fall ?
Experten hier draußen ALSO aus.Bitte helft mir 🙂
Die SensorChanged-Ereignis ausgelöst wird, wie und Wann es zu einer änderung in der sensor-Daten. Ich habe keine Kontrolle über das Ereignis. Über Ihren Vorschlag zu Lesen/Anfragen der tatsächlichen Werte zu einem bestimmten Zeitpunkt....ist genau das, was ich verlange. Wie explizit Anforderung für die Daten des Sensors ??
gut, nach nininho schrieb dies scheint nicht möglich zu sein, in android. Aber da Sie wissen, dass wenn es keine SensorChanged Ereignisses, das ausgelöst wird, gab es keine Veränderung, können Sie einfach Ihre alten Werte. Da fragte man für LOG-Daten in bestimmten Abständen, das würde ich nicht tun, keine Ausgabe in der onSensorChanged-Methode nur clone die neuen Daten an Ihre accelerometerdata variable. Und als log-Wert von accelerometerdata alle 40ms. Auf diese Weise sind Sie die Protokollierung der tatsächliche Wert jedes 40ms, auch wenn die Daten nicht ändern....
Infact dies ist, was ich gestern Tat. Sieht aus wie wir beide sind in gleichen Zeilen 🙂 Kannst du das als Antwort, so dass ich Sie akzeptieren kann.
und da ist es...
InformationsquelleAutor this-Me | 2012-09-03
Du musst angemeldet sein, um einen Kommentar abzugeben.
Da Sie wissen, dass wenn es keine SensorChanged Ereignisses, das ausgelöst wird, gab es keine Veränderung, können Sie einfach Ihre alten Werte.
Als Sie fragte, für die LOG-Daten in bestimmten Abständen, das würde ich nicht tun, keine Ausgabe in der onSensorChanged-Methode nur clone die neuen Daten an Ihre accelerometerdata variable.
Und als log-Wert von accelerometerdata alle 40ms. Auf diese Weise sind Sie die Protokollierung der tatsächliche Wert jedes 40ms, auch wenn die Daten nicht ändern....
Hinweis: Nach Ridcullys Antwort es scheint auch möglich zu sein, get Sensor data "erlöst" werden in bestimmten Zeitabständen. Da es aber eine Verzögerung, die auf diese "Lieferungen", wie immer mit sensor-Daten auf Android, mit meiner Lösung werden Sie mehr genau auf die 40ms Intervall. Auf der anderen Seite könnte es passieren, dass, wenn die Daten des Sensors ändert sich in dem moment, Sie melden Sie, kann es passieren, dass Sie unverzüglich die neuen Daten für ein Intervall.
Und ich denke (nicht sicher über diesen Punkt) - seit seiner nur zum anmelden und nicht über sth wie "machen Sie es so schnell wie möglich in Echtzeit", so ist dies nicht eine Anforderung - die Timer-Lösung verursacht weniger CPU-Last.
Ich habe versucht, diese Lösung aber es hat bei mir nicht funktioniert :\ Neue threads erstellt wurden, meldet falsche Daten an falschen Abständen. Würde jeder eine poste bitte ein code-snippet für diese Lösung ? Dank der in beide Richtungen 🙂
InformationsquelleAutor nurgan
Können Sie das Intervall ändern, durch ändern der Verzögerung bei der Registrierung für den sensor.
Laut diese, den Schnellsten Verzögerung ist, was Sie brauchen, und wenn Sie es nicht ändert schnell genug für Sie ist, da gab es keine änderungen. Es gibt keine getSensorData Methode.
siehe edit, es gibt keine Möglichkeit, das zu tun, android
InformationsquelleAutor Marcio Covre
Wenn Sie Ihre Zuhörer mit der
SensorManager
mit registerListener, statt der festen KonstantenSENSOR_DELAY_...
können Sie pass das Intervall in Mikrosekunden, wie beschrieben, in den JavaDocs:So, nur pass 40000 passend zu Ihrem Beispiel, Anfrage, auch, wie gesagt, dies ist nur ein Tipp also ich würde nicht verlassen sich auf, um die Werte in Abständen exakt auf die Mikrosekunden.
InformationsquelleAutor Ridcully
Habe ich versucht herauszufinden, wie kann ich sehr lange Verzögerungen mit sensoren, und so weit ich erfolgreich gewesen. Die Dokumentation auf der Entwickler.android spricht, kann die delay-Zeit in Mikrosekunden angegeben werden, ist eine große Zahl, die ich ausprobiert:
Aber beachten Sie die LogCat-dump unten - die onSensorChanged() - wird aufgerufen, so viele wie 4 mal in der Sekunde... ich versuche immer größeren Verzögerungen bisher ohne Erfolg!!!
01-14 06:58:07.088: D/OIE Sensoren(20933): onSensorChanged genannt, das Ereignis ist: android.hardware.SensorEvent@42849f70
01-14 06:58:07.268: D/OIE Sensoren(20933): onSensorChanged genannt, das Ereignis ist: android.hardware.SensorEvent@42849f70
01-14 06:58:07.448: D/OIE Sensoren(20933): onSensorChanged genannt, das Ereignis ist: android.hardware.SensorEvent@42849f70
01-14 06:58:07.628: D/OIE Sensoren(20933): onSensorChanged genannt, das Ereignis ist: android.hardware.SensorEvent@42849f70
01-14 06:58:07.808: D/OIE Sensoren(20933): onSensorChanged genannt, das Ereignis ist: android.hardware.SensorEvent@42849f70
01-14 06:58:07.989: D/OIE Sensoren(20933): onSensorChanged genannt, das Ereignis ist: android.hardware.SensorEvent@42849f70
01-14 06:58:08.169: D/OIE Sensoren(20933): onSensorChanged genannt, das Ereignis ist: android.hardware.SensorEvent@42849f70
InformationsquelleAutor Ashu Joshi
Es scheint, dass die rate, mit der die onSensorChanged genannt wird, hat eine der 4 vorgeschlagenen Werte.
Was Sie tun können, für "slow liest' ist die Verwendung SENSOR_DELAY_UI und (in der onSensorChanged) Messen Sie die Zeit, die vergangen ist, seit Sie das Letzte mal Sie Lesen Sie die sensordata:
Der einzige Nachteil, den ich hier sehe ist, dass die if-Anweisung viele Male aufgerufen werden, mit einem falschen Ergebnis.
InformationsquelleAutor pursang