Orientación de estimación con un filtro complementario y datos IMU
Este ejemplo muestra cómo transmitir datos IMU desde un Arduino y estimar la orientación utilizando un filtro complementario.
Conectar hardware
Conecte los pines SDA, SCL, GND y VCC del sensor MPU-9250 a los pines correspondientes del hardware Arduino®. Este ejemplo utiliza una placa Arduino® Uno con las siguientes conexiones:
ADV - A4
SCL-A5
VCC-+3,3 V
Tierra - Tierra
Asegúrese de que las conexiones a los sensores estén intactas. Se recomienda acoplar/conectar el sensor a un escudo prototipo para evitar conexiones sueltas mientras el sensor está en movimiento. Consulte la página para depurar los problemas relacionados con el sensor.
Crear objeto sensor
Cree un objeto arduino
y un objeto mpu9250
. Especifique la frecuencia de muestreo del sensor Fs
y la cantidad de tiempo para ejecutar los bucles. Opcionalmente, habilite el indicador isVerbose
para verificar si alguna muestra está desbordada. Al deshabilitar el indicador useHW
, también puede ejecutar el ejemplo con los datos del sensor guardados en el archivo MAT loggedMPU9250Data.mat
.
Los datos en loggedMPU9250Data.mat
se registraron mientras la IMU generalmente miraba hacia el sur y luego se rotaron:
+90 grados alrededor del eje z
-180 grados alrededor del eje z
+90 grados alrededor del eje z
+90 grados alrededor del eje y
-180 grados alrededor del eje y
+90 grados alrededor del eje y
+90 grados alrededor del eje x
-270 grados alrededor del eje x
+180 grados alrededor del eje x
Observe que las dos últimas rotaciones alrededor del eje x son 90 grados adicionales. Esto se hizo para voltear el dispositivo al revés. La orientación final de la IMU es la misma que la orientación inicial, hacia el sur.
Fs = 100; samplesPerRead = 10; runTime = 20; isVerbose = false; useHW = true; if useHW a = arduino; imu = mpu9250(a, 'SampleRate', Fs, 'OutputFormat', 'matrix', ... 'SamplesPerRead', samplesPerRead); else load('loggedMPU9250Data.mat', 'allAccel', 'allGyro', 'allMag', ... 'allT', 'allOverrun', ... 'numSamplesAccelGyro', 'numSamplesAccelGyroMag') end
Alinear ejes del sensor MPU-9250 con coordenadas NED
Los ejes del acelerómetro, giroscopio y magnetómetro del MPU-9250 no están alineados entre sí. Especifique el índice y el signo de los ejes x, y y z de cada sensor para que el sensor esté alineado con el sistema de coordenadas noreste-abajo (NED) cuando esté en reposo. En este ejemplo, los ejes del magnetómetro se cambian mientras que los ejes del acelerómetro y del giroscopio permanecen fijos. Para sus propias aplicaciones, cambie los siguientes parámetros según sea necesario.
% Accelerometer axes parameters. accelXAxisIndex = 1; accelXAxisSign = 1; accelYAxisIndex = 2; accelYAxisSign = 1; accelZAxisIndex = 3; accelZAxisSign = 1; % Gyroscope axes parameters. gyroXAxisIndex = 1; gyroXAxisSign = 1; gyroYAxisIndex = 2; gyroYAxisSign = 1; gyroZAxisIndex = 3; gyroZAxisSign = 1; % Magnetometer axes parameters. magXAxisIndex = 2; magXAxisSign = 1; magYAxisIndex = 1; magYAxisSign = 1; magZAxisIndex = 3; magZAxisSign = -1; % Helper functions used to align sensor data axes. alignAccelAxes = @(in) [accelXAxisSign, accelYAxisSign, accelZAxisSign] ... .* in(:, [accelXAxisIndex, accelYAxisIndex, accelZAxisIndex]); alignGyroAxes = @(in) [gyroXAxisSign, gyroYAxisSign, gyroZAxisSign] ... .* in(:, [gyroXAxisIndex, gyroYAxisIndex, gyroZAxisIndex]); alignMagAxes = @(in) [magXAxisSign, magYAxisSign, magZAxisSign] ... .* in(:, [magXAxisIndex, magYAxisIndex, magZAxisIndex]);
Realizar una calibración adicional del sensor
Si es necesario, puede calibrar el magnetómetro para compensar las distorsiones magnéticas. Para obtener más detalles, consulte la sección Compensación de distorsiones de hierro duro del ejemplo Estimating Orientation Using Inertial Sensor Fusion and MPU-9250 (Sensor Fusion and Tracking Toolbox) .
Especificar parámetros de filtro complementarios
El complementaryFilter
tiene dos parámetros ajustables. El parámetro AccelerometerGain
determina en qué medida se confía más en la medición del acelerómetro que en la medición del giroscopio. El parámetro MagnetometerGain
determina en qué medida se confía más en la medición del magnetómetro que en la medición del giroscopio.
compFilt = complementaryFilter('SampleRate', Fs)
compFilt = complementaryFilter with properties: SampleRate: 100 AccelerometerGain: 0.0100 MagnetometerGain: 0.0100 HasMagnetometer: 1 OrientationFormat: 'quaternion'
Estimar la orientación con acelerómetro y giroscopio
Establezca la propiedad HasMagnetometer
en false
para deshabilitar la entrada de medición del magnetómetro. En este modo, el filtro solo toma como entradas mediciones del acelerómetro y giroscopio. Además, el filtro supone que la orientación inicial de la IMU está alineada con el marco de navegación principal. Si la IMU no está alineada inicialmente con el marco de navegación, habrá un desplazamiento constante en la estimación de la orientación.
compFilt = complementaryFilter('HasMagnetometer', false); tuner = HelperOrientationFilterTuner(compFilt); if useHW tic else idx = 1:samplesPerRead; overrunIdx = 1; end while true if useHW [accel, gyro, mag, t, overrun] = imu(); accel = alignAccelAxes(accel); gyro = alignGyroAxes(gyro); else accel = allAccel(idx,:); gyro = allGyro(idx,:); mag = allMag(idx,:); t = allT(idx,:); overrun = allOverrun(overrunIdx,:); idx = idx + samplesPerRead; overrunIdx = overrunIdx + 1; pause(samplesPerRead/Fs) end if (isVerbose && overrun > 0) fprintf('%d samples overrun ...\n', overrun); end q = compFilt(accel, gyro); update(tuner, q); if useHW if toc >= runTime break; end else if idx(end) > numSamplesAccelGyro break; end end end
Estimar la orientación con acelerómetro, giroscopio y magnetómetro
Con los valores predeterminados de AccelerometerGain
y MagnetometerGain
, el filtro confía más en las mediciones del giroscopio en el corto plazo, pero confía más en las mediciones del acelerómetro y magnetómetro en el corto plazo. a largo plazo. Esto permite que el filtro sea más reactivo a los cambios rápidos de orientación y evita que las estimaciones de orientación se desvíen durante períodos de tiempo más largos. Para sensores IMU específicos y fines de aplicación, es posible que desee ajustar los parámetros del filtro para mejorar la precisión de la estimación de la orientación.
compFilt = complementaryFilter('SampleRate', Fs); tuner = HelperOrientationFilterTuner(compFilt); if useHW tic end while true if useHW [accel, gyro, mag, t, overrun] = imu(); accel = alignAccelAxes(accel); gyro = alignGyroAxes(gyro); mag = alignMagAxes(mag); else accel = allAccel(idx,:); gyro = allGyro(idx,:); mag = allMag(idx,:); t = allT(idx,:); overrun = allOverrun(overrunIdx,:); idx = idx + samplesPerRead; overrunIdx = overrunIdx + 1; pause(samplesPerRead/Fs) end if (isVerbose && overrun > 0) fprintf('%d samples overrun ...\n', overrun); end q = compFilt(accel, gyro, mag); update(tuner, q); if useHW if toc >= runTime break; end else if idx(end) > numSamplesAccelGyroMag break; end end end
Resumen
Este ejemplo mostró cómo estimar la orientación de una IMU utilizando datos de un Arduino y un filtro complementario. Este ejemplo también mostró cómo configurar la IMU y analizó los efectos de ajustar los parámetros del filtro complementario.