imufilter

Ориентация от акселерометра и показаний гироскопа

Описание

Система imufilter object™ плавит акселерометр и данные о датчике гироскопа, чтобы оценить ориентацию устройства.

Оценить ориентацию устройства:

  1. Создайте объект imufilter и установите его свойства.

  2. Вызовите объект с аргументами, как будто это была функция.

Чтобы узнать больше, как Системные объекты работают, смотрите то, Что Системные объекты? MATLAB.

Создание

Синтаксис

FUSE = imufilter
FUSE = imufilter(Name,Value)

Описание

пример

FUSE = imufilter возвращает косвенный Системный объект Фильтра Калмана, FUSE, для сплава акселерометра и данных о гироскопе, чтобы оценить ориентацию устройства. Фильтр использует вектор состояния с девятью элементами для дефекта записи в оценке ориентации, оценке смещения гироскопа и линейной ускоряющей оценке.

пример

FUSE = imufilter(Name,Value) наборы каждое свойство Name к заданному Value. Незаданные свойства имеют значения по умолчанию.

Пример: FUSE = imufilter('SampleRate',200,'GyroscopeNoise',1e-6) создает Системный объект, FUSE, с частотой дискретизации на 200 Гц и набором шума гироскопа к 1e-6 радианам в секунду придал квадратную форму.

Свойства

развернуть все

Если в противном случае не обозначено, свойства являются ненастраиваемыми, что означает, что вы не можете изменить их значения после вызова объекта. Объекты блокируют, когда вы вызываете их, и функция release разблокировала их.

Если свойство является настраиваемым, можно изменить его значение в любое время.

Для получения дополнительной информации об изменении значений свойств смотрите Разработку системы в MATLAB Используя Системные объекты (MATLAB).

Частота дискретизации входных данных о датчике в Гц, заданном как положительный конечный скаляр.

Настраиваемый: нет

Типы данных: single | double | uint8 | uint16 | uint32 | uint64 | int8 | int16 | int32 | int64

Фактор десятикратного уменьшения, которым можно уменьшать частоту дискретизации входных данных о датчике, заданных как положительный целочисленный скаляр.

Количество строк входных параметров, accelReadings и gyroReadings, должно быть кратным фактору десятикратного уменьшения.

Настраиваемый: нет

Типы данных: single | double | uint8 | uint16 | uint32 | uint64 | int8 | int16 | int32 | int64

Отклонение акселерометра сигнализирует о шуме в (m/s2) 2, заданный как положительный действительный скаляр.

Настраиваемый: да

Типы данных: single | double | uint8 | uint16 | uint32 | uint64 | int8 | int16 | int32 | int64

Отклонение гироскопа сигнализирует о шуме в (rad/s) 2, заданный как положительный действительный скаляр.

Настраиваемый: да

Типы данных: single | double | uint8 | uint16 | uint32 | uint64 | int8 | int16 | int32 | int64

Отклонение смещения гироскопа дрейфует в (rad/s) 2, заданный как положительный действительный скаляр.

Настраиваемый: да

Типы данных: single | double | uint8 | uint16 | uint32 | uint64 | int8 | int16 | int32 | int64

Отклонение линейного ускоряющего шума в (m/s2) 2, заданный как положительный действительный скаляр. Линейное ускорение моделируется, когда lowpass отфильтровал белый шумовой процесс.

Настраиваемый: да

Типы данных: single | double | uint8 | uint16 | uint32 | uint64 | int8 | int16 | int32 | int64

Фактор затухания для линейного ускоряющего дрейфа, заданного как скаляр в области значений [0,1]. Если линейное ускорение изменяется быстро, установите LinearAccelerationDecayFactor на нижнее значение. Если линейное ускорение медленно изменяется, установите LinearAccelerationDecayFactor на более высокое значение. Линейный ускоряющий дрейф моделируется как lowpass-отфильтрованный белый шумовой процесс.

Настраиваемый: да

Типы данных: single | double | uint8 | uint16 | uint32 | uint64 | int8 | int16 | int32 | int64

