exponenta event banner

Оценка ориентации с помощью дополнительного фильтра и данных IMU

В этом примере показано, как передавать данные 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 по координатам NED

Оси акселерометра, гироскопа и магнитометра в 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, и рассмотрены эффекты настройки дополнительных параметров фильтра.