В этом примере показано, как передать данные IMU потоком из Arduino и оценочной ориентации с помощью дополнительного фильтра.
Соедините SDA, SCL, GND и контакты VCC датчика MPU-9250 к соответствующим контактам оборудования Arduino®. Этот пример использует плату Arduino® Uno со следующими связями:
SDA - A4
SCL - A5
VCC - +3.3V
GND - GND
Убедитесь, что связи с датчиками неповреждены. Рекомендуется присоединить/соединить датчик к прототипному щиту, чтобы избежать свободных связей, в то время как датчик находится в движении. Пошлите страницу Troubleshooting Sensors отладить связанные с датчиком проблемы.
Создайте arduino
возразите и mpu9250
объект. Задайте частоту дискретизации датчика Fs
и количество времени, чтобы запустить циклы. Опционально, включите isVerbose
отметьте, чтобы проверять, превышаются ли какие-либо выборки. Путем отключения useHW
отметьте, можно также запустить пример с данными о датчике, сохраненными в MAT-файле loggedMPU9250Data.mat
.
Данные в loggedMPU9250Data.mat
регистрировался, в то время как IMU обычно стоял перед должным Югом, затем вращаемым:
+90 градусов вокруг оси z
- 180 градусов вокруг оси z
+90 градусов вокруг оси z
+90 градусов вокруг оси Y
- 180 градусов вокруг оси Y
+90 градусов вокруг оси Y
+90 градусов вокруг оси X
- 270 градусов вокруг оси X
+180 градусов вокруг оси X
Заметьте, что последние два вращения вокруг оси X являются еще 90 градусами. Это было сделано, чтобы инвертировать устройство вверх тормашками. Итоговая ориентация IMU совпадает с начальной ориентацией, должным Югом.
Fs = 100; samplesPerRead = 10; runTime = 20; isVerbose = false; useHW = true; if useHW a = arduino; imu = mpu9250(a, 'SampleRate', Fs, 'OutputFormat', 'matrix', ... 'SamplesPerRead', samplesPerRead, 'Streaming', true); else load('loggedMPU9250Data.mat', 'allAccel', 'allGyro', 'allMag', ... 'allT', 'allOverrun', ... 'numSamplesAccelGyro', 'numSamplesAccelGyroMag') end
Оси акселерометра, гироскопа и магнитометра в MPU-9250 не выравниваются друг с другом. Задайте индекс и подпишите x-, y-, и ось z каждого датчика так, чтобы датчик был выровнен с Северо-востоком вниз (NED) система координат, когда это в покое. В этом примере изменяются оси магнитометра, в то время как акселерометр и оси гироскопа остаются фиксированными. Для ваших собственных приложений измените следующие параметры по мере необходимости.
% 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]);
При необходимости можно калибровать магнитометр, чтобы компенсировать магнитные искажения. Для получения дополнительной информации смотрите раздел Compensating for Hard Iron Distortions Оценки Ориентации Используя Инерционное Cочетание датчиков и MPU-9250 (Sensor Fusion and Tracking Toolbox) пример.
complementaryFilter
имеет два настраиваемых параметра. AccelerometerGain
параметр определяет, насколько измерению акселерометра доверяют по измерению гироскопа. MagnetometerGain
параметр определяет, насколько измерению магнитометра доверяют по измерению гироскопа.
compFilt = complementaryFilter('SampleRate', Fs)
compFilt = complementaryFilter with properties: SampleRate: 100 AccelerometerGain: 0.0100 MagnetometerGain: 0.0100 HasMagnetometer: 1 OrientationFormat: 'quaternion'
Установите HasMagnetometer
свойство к false
отключить вход измерения магнитометра. В этом режиме фильтр только берет акселерометр и измерения гироскопа как входные параметры. Кроме того, фильтр принимает, что начальная ориентация IMU выравнивается с родительской системой координат навигации. Если IMU не будет выровнен с системой координат навигации первоначально, по оценке ориентации будет постоянное смещение.
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
Со значениями по умолчанию AccelerometerGain
и MagnetometerGain
, фильтр доверяет больше на измерениях гироскопа в ближайшей перспективе, но доверяет больше на измерениях акселерометра и магнитометра в долгосрочной перспективе. Это позволяет фильтру быть более реактивным к быстрой ориентации, изменяет и препятствует тому, чтобы оценки ориентации дрейфовали за более длительные промежутки времени. Для определенных датчиков IMU и целей приложения, можно хотеть настроить параметры фильтра, чтобы улучшить точность оценки ориентации.
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
Этот пример показал, как оценить ориентацию IMU использование данных из Arduino и дополнительного фильтра. Этот пример также показал, как сконфигурировать IMU и обсудил эффекты настройки дополнительных параметров фильтра.