Ковариационная матрица для шума процесса, заданного как 9 9 матрица. Значение по умолчанию:

  Columns 1 through 6

   0.000006092348396                   0                   0                   0                   0                   0
                   0   0.000006092348396                   0                   0                   0                   0
                   0                   0   0.000006092348396                   0                   0                   0
                   0                   0                   0   0.000076154354947                   0                   0
                   0                   0                   0                   0   0.000076154354947                   0
                   0                   0                   0                   0                   0   0.000076154354947
                   0                   0                   0                   0                   0                   0
                   0                   0                   0                   0                   0                   0
                   0                   0                   0                   0                   0                   0

  Columns 7 through 9

                   0                   0                   0
                   0                   0                   0
                   0                   0                   0
                   0                   0                   0
                   0                   0                   0
                   0                   0                   0
   0.009623610000000                   0                   0
                   0   0.009623610000000                   0
                   0                   0   0.009623610000000

Начальная ковариационная матрица процесса составляет ошибку в модели процесса.

Типы данных: single | double | uint8 | uint16 | uint32 | uint64 | int8 | int16 | int32 | int64

Выведите формат ориентации, заданный как 'quaternion' или 'Rotation matrix'. Размер вывода зависит от входного размера, N и выходного формата ориентации:

  • 'quaternion' – Выводом является N-by-1 quaternion.

  • 'Rotation matrix' – Вывод является 3 3 N матрицей вращения.

Типы данных: char | string

Использование

Синтаксис

[orientation,angularVelocity] = FUSE(accelReadings,gyroReadings)

Описание

пример

[orientation,angularVelocity] = FUSE(accelReadings,gyroReadings) акселерометр предохранителей и показания гироскопа, чтобы вычислить ориентацию и угловые скоростные измерения. Алгоритм принимает, что устройство является стационарным перед первым вызовом.

Входные параметры

развернуть все

Показания акселерометра в системе координат корпуса датчика в m/s2, заданном как N-by-3 матрица. N является количеством выборок, и три столбца accelReadings представляют [x y z] измерения. Показания акселерометра приняты, чтобы соответствовать частоте дискретизации, заданной свойством SampleRate.

Типы данных: single | double

Показания гироскопа в системе координат корпуса датчика в rad/s, заданном как N-by-3 матрица. N является количеством выборок, и три столбца gyroReadings представляют [x y z] измерения. Показания гироскопа приняты, чтобы соответствовать частоте дискретизации, заданной свойством SampleRate.

Типы данных: single | double

Выходные аргументы

развернуть все

Ориентация, которая может вращать количества от глобальной системы координат до системы координат тела, возвратилась как кватернионы или массив. Размер и тип orientation зависят от того, установлено ли свойство OrientationFormat в 'quaternion' или 'Rotation matrix':

  • 'quaternion' – Выводом является M-by-1 вектор кватернионов с тем же базовым типом данных как входные параметры.

  • 'Rotation matrix' – Вывод является 3 3 M массивом матриц вращения совпадающий тип данных как входные параметры.

Количество входных выборок, N и свойства DecimationFactor определяет M.

Можно использовать orientation в функции rotateframe, чтобы вращать количества от глобальной системы координат до системы координат корпуса датчика.

Типы данных: quaternion | single | double

Угловая скорость со смещением гироскопа, удаленным в системе координат корпуса датчика в rad/s, возвращенном как M-by-3 массив. Количество входных выборок, N и свойства DecimationFactor определяет M.

Типы данных: single | double

Функции объекта

Чтобы использовать объектную функцию, задайте Системный объект как первый входной параметр. Например, чтобы выпустить системные ресурсы Системного объекта под названием obj, используйте этот синтаксис:

release(obj)

развернуть все

stepЗапустите алгоритм Системного объекта
releaseВысвободите средства и позвольте изменения в значениях свойств Системного объекта и введите характеристики
resetСбросьте внутренние состояния Системного объекта

Примеры

развернуть все

Загрузите файл rpy_9axis, который содержит записанный акселерометр, гироскоп, и данные о датчике магнитометра из устройства, колеблющегося в подаче (вокруг оси Y), затем отклоняются от курса (вокруг оси z), и затем прокручиваются (вокруг оси X). Файл также содержит частоту дискретизации записи.

load 'rpy_9axis.mat' sensorData Fs

