Die Android-Plattform verfügt über mehrere Sensoren, mit denen du Bewegungen erfassen kannst. eines Geräts.
Die Die möglichen Architekturen variieren je nach Sensortyp:
- Schwerkraft, lineare Beschleunigung, Rotationsvektor, signifikante Bewegung, Schritt Zähler- und Schrittdetektorsensoren hardwarebasiert softwarebasiert.
- Der Beschleunigungsmesser und die Gyroskopsensoren sind immer hardwarebasiert.
Die meisten Android-Geräte verfügen über einen Beschleunigungsmesser und viele haben jetzt auch einen Gyroskop. Die Verfügbarkeit der softwarebasierten Sensoren da sie häufig auf einen oder mehrere Hardwaresensoren zurückgreifen, Daten. Je nach Gerät können diese softwarebasierten Sensoren ihre entweder vom Beschleunigungsmesser und Magnetometer oder vom Gyroskop.
Bewegungssensoren sind nützlich, um Gerätebewegungen wie Neigung, Schüttel, Drehung oder schwingen. Die Bewegung spiegelt in der Regel direkte Nutzereingaben wider (z. B. wenn Nutzende ein ein Auto in einem Spiel oder ein Nutzer, der einen Ball in einem Spiel steuert. der Umgebung, in der sich das Gerät befindet (z. B. wenn Sie sich beim Fahren mit Ihnen bewegen) Ihres Autos). Im ersten Fall beobachten Sie die Bewegung relativ zum Bezugsrahmen des Geräts. oder den Bezugsrahmen Ihrer App; Im zweiten Fall beobachten Sie die Bewegung Bezugsrahmen der Welt. Bewegungssensoren selbst werden in der Regel nicht zur Überwachung Geräteposition, können aber zusammen mit anderen Sensoren verwendet werden, z. B. dem Sensor für geomagnetische Felder, um die Position eines Geräts relativ zum Bezugsrahmen der Welt bestimmen. Weitere Informationen finden Sie unter Positionssensoren. Informationen).
Alle Bewegungssensoren geben für jede SensorEvent
mehrdimensionale Arrays von Sensorwerten zurück. Beispielsweise gibt der Beschleunigungsmesser während eines einzelnen Sensorereignisses
Beschleunigungskraftdaten für die drei Koordinatenachsen und das Gyroskop gibt die Rotationsrate zurück
für die drei Koordinatenachsen. Diese Datenwerte werden in einem float
-Array zurückgegeben.
(values
) zusammen mit anderen SensorEvent
Parameter. In Tabelle 1 sind die Bewegungssensoren zusammengefasst, die auf der Android-Plattform verfügbar sind.
Sensor | Sensorereignisdaten | Beschreibung | Maßeinheiten |
---|---|---|---|
TYPE_ACCELEROMETER |
SensorEvent.values[0] |
Beschleunigungskraft entlang der x-Achse (einschließlich der Schwerkraft). | m/s2 |
SensorEvent.values[1] |
Beschleunigungskraft entlang der Y-Achse (einschließlich der Schwerkraft). | ||
SensorEvent.values[2] |
Beschleunigungskraft entlang der z-Achse (einschließlich der Schwerkraft). | ||
TYPE_ACCELEROMETER_UNCALIBRATED |
SensorEvent.values[0] |
Gemessene Beschleunigung entlang der X-Achse ohne Verzerrungskompensation. | m/s2 |
SensorEvent.values[1] |
Gemessene Beschleunigung entlang der Y-Achse ohne Verzerrungskompensation. | ||
SensorEvent.values[2] |
Gemessene Beschleunigung entlang der Z-Achse ohne Verzerrungskompensation. | ||
SensorEvent.values[3] |
Gemessene Beschleunigung entlang der X-Achse mit geschätzter Verzerrungskompensation. | ||
SensorEvent.values[4] |
Gemessene Beschleunigung entlang der Y-Achse mit geschätzter Verzerrungskompensation. | ||
SensorEvent.values[5] |
Gemessene Beschleunigung entlang der Z-Achse mit geschätzter Verzerrungskompensation. | ||
TYPE_GRAVITY |
SensorEvent.values[0] |
Schwerkraft entlang der x-Achse. | m/s2 |
SensorEvent.values[1] |
Schwerkraft entlang der y-Achse. | ||
SensorEvent.values[2] |
Schwerkraft entlang der z-Achse. | ||
TYPE_GYROSCOPE |
SensorEvent.values[0] |
Rotationsrate um die x-Achse. | Rad/s |
SensorEvent.values[1] |
Rotationsrate um die Y-Achse. | ||
SensorEvent.values[2] |
Rotationsrate um die z-Achse. | ||
TYPE_GYROSCOPE_UNCALIBRATED |
SensorEvent.values[0] |
Rotationsrate (ohne Driftkompensation) um die x-Achse. | Rad/s |
SensorEvent.values[1] |
Rotationsrate (ohne Driftkompensation) um die y-Achse. | ||
SensorEvent.values[2] |
Rotationsrate (ohne Driftkompensation) um die z-Achse. | ||
SensorEvent.values[3] |
Geschätzte Abweichung um die x-Achse. | ||
SensorEvent.values[4] |
Geschätzte Abweichung um die Y-Achse. | ||
SensorEvent.values[5] |
Geschätzte Abweichung um die z-Achse. | ||
TYPE_LINEAR_ACCELERATION |
SensorEvent.values[0] |
Beschleunigungskraft entlang der x-Achse (ohne die Schwerkraft). | m/s2 |
SensorEvent.values[1] |
Beschleunigungskraft entlang der Y-Achse (ohne die Schwerkraft). | ||
SensorEvent.values[2] |
Beschleunigungskraft entlang der z-Achse (ohne die Schwerkraft). | ||
TYPE_ROTATION_VECTOR |
SensorEvent.values[0] |
Rotationsvektorkomponente entlang der x-Achse (x * sin(Θ/2)). | Ohne Einheit |
SensorEvent.values[1] |
Komponente des Rotationsvektors entlang der Y-Achse (y × sin(Θ/2)). | ||
SensorEvent.values[2] |
Rotationsvektorkomponente entlang der z-Achse (z × sin(Θ/2)). | ||
SensorEvent.values[3] |
Skalare Komponente des Rotationsvektors ((cos(Θ/2))1 | ||
TYPE_SIGNIFICANT_MOTION |
– | – | – |
TYPE_STEP_COUNTER |
SensorEvent.values[0] |
Anzahl der Schritte, die der Nutzer seit dem letzten Neustart gemacht hat, während der Sensor aktiviert wurde. | Schritte |
TYPE_STEP_DETECTOR |
– | – | – |
1 Die Skalarkomponente ist ein optionaler Wert.
Der Rotationsvektorsensor und der Schwerkraftsensor sind die am häufigsten verwendeten Sensoren für Bewegungen Erkennung und Monitoring. Der Rotationsvektorsensor ist besonders vielseitig und kann für eine Vielzahl von bewegungsbezogenen Aufgaben wie das Erkennen von Gesten, das Überwachen von Winkeländerungen und relativen Ausrichtungsänderungen überwachen. Der Rotationsvektorsensor ist beispielsweise ideal, ein Spiel, eine Augmented-Reality-App, einen zwei- oder dreidimensionalen Kompass oder eine App zur Kamerastabilisierung verwenden. In den meisten Fällen ist die Verwendung dieser Sensoren die bessere Wahl als die Verwendung Beschleunigungsmesser und den Sensor für geomagnetische Felder oder den Ausrichtungssensor.
Sensoren des Open-Source-Projekts von Android
Das Android Open Source Project (AOSP) bietet drei softwarebasierte Bewegungssensoren: ein
einen linearen Beschleunigungssensor und einen Rotationsvektorsensor. Diese Sensoren wurden aktualisiert im
Android 4.0 und nutzen jetzt neben anderen Sensoren das Gyroskop des Geräts zur Verbesserung von Stabilität und
die Leistung. Wenn du diese Sensoren ausprobieren möchtest, kannst du sie mithilfe der Methoden getVendor()
und getVersion()
identifizieren
Der Anbieter ist Google LLC, die Versionsnummer lautet 3. Die Identifizierung der Sensoren
nach Anbieter und
ist erforderlich, weil das Android-System diese drei Sensoren als sekundär betrachtet.
Sensoren. Wenn beispielsweise ein Gerätehersteller einen eigenen Schwerkraftsensor bereitstellt, dann ist der AOSP
der Schwerkraftsensor als sekundärer Schwerkraftsensor angezeigt. Alle drei Sensoren nutzen
Gyroskop: Wenn ein Gerät kein Gyroskop hat, werden diese Sensoren nicht angezeigt
die Sie verwenden können.
Schwerkraftsensor verwenden
Der Schwerkraftsensor liefert einen dreidimensionalen Vektor, der die Richtung und Größe der Schwerkraft. Dieser Sensor wird in der Regel verwendet, der relativen Ausrichtung des Geräts im Raum. Der folgende Code zeigt, wie Sie Rufen Sie eine Instanz des Standard-Schwerkraftsensors ab:
Kotlin
val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager val sensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY)
Java
private SensorManager sensorManager; private Sensor sensor; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
Die Einheiten entsprechen denen der Beschleunigung. (m/s2) und das Koordinatensystem ist dasselbe wie das vom Beschleunigungssensor.
Hinweis:Wenn sich ein Gerät im Ruhezustand befindet, gibt die Ausgabe des Schwerkraftsensors sollte mit dem Beschleunigungsmesser übereinstimmen.
Linearen Beschleunigungsmesser verwenden
Der lineare Beschleunigungssensor liefert Ihnen einen dreidimensionalen Vektor für die Beschleunigung entlang jeder Geräteachse, ausschließlich der Schwerkraft. Sie können Wert, um die Bewegungserkennung durchzuführen. Der Wert kann auch als Eingabe für Trägheitsnavigationssystem, das Tottenrechnung nutzt. Der folgende Code zeigt So rufen Sie eine Instanz des standardmäßigen linearen Beschleunigungssensors ab:
Kotlin
val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager val sensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION)
Java
private SensorManager sensorManager; private Sensor sensor; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); sensor = sensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);
Konzeptionell liefert dir dieser Sensor Beschleunigungsdaten gemäß den folgenden Kriterien: Beziehung:
linear acceleration = acceleration - acceleration due to gravity
Sie verwenden diesen Sensor in der Regel, wenn Sie Beschleunigungsdaten ohne Einfluss von Schwerkraft. Mit diesem Sensor können Sie beispielsweise feststellen, wie schnell Ihr Auto fährt. Die lineare Der Beschleunigungssensor hat immer einen Versatz, den Sie entfernen müssen. Am einfachsten geht das, um einen Kalibrierungsschritt in Ihre Anwendung zu integrieren. Während der Kalibrierung können Nutzer das Gerät auf einem Tisch und lesen die Offsets für alle drei Achsen. Diesen Wert können Sie dann subtrahieren, von den direkten Messwerten des Beschleunigungssensors abweichen, um die tatsächliche von Beschleunigungen.
Die Sensor-Koordinate entspricht dem System, das vom Beschleunigungssensor verwendet wird, sowie den Maßeinheiten (m/s2)
Rotationsvektorsensor verwenden
Der Rotationsvektor stellt die Ausrichtung des Geräts als Kombination aus einem Winkel und einem an der das Gerät um eine Achse (x, y oder z) gedreht wurde. Die folgenden zeigt Ihnen, wie Sie eine Instanz des Standard-Rotationsvektorsensors abrufen:
Kotlin
val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager val sensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR)
Java
private SensorManager sensorManager; private Sensor sensor; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
Die drei Elemente des Rotationsvektors werden wie folgt ausgedrückt:
Dabei ist die Größe des Rotationsvektors gleich sin(Θ/2) und die Richtung des Rotationsvektor entspricht der Richtung der Drehachse.
Die drei Elemente des Rotationsvektors entsprechen den letzten drei Komponenten einer Einheit Quaternion (cos(Θ/2), x*sin(Θ/2), y*sin(Θ/2), z*sin(Θ/2)). Elemente des Rotationsvektors sind ohne Einheit. Die x-, y- und z-Achsen sind genauso definiert wie der Beschleunigungssensor. Die Referenz Koordinatensystem als direkte Orthonormalbasis definiert ist (siehe Abbildung 1). Dieses Koordinatensystem weist folgende Merkmale auf:
- X ist definiert als das Vektorprodukt Y x Z. Sie bezieht sich auf die am aktuellen Standort des Geräts und zeigt ungefähr nach Osten.
- Y ist am aktuellen Standort des Geräts tangential für den Boden und zeigt auf geomagnetisch Nordpol.
- Z zeigt in Richtung Himmel und ist senkrecht zur Bodenebene.
Eine Beispielanwendung, die zeigt, wie der Rotationsvektorsensor verwendet wird, finden Sie unter . RotationVectorDemo.java aus.
Bewegungssensor mit signifikanter
Der Bewegungssensor löst jedes Mal ein Ereignis aus, wenn eine erhebliche Bewegung erkannt wird deaktiviert er sich selbst. Eine signifikante Bewegung ist eine Bewegung, die zu einer Veränderung des Standort des Nutzers zum Beispiel gehen, Radfahren oder in einem fahrenden Auto sitzen. Der folgende Code zeigt Ihnen, wie man eine Instanz des Standard-Bewegungssensors für signifikante Bewegungen erhält und wie man ein Ereignis registriert Listener:
Kotlin
val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager val mSensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION) val triggerEventListener = object : TriggerEventListener() { override fun onTrigger(event: TriggerEvent?) { // Do work } } mSensor?.also { sensor -> sensorManager.requestTriggerSensor(triggerEventListener, sensor) }
Java
private SensorManager sensorManager; private Sensor sensor; private TriggerEventListener triggerEventListener; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); sensor = sensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION); triggerEventListener = new TriggerEventListener() { @Override public void onTrigger(TriggerEvent event) { // Do work } }; sensorManager.requestTriggerSensor(triggerEventListener, mSensor);
Weitere Informationen findest du unter TriggerEventListener
.
Schrittzähler-Sensor verwenden
Der Schrittzähler-Sensor gibt die Anzahl der Schritte an, die der Nutzer seit dem letzten Neustart gemacht hat während der Sensor aktiviert war. Der Schrittzähler hat eine höhere Latenz (bis zu 10 Sekunden), aber mehr genauer als der Schrittdetektorsensor.
Hinweis: Sie müssen das
ACTIVITY_RECOGNITION
Berechtigung, damit deine App diesen Sensor auf Geräten verwenden kann, auf denen
Android 10 (API-Level 29) oder höher
Der folgende Code zeigt, wie Sie eine Instanz des Standardschritts abrufen. Zählersensor:
Kotlin
val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager val sensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER)
Java
private SensorManager sensorManager; private Sensor sensor; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); sensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
Um den Akku der Geräte zu schonen, auf denen deine App ausgeführt wird, solltest du die Funktion
Klasse JobScheduler
, aus der der aktuelle Wert abgerufen werden soll
Schrittzähler-Sensors in einem bestimmten Intervall. Obwohl verschiedene Arten von Apps
unterschiedliche Intervalle für die Sensormessung erfordern,
so lang wie möglich, es sei denn, Ihre App benötigt Echtzeitdaten vom Sensor.
Schritterkennungssensor verwenden
Der Schrittdetektorsensor löst jedes Mal ein Ereignis aus, wenn der Nutzer einen Schritt ausführt. Die Latenz beträgt bei weniger als 2 Sekunden liegen.
Hinweis: Sie müssen das
ACTIVITY_RECOGNITION
Berechtigung, damit deine App diesen Sensor auf Geräten verwenden kann, auf denen
Android 10 (API-Level 29) oder höher
Der folgende Code zeigt, wie Sie eine Instanz des Standardschritts abrufen. Detektorsensor:
Kotlin
val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager val sensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR)
Java
private SensorManager sensorManager; private Sensor sensor; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); sensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);
Mit Rohdaten arbeiten
Die folgenden Sensoren liefern Ihrer App Rohdaten über die lineare und Rotationskräfte, die auf das Gerät angewendet werden. Um die Werte aus müssen Sie Faktoren aus der Umgebung herausfiltern, wie die Schwerkraft. Möglicherweise müssen Sie auch einen Glättungsalgorithmus auf den Trend anwenden. um Rauschen zu reduzieren.
Beschleunigungsmesser verwenden
Ein Beschleunigungssensor misst die auf das Gerät angewendete Beschleunigung, einschließlich der Kraft der Schwerkraft. Der folgende Code zeigt, wie Sie eine Instanz des Standard-Beschleunigungssensors abrufen:
Kotlin
val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager val sensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
Java
private SensorManager sensorManager; private Sensor sensor; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
Hinweis : Wenn Ihre App auf Android 12 (API-Level 31) oder höher ist, ist dieser Sensor begrenzt.
Konzeptionell bestimmt ein Beschleunigungssensor die angewendete Beschleunigung auf ein Gerät (Ad) angewendet, indem die Kräfte gemessen werden, die auf den Sensor sich selbst (Fs) mithilfe der folgenden Beziehung zu:
Die Schwerkraft hat jedoch immer einen Einfluss auf die gemessene Beschleunigung gemäß dem die folgende Beziehung:
Wenn das Gerät auf einem Tisch liegt und nicht beschleunigt wird, Der Beschleunigungsmesser zeigt eine Größenordnung von g = 9,81 m/s2 an. Wenn sich das Gerät in und damit mit 9,81 m/s2 schnell auf den Boden zu, wodurch die der Beschleunigungsmesser eine Größenordnung von g = 0 m/s2 anzeigt. Um also zu messen, der tatsächlichen Beschleunigung des Geräts, muss der Beitrag der Schwerkraft von der die Daten des Beschleunigungsmessers. Dies kann durch die Anwendung eines Hochpassfilters erreicht werden. Umgekehrt ist ein Lowpass Filter kann verwendet werden, um die Schwerkraft zu isolieren. Das folgende Beispiel zeigt, wie Sie dies:
Kotlin
override fun onSensorChanged(event: SensorEvent) { // 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. val alpha: Float = 0.8f // 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] }
Java
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]; }
Hinweis:Sie können Sensordaten auf viele verschiedene Arten filtern. Im Codebeispiel oben wird eine einfache Filterkonstante (Alpha) verwendet, um einen Tiefpassfilter zu erstellen. Dieser Filter wird von einer Zeitkonstante (t) abgeleitet, die eine grobe Darstellung der Latenz darstellt, fügt der Filter die Sensorereignisse und die Ereignislieferrate des Sensors (dt) hinzu. Das Codebeispiel verwendet zu Demonstrationszwecken einen Alphawert von 0,8. Bei dieser Filtermethode benötigen Sie um einen anderen Alphawert auszuwählen.
Beschleunigungsmesser nutzen die standardmäßigen Sensorkoordinaten . In der Praxis bedeutet dies, dass die folgenden Bedingungen gelten, wenn ein Gerät auf einer flach auf einem Tisch in natürlicher Ausrichtung liegen:
- Wenn du das Gerät auf die linke Seite drückst, sodass es sich nach rechts bewegt, wird der x-Beschleunigungswert positiv ist.
- Wenn Sie das Gerät auf die Unterseite drücken (sodass es sich von Ihnen wegbewegt), beträgt der y-Beschleunigungswert positiv zu bewerten.
- Wenn Sie das Gerät mit einer Beschleunigung von A m/s2 in Richtung Himmel drücken, z-Beschleunigungswert ist gleich A + 9,81, was der Beschleunigung des Geräts entspricht (+A m/s2) abzüglich der Schwerkraft (-9,81 m/s2).
- Das unbewegliche Gerät hat einen Beschleunigungswert von +9,81, was dem Wert Beschleunigung des Geräts (0 m/s2 abzüglich der Schwerkraft, also -9,81) m/s2).
Im Allgemeinen ist der Beschleunigungsmesser ein guter Sensor zur Überwachung der Gerätebewegung. Nahezu alle Android-Geräte und -Tablets verfügen über einen Beschleunigungsmesser, der etwa zehnmal weniger Energie als die anderen Bewegungssensoren. Ein Nachteil ist, dass Sie möglicherweise Tiefpass- und Hochpassfilter, um Gravitationskräfte zu eliminieren und Störgeräusche zu reduzieren.
Gyroskop verwenden
Das Gyroskop misst die Umdrehungsgeschwindigkeit in Rad/s um die x-, y- und und die Z-Achse an. Der folgende Code zeigt, wie Sie eine Instanz des Standard-Gyroskops abrufen:
Kotlin
val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager val sensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE)
Java
private SensorManager sensorManager; private Sensor sensor; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
Hinweis : Wenn Ihre App auf Android 12 (API-Level 31) oder höher ist, ist dieser Sensor begrenzt.
Das Koordinatensystem des Sensors. ist mit dem für den Beschleunigungssensor verwendeten Sensor identisch. Die Rotation ist im Bereich gegen den Uhrzeigersinn also ein Beobachter, der von einer positiven Position auf der x-, y- oder z-Achse an einem Gerät, das am Ursprung positioniert ist, würde positive Drehung, wenn sich das Gerät offenbar gegen den Uhrzeigersinn dreht. Dies ist die die standardmäßige mathematische Definition der positiven Rotation. Sie ist nicht mit der Definition für die vom Ausrichtungssensor verwendet wird.
In der Regel wird die Ausgabe des Gyroskops über einen längeren Zeitraum hinweg integriert, um eine Drehung zu berechnen, die Änderung der Winkel im Zeitverlauf. Beispiel:
Kotlin
// Create a constant to convert nanoseconds to seconds. private val NS2S = 1.0f / 1000000000.0f private val deltaRotationVector = FloatArray(4) { 0f } private var timestamp: Float = 0f override fun onSensorChanged(event: SensorEvent?) { // This timestep's delta rotation to be multiplied by the current rotation // after computing it from the gyro sample data. if (timestamp != 0f && event != null) { val dT = (event.timestamp - timestamp) * NS2S // Axis of the rotation sample, not normalized yet. var axisX: Float = event.values[0] var axisY: Float = event.values[1] var axisZ: Float = event.values[2] // Calculate the angular speed of the sample val omegaMagnitude: Float = 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. val thetaOverTwo: Float = omegaMagnitude * dT / 2.0f val sinThetaOverTwo: Float = sin(thetaOverTwo) val cosThetaOverTwo: Float = cos(thetaOverTwo) deltaRotationVector[0] = sinThetaOverTwo * axisX deltaRotationVector[1] = sinThetaOverTwo * axisY deltaRotationVector[2] = sinThetaOverTwo * axisZ deltaRotationVector[3] = cosThetaOverTwo } timestamp = event?.timestamp?.toFloat() ?: 0f val deltaRotationMatrix = FloatArray(9) { 0f } 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; }
Java
// 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; }
Standard-Gyroskope liefern Rohdaten zu Rotationen ohne Filterung oder Korrektur von Rauschen Drift (Verzerrung). In der Praxis führen Gyroskoprauschen und -drift zu Fehlern, die behoben werden müssen. kompensiert werden. Normalerweise stellen Sie die Abweichung (Verzerrung) und das Rauschen durch die Überwachung anderer Sensoren fest, z. B. wie der Schwerkraft- oder Beschleunigungsmesser.
Nicht kalibriertes Gyroskop verwenden
Das nicht kalibrierte Gyroskop ähnelt dem Gyroskop,
außer dass keine Gyroskopkompensation auf die Rotationsrate angewendet wird. Werkskalibrierung
und die Temperaturkompensation weiterhin
auf die Drehgeschwindigkeit angewendet. Das nicht kalibrierte
Das Gyroskop eignet sich zur Nachbearbeitung und Zusammenführung von Ausrichtungsdaten. Im Allgemeinen
gyroscope_event.values[0]
liegt in der Nähe von
uncalibrated_gyroscope_event.values[0] - uncalibrated_gyroscope_event.values[3]
.
Das heißt:
calibrated_x ~= uncalibrated_x - bias_estimate_x
Hinweis:Nicht kalibrierte Sensoren liefern genauere Ergebnisse und können enthalten eine gewisse Verzerrung, aber ihre Messungen enthalten weniger Sprünge von Korrekturen bis Kalibrierung. Einige Anwendungen bevorzugen diese nicht kalibrierten Ergebnisse als flüssiger und besser zuverlässig sind. Wenn eine Anwendung z. B. versucht, eine eigene Sensorfusion durchzuführen, Kalibrierungen können die Ergebnisse verzerren.
Neben den Drehgeschwindigkeiten liefert das nicht kalibrierte Gyroskop auch die geschätzten Drift um jede Achse. Der folgende Code zeigt, wie Sie eine Instanz des Standard- nicht kalibriertes Gyroskop:
Kotlin
val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager val sensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE_UNCALIBRATED)
Java
private SensorManager sensorManager; private Sensor sensor; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE_UNCALIBRATED);
Zusätzliche Codebeispiele
Die Beispiel BatchStepSensor veranschaulicht zur Verwendung der auf dieser Seite beschriebenen APIs.