В этом примере показано, как передавать данные IMU из Arduino и оценивать ориентацию с помощью дополнительного фильтра.
Подключите контакты SDA, SCL, GND и VCC датчика MPU-9250 к соответствующим контактам аппаратных средств Arduino ®. В этом примере используется плата Arduino ® Uno со следующими соединениями:
ПДД - A4
SCL - A5
VCC - + 3,3 В
ЗАЗЕМЛЕНИЕ - ЗАЗЕМЛЕНИЕ

Убедитесь, что соединения с датчиками не повреждены. Рекомендуется прикреплять/присоединять датчик к экрану прототипа, чтобы избежать ослабления соединений во время движения датчика. Обратитесь к странице «Устранение неполадок датчиков» для отладки проблем, связанных с датчиками.
Создание 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]);
При необходимости можно откалибровать магнитометр для компенсации магнитных искажений. Дополнительные сведения см. в разделе «Компенсация искажений твердого железа» примера «Оценка ориентации с использованием инерциального слияния датчиков и 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, и рассмотрены эффекты настройки дополнительных параметров фильтра.