accelerometerReadings = sensorData.Acceleration;
gyroscopeReadings = sensorData.AngularVelocity;

Создайте Систему imufilter object™ с набором частоты дискретизации к частоте дискретизации данных о датчике. Задайте фактор десятикратного уменьшения два, чтобы уменьшать вычислительную стоимость алгоритма.

decim = 2;
fuse = imufilter('SampleRate',Fs,'DecimationFactor',decim);

Передайте показания акселерометра и показания гироскопа к объекту imufilter, fuse, чтобы выводить оценку ориентации корпуса датчика в зависимости от времени. По умолчанию ориентация выводится как вектор кватернионов.

q = fuse(accelerometerReadings,gyroscopeReadings);

Ориентация задана угловым смещением, требуемым вращать систему координаты вышестоящего элемента к системе координаты нижестоящего элемента. Постройте ориентацию в Углах Эйлера в градусах в зависимости от времени.

Сплав imufilter правильно оценивает изменение в ориентации от принятой стоящей с севером начальной ориентации. Однако ось X устройства указывала на юг, когда зарегистрировано. Чтобы правильно оценить ориентацию относительно истинной начальной ориентации или относительно NED, используйте ahrsfilter.

time = (0:decim:size(accelerometerReadings,1)-1)/Fs;

plot(time,eulerd(q,'ZYX','frame'))
title('Orientation Estimate')
legend('Z-axis', 'Y-axis', 'X-axis')
xlabel('Time (s)')
ylabel('Rotation (degrees)')

Смоделируйте наклон IMU, который содержит акселерометр и гироскоп с помощью Системы imuSensor object™. Используйте идеальные и реалистические модели, чтобы сравнить результаты отслеживания ориентации с помощью Системного объекта imufilter.

Загрузите struct, описывающий движение наземной истины и частоту дискретизации. Struct движения описывает последовательные вращения:

  1. отклонение от курса: 120 градусов более чем две секунды

  2. подача: 60 градусов более чем одна секунда

  3. список: 30 градусов по половине второго

  4. список:-30 градусов по половине второго

  5. подача:-60 градусов более чем одна секунда

  6. отклонение от курса:-120 градусов более чем две секунды

На последней стадии struct движения комбинирует 1-е, 2-е, и 3-и вращения во вращение одно оси. Ускорение, угловая скорость и ориентация заданы в локальной системе координат NED.

load y120p60r30.mat motion fs
accNED = motion.Acceleration;
angVelNED = motion.AngularVelocity;
orientationNED = motion.Orientation;

numSamples = size(motion.Orientation,1);
t = (0:(numSamples-1)).'/fs;

Создайте идеальный объект датчика IMU и объект фильтра IMU по умолчанию.

IMU = imuSensor('accel-gyro','SampleRate',fs);

aFilter = imufilter('SampleRate',fs);

В цикле:

  1. Моделируйте IMU вывод путем питания движения наземной истины объект датчика IMU.

  2. Отфильтруйте IMU вывод с помощью объекта фильтра IMU по умолчанию.

orientation = zeros(numSamples,1,'quaternion');
for i = 1:numSamples

    [accelBody,gyroBody] = IMU(accNED(i,:),angVelNED(i,:),orientationNED(i,:));

    orientation(i) = aFilter(accelBody,gyroBody);

end
release(aFilter)

Стройте ориентацию в зависимости от времени.

figure(1)
plot(t,eulerd(orientation,'ZYX','frame'))
xlabel('Time (s)')
ylabel('Rotation (degrees)')
title('Orientation Estimation -- Ideal IMU Data, Default IMU Filter')
legend('Z-axis','Y-axis','X-axis')

Измените свойства своего imuSensor смоделировать реальные датчики. Запустите цикл снова и стройте оценку ориентации в зависимости от времени.

IMU.Accelerometer = accelparams( ...
    'MeasurementRange',19.62, ...
    'Resolution',0.00059875, ...
    'ConstantBias',0.4905, ...
    'AxesMisalignment',2, ...
    'NoiseDensity',0.003924, ...
    'BiasInstability',0, ...
    'TemperatureBias', [0.34335 0.34335 0.5886], ...
    'TemperatureScaleFactor',0.02);
