IMU verstehen – Beschleunigung, Drehrate & Orientierung mit Sensorfusion

IMU verstehen: Accel, Gyro & (Mag) – Orientierung aus Rohdaten gewinnen
Eine IMU (Inertial Measurement Unit) enthält meist einen 3-Achsen-Beschleunigungssensor, ein 3-Achsen-Gyroskop und optional ein Magnetometer. Zusammen erlauben sie die Bestimmung von Roll, Pitch und Yaw, die Erkennung von Bewegungen und die Stabilisierung von Robotern, Drohnen oder Wearables.
Kurzübersicht
-
Einheiten: Accel in
g
oderm/s²
, Gyro in°/s
oderrad/s
, Mag inµT
. - Achsen: Rechtshandsystem (X,Y,Z), Datenblatt beachten (Board-Orientierung!).
- Abtastrate: 50–200 Hz für Lage; Anti-Aliasing/LPF nutzen.
- Sensorfusion: Complementary/Madgwick/Mahony → Kombination aus Gyro (schnell, driftet) und Accel/Mag (langsam, absolute Referenz).
Verdrahtung (I²C – typisch)
- VCC → 3,3 V (bei 5-V-MCUs Level-Shifter/5-V-tolerantes Breakout nutzen)
- GND → gemeinsame Masse
- SCL → I²C-SCL, SDA → I²C-SDA (Pull-Ups meist auf dem Breakout)
- CS/SDO je nach Board für SPI/Adresswahl
Kalibrierung (muss!)
- Gyro-Bias: IMU ruhig liegen lassen, einige Sekunden mitteln → Offsets abziehen.
- Accel-Bias/Scale: ±1g-Lage nacheinander auf X/Y/Z ausrichten, Offsets/Skalierung anpassen.
- Mag-Hard/Soft-Iron: 8-Zähl-Bewegung (alle Raumrichtungen), Ellipsen-Fit → 3D-Offset/Skalierung.
- Offsets persistieren (EEPROM/Flash), regelmäßig neu kalibrieren.
Complementary-Filter (Grundidee)
Gyro integriert Winkel schnell, treibt aber weg; Accel liefert Schwerkraft-Richtung, ist aber rauschig. Mischung:
winkel = α · (winkel + gyro · Δt) + (1−α) · accel_winkel
Typisch α ≈ 0,98
bei 100 Hz.
Arduino-Beispiel: LSM6DS-IMU + Madgwick (Roll/Pitch/Yaw)
Beispiel nutzt eine 6-Achsen-IMU (z. B. LSM6DSOX/LSM6DS33) via I²C und den Madgwick-Filter (nur Accel+Gyro). Für Yaw ohne Magnetometer ist Drift unvermeidlich.
#include <Wire.h>
#include <Adafruit_LSM6DSOX.h>
#include <Adafruit_AHRS.h> // Madgwick/Mahony
Adafruit_LSM6DSOX imu;
Adafruit_Madgwick filter; // default beta
float sampleRateHz = 100.0f;
void setup() {
Serial.begin(115200);
if (!imu.begin_I2C()) {
Serial.println("IMU nicht gefunden"); while(1);
}
imu.setAccelRange(LSM6DS_ACCEL_RANGE_4_G);
imu.setGyroRange(LSM6DS_GYRO_RANGE_500_DPS);
imu.setAccelDataRate(LSM6DS_RATE_104_HZ);
imu.setGyroDataRate(LSM6DS_RATE_104_HZ);
filter.begin(sampleRateHz);
}
void loop() {
sensors_event_t acc, gyro, temp;
imu.getEvent(&acc, &gyro, &temp);
// Adafruit liefert Gyro in rad/s, Acc in m/s^2.
float gx=gyro.gyro.x, gy=gyro.gyro.y, gz=gyro.gyro.z;
float ax=acc.acceleration.x, ay=acc.acceleration.y, az=acc.acceleration.z;
filter.updateIMU(gx, gy, gz, ax, ay, az);
float roll, pitch, yaw;
filter.getEulerAngles(roll, pitch, yaw); // rad
Serial.print("Roll="); Serial.print(roll * 180.0f/3.14159f);
Serial.print(" Pitch="); Serial.print(pitch * 180.0f/3.14159f);
Serial.print(" Yaw="); Serial.println(yaw * 180.0f/3.14159f);
delay(5);
}
Python-Beispiel: CircuitPython auf Raspberry Pi (LSM6DS + Complementary)
Liess Accel/Gyro und berechne Roll/Pitch mit einem einfachen Complementary-Filter (Yaw benötigt ein Magnetometer).
import time, math, board, busio
from adafruit_lsm6ds import LSM6DS33
i2c = busio.I2C(board.SCL, board.SDA)
imu = LSM6DS33(i2c)
roll = 0.0
pitch = 0.0
alpha = 0.98
dt = 1.0/100.0 # 100 Hz
while True:
ax, ay, az = imu.acceleration # m/s^2
gx, gy, gz = imu.gyro # rad/s
# Winkel aus Accel (Neigung relativ zur Gravitation)
acc_roll = math.atan2(ay, az)
acc_pitch = math.atan2(-ax, math.sqrt(ay*ay + az*az))
# Gyro integrieren + fusionieren
roll = alpha*(roll + gx*dt) + (1-alpha)*acc_roll
pitch = alpha*(pitch + gy*dt) + (1-alpha)*acc_pitch
print("Roll={:.1f}°, Pitch={:.1f}°".format(roll*180/3.14159, pitch*180/3.14159))
time.sleep(dt)
Euler, Quaternionen & Gimbal-Lock
- Eulerwinkel (Roll/Pitch/Yaw) sind anschaulich, aber anfällig für Gimbal-Lock bei Pitch ≈ ±90°.
- Quaternionen vermeiden Singularitäten und sind numerisch stabil – Sensorfusion oft intern quaternion-basiert.
IMU vs. 9-DoF-AHRS – kurz verglichen
System | Sensoren | Vorteile | Hinweise |
---|---|---|---|
6-DoF IMU | Accel + Gyro | Schnell, kompakt | Yaw driftet ohne Magnetometer |
9-DoF AHRS | Accel + Gyro + Mag | Absolute Yaw-Referenz | Mag-Kalibrierung/Entstörung nötig |
Fusion-SoC | On-chip Fusion | Einfach, direkt Euler/Quat | Weniger flexibel |
Fehler, die man nur einmal macht
- Einheitenmix: Gyro in rad/s vs. °/s; Accel in g vs. m/s².
- Falsche Achsen: Board-Orientierung ignoriert → vertauschte Winkel.
- Keine Kalibrierung: Bias führt zu Drift/Schieflage.
- Zu niedrige Abtastrate: Alias-Effekte; Filter instabil.
- Magnetische Störer: Yaw springt; Hard/Soft-Iron nicht kompensiert.
Checkliste
- Abtastrate ≥100 Hz (Lage), passende LPF/HPF gesetzt
- Bias/Offsets kalibriert & gespeichert
- Achsen/Einheiten geprüft (Datentypen, Skalierung)
- Complementary/Madgwick/Mahony passend gewählt
- (Optional) Magnetometer kalibriert für stabilen Yaw
Fazit
IMUs liefern reichhaltige Bewegungsdaten. Mit sauberer Kalibrierung, korrektem Filter und konsistenten Einheiten erhältst du stabile Lage- und Bewegungsinformationen – ideal für Robotik, Drohnen und Interaktions-Projekte.
Tipp: Starte mit Complementary (einfach & robust). Wenn du absolute Yaw-Stabilität brauchst oder schnelle Dynamik hast, wechsle zu Madgwick/Mahony und füge ein Magnetometer hinzu.
- Tags: AHRS Arduino Beschleunigungssensor CircuitPython Complementary Filter Drift Drohne ESP32 Eulerwinkel Gyroskop I2C IMU Kalibrierung Kalman Low-Pass Madgwick Magnetometer Mahony Motion Tracking Quaternion Raspberry Pi Pico Robotik Sensorfusion SPI
0 Kommentare