IMU.Gyroscope = gyroparams( ...
    'MeasurementRange',4.3633, ...
    'Resolution',0.00013323, ...
    'AxesMisalignment',2, ...
    'NoiseDensity',8.7266e-05, ...
    'TemperatureBias',0.34907, ...
    'TemperatureScaleFactor',0.02, ...
    'AccelerationBias',0.00017809, ...
    'ConstantBias',[0.3491,0.5,0]);

orientationDefault = zeros(numSamples,1,'quaternion');
for i = 1:numSamples

    [accelBody,gyroBody] = IMU(accNED(i,:),angVelNED(i,:),orientationNED(i,:));

    orientationDefault(i) = aFilter(accelBody,gyroBody);

end
release(aFilter)

figure(2)
plot(t,eulerd(orientationDefault,'ZYX','frame'))
xlabel('Time (s)')
ylabel('Rotation (degrees)')
title('Orientation Estimation -- Realistic IMU Data, Default IMU Filter')
legend('Z-axis','Y-axis','X-axis')

Способность imufilter отследить данные наземной истины значительно уменьшается при моделировании реалистического IMU. Чтобы улучшать производительность, измените свойства своего объекта imufilter. Эти значения были определены опытным путем. Запустите цикл снова и стройте оценку ориентации в зависимости от времени.

aFilter.GyroscopeNoise          = 7.6154e-7;
aFilter.AccelerometerNoise      = 0.0015398;
aFilter.GyroscopeDriftNoise     = 3.0462e-12;
aFilter.LinearAccelerationNoise = 0.00096236;
aFilter.InitialProcessNoise     = aFilter.InitialProcessNoise*10;

orientationNondefault = zeros(numSamples,1,'quaternion');
for i = 1:numSamples
    [accelBody,gyroBody] = IMU(accNED(i,:),angVelNED(i,:),orientationNED(i,:));

    orientationNondefault(i) = aFilter(accelBody,gyroBody);
end
release(aFilter)

figure(3)
plot(t,eulerd(orientationNondefault,'ZYX','frame'))
xlabel('Time (s)')
ylabel('Rotation (degrees)')
title('Orientation Estimation -- Realistic IMU Data, Nondefault IMU Filter')
legend('Z-axis','Y-axis','X-axis')

Чтобы определить количество улучшенной производительности измененного imufilter, постройте расстояние кватерниона между движением наземной истины и ориентацией, как возвращено imufilter со свойствами не по умолчанию и по умолчанию.

qDistDefault = rad2deg(dist(orientationNED,orientationDefault));
qDistNondefault = rad2deg(dist(orientationNED,orientationNondefault));

figure(4)
plot(t,[qDistDefault,qDistNondefault])
title('Quaternion Distance from True Orientation')
legend('Realistic IMU Data, Default IMU Filter', ...
       'Realistic IMU Data, Nondefault IMU Filter')
xlabel('Time (s)')
ylabel('Quaternion Distance (degrees)')

Этот пример показывает, как удалить смещение гироскопа из IMU использование imufilter.

Используйте kinematicTrajectory, чтобы создать траекторию с постоянной угловой скоростью приблизительно y-и оси z.

duration = 60*5;
fs = 20;
numSamples = duration * fs;

angVelBody = repmat([0,0.5,0.25],numSamples,1);
accBody = zeros(numSamples,3);

traj = kinematicTrajectory('SampleRate',fs);

[~,qNED,~,accNED,angVelNED] = traj(accBody,angVelBody);

Создайте Систему imuSensor object™, IMU, с неидеальным гироскопом. Вызовите IMU с ускорением наземной истины, угловой скоростью и ориентацией.

IMU = imuSensor('accel-gyro', ...
    'Gyroscope',gyroparams('BiasInstability',0.003,'ConstantBias',0.3), ...
    'SampleRate',fs);

[accelReadings, gyroReadingsBody] = IMU(accNED,angVelNED,qNED);

Создайте Системный объект imufilter, fuse. Вызовите fuse со смоделированными показаниями акселерометра и показаниями гироскопа.

fuse = imufilter('SampleRate',fs);

[~,angVelBodyRecovered] = fuse(accelReadings,gyroReadingsBody);

Постройте наземную истину угловая скорость, показания гироскопа и восстановленная угловая скорость для каждой оси.

Угловая скорость, возвращенная в imufilter, компенсирует эффект смещения гироскопа в зависимости от времени и сходится к истинной угловой скорости.

time = (0:numSamples-1)'/fs;

figure(1)
plot(time,angVelBody(:,3), ...
     time,gyroReadingsBody(:,3), ...
     time,angVelBodyRecovered(:,3))
title('X-axis')
legend('True Angular Velocity', ...
       'Gyroscope Readings', ...
       'Recovered Angular Velocity')
ylabel('Angular Velocity (rad/s)')

figure(2)
plot(time,angVelBody(:,2), ...
     time,gyroReadingsBody(:,2), ...
     time,angVelBodyRecovered(:,2))
title('Y-axis')
ylabel('Angular Velocity (rad/s)')

figure(3)
plot(time,angVelBody(:,1), ...
     time,gyroReadingsBody(:,1), ...
     time,angVelBodyRecovered(:,1))
title('Z-axis')
ylabel('Angular Velocity (rad/s)')
xlabel('Time (s)')

Алгоритмы

развернуть все

imufilter использует структуру Фильтра Калмана с шестью осями, описанную в [1]. Алгоритм пытается отследить ошибки в ориентации, смещении гироскопа и линейном ускорении, чтобы вывести итоговую ориентацию и угловую скорость. Вместо того, чтобы отследить ориентацию непосредственно, косвенный Фильтр Калмана моделирует ошибочный процесс, x, с рекурсивным обновлением:

xk=[θkbkak]=Fk[θk1bk1ak1]+wk

где xk 9 1 вектор, состоящий из:

  • θk – Вектор ошибок ориентации 3 на 1, в градусах, во время k

  • bk – Нулевой вектор смещения уровня гироскопа 3 на 1, в градусе/с, во время k

  • ak – Ускоряющий вектор ошибок 3 на 1 измеряется в кадре датчика, в g, во время k

  • wk – 9 1 аддитивный шумовой вектор

  • Fk – модель изменения состояния

Поскольку x k задан как ошибочный процесс, априорная оценка всегда является нулем, и поэтому модель изменения состояния, F k, является нулем. Это понимание приводит к следующему сокращению стандарта уравнения Кальмана:

Стандарт уравнения Кальмана:

xk=Fkxk1+Pk=FkPk1+FkT+Qkyk=zkHkxkSk=Rk+HkPkHkTKk=PkHkT(Sk)1xk+=xk+KkykPk+=PkKkHkPk

Уравнения Кальмана использовали в этом алгоритме:

xk=0Pk=Qkyk=zkSk=Rk+HkPkHkTKk=PkHkT(Sk)1xk+=KkykPk+=PkKkHkPk

где

  • xk – предсказанный (априорно) утверждают оценку; ошибочный процесс

  • Pk – предсказанный (априорно) оценивают ковариацию

  • yk – инновации

  • Sk – инновационная ковариация

  • Kk – Усиление Кальмана

  • xk + – обновленный (по опыту) утверждает оценку

  • Pk + – обновленный (по опыту) оценивает ковариацию

k представляет итерацию, верхний индекс + представляет по опыту оценка, и верхний индекс представляет априорную оценку.

Графические и следующие шаги описывают одну основанную на кадре итерацию через алгоритм.

Перед первой итерацией accelReadings и входные параметры gyroReadings разделяются на блоки в 1 3 кадры и DecimationFactor-by-3 кадры, соответственно. Алгоритм использует актуальнейшие показания акселерометра, соответствующие фрагменту показаний гироскопа.

Ссылки

[1] Fusion датчика с открытым исходным кодом. https://github.com/memsindustrygroup/Open-Source-Sensor-Fusion/tree/master/docs

[2] Roetenberg, D., Х.Дж. Линдж, C.T.M. Baten и П.Х. Велтинк. "Компенсация Магнитных Воздействий Улучшает Инерционное и Магнитное Обнаружение Ориентации Сегмента Человеческого тела". Транзакции IEEE в Нейронных Системах и Разработке Реабилитации. Издание 13. Выпуск 3, 2005, стр 395-405.

Расширенные возможности

Введенный в R2018b