meanrot

Среднее вращение Кватерниона

Описание

пример

quatAverage = meanrot(quat) возвращает среднее вращение элементов quat вдоль первого измерения массива, размер которого не равен 1.

  • Если quat является вектором, meanrot(quat) возвращает среднее вращение элементов.

  • Если quat является матрицей, meanrot(quat) возвращает вектор-строку, содержащую среднее вращение каждого столбца.

  • Если quat является многомерным массивом, затем mearot(quat) действует вдоль первого измерения массива, размер которого не равен 1, обрабатывая элементы как векторы. Эта размерность становится равным 1, в то время как размеры всех других размерностей остаются неизменными.

meanrot функция нормализует входные кватернионы, quat, перед вычислением среднего.

quatAverage = meanrot(quat,dim) возвращает среднее вращение по размерности dim. Для примера, если quat является матрицей, тогда meanrot(quat,2) - вектор-столбец, содержащая среднее значение каждой строки.

quatAverage = meanrot(___,nanflag) определяет, включать или опускать NaN значения из вычисления для любого из предыдущих синтаксисов. meanrot(quat,'includenan') включает все NaN значения в вычислении при mean(quat,'omitnan') игнорирует их.

Примеры

свернуть все

Создайте матрицу кватернионов, соответствующих трем наборам углов Эйлера.

eulerAngles = [40 20 10; ...
               50 10 5; ...
               45 70 1];

quat = quaternion(eulerAngles,'eulerd','ZYX','frame');

Определите среднее вращение, представленное кватернионами. Преобразуйте среднее вращение в углы Эйлера в степенях для читаемости.

quatAverage = meanrot(quat)
quatAverage = quaternion
      0.88863 - 0.062598i +  0.27822j +  0.35918k

eulerAverage = eulerd(quatAverage,'ZYX','frame')
eulerAverage = 1×3

   45.7876   32.6452    6.0407

Использование meanrot по последовательности кватернионов для среднего значения аддитивного шума.

Создайте вектор из 1e6 кватернионов, расстояние которых определяется dist функция от кватерниона (1,0,0,0) обычно распределена. Постройте график углов Эйлера, соответствующих зашумленному вектору кватерниона.

nrows = 1e6;
ax = 2*rand(nrows,3) - 1;   
ax = ax./sqrt(sum(ax.^2,2));
ang = 0.5*randn(size(ax,1),1);
q = quaternion(ax.*ang ,'rotvec');

noisyEulerAngles = eulerd(q,'ZYX','frame');

figure(1)

subplot(3,1,1)
plot(noisyEulerAngles(:,1))
title('Z-Axis')
ylabel('Rotation (degrees)')
hold on

subplot(3,1,2)
plot(noisyEulerAngles(:,2))
title('Y-Axis')
ylabel('Rotation (degrees)')
hold on

subplot(3,1,3)
plot(noisyEulerAngles(:,3))
title('X-Axis')
ylabel('Rotation (degrees)')
hold on

Figure contains 3 axes. Axes 1 with title Z-Axis contains an object of type line. Axes 2 with title Y-Axis contains an object of type line. Axes 3 with title X-Axis contains an object of type line.

Использование meanrot определить средний кватернион, заданный вектор кватернионов. Преобразуйте углы Эйлера и постройте график результатов.

qAverage = meanrot(q);

qAverageInEulerAngles = eulerd(qAverage,'ZYX','frame');

figure(1)

subplot(3,1,1)
plot(ones(nrows,1)*qAverageInEulerAngles(:,1))
title('Z-Axis')

subplot(3,1,2)
plot(ones(nrows,1)*qAverageInEulerAngles(:,2))
title('Y-Axis')

subplot(3,1,3)
plot(ones(nrows,1)*qAverageInEulerAngles(:,3))
title('X-Axis')

Figure contains 3 axes. Axes 1 with title Z-Axis contains 2 objects of type line. Axes 2 with title Y-Axis contains 2 objects of type line. Axes 3 with title X-Axis contains 2 objects of type line.

The meanrot Алгоритм

The meanrot функция выводит кватернион, который минимизирует квадратную норму Фробениуса различия между матрицами вращения. Рассмотрим два кватерниона:

  • q0 не представляет вращение.

  • q90 представляет вращение на 90 степени вокруг оси X.

q0 = quaternion([0 0 0],'eulerd','ZYX','frame');
q90 = quaternion([0 0 90],'eulerd','ZYX','frame');

Создайте кватернион свип, qSweep, который представляет повороты от 0 до 180 степеней вокруг оси X.

eulerSweep = (0:1:180)';
qSweep = quaternion([zeros(numel(eulerSweep),2),eulerSweep], ...
    'eulerd','ZYX','frame');

Преобразование q0, q90, и qSweep в матрицы поворота. В цикле вычислите метрику, чтобы минимизировать для каждого представителя кватерниона. Постройте график результатов и верните значение сдвига Эйлера, которое соответствует минимуму метрики.

r0     = rotmat(q0,'frame');
r90    = rotmat(q90,'frame');
rSweep = rotmat(qSweep,'frame');

metricToMinimize = zeros(size(rSweep,3),1);
for i = 1:numel(qSweep)
    metricToMinimize(i) = norm((rSweep(:,:,i) - r0),'fro').^2 + ...
                          norm((rSweep(:,:,i) - r90),'fro').^2;
end

plot(eulerSweep,metricToMinimize)
xlabel('Euler Sweep (degrees)')
ylabel('Metric to Minimize')

Figure contains an axes. The axes contains an object of type line.

[~,eulerIndex] = min(metricToMinimize);
eulerSweep(eulerIndex)
ans = 45

Минимум метрики соответствует углу Эйлера свип на 45 степенях. То есть meanrot определяет среднее значение между quaterion([0 0 0],'ZYX','frame') и quaternion([0 0 90],'ZYX','frame') как quaternion([0 0 45],'ZYX','frame'). Функции meanrot с q0 и q90 для проверки того же результата.

eulerd(meanrot([q0,q90]),'ZYX','frame')
ans = 1×3

         0         0   45.0000

Ограничения

Метрика, которая meanrot использует, чтобы определить среднее вращение не уникально для кватернионов значительно далеко друг от друга. Повторите эксперимент выше для кватернионов, которые разделены на 180 степени.

q180 = quaternion([0 0 180],'eulerd','ZYX','frame');
r180 = rotmat(q180,'frame');

for i = 1:numel(qSweep)
    metricToMinimize(i) = norm((rSweep(:,:,i) - r0),'fro').^2 + ...
                          norm((rSweep(:,:,i) - r180),'fro').^2;
end

plot(eulerSweep,metricToMinimize)
xlabel('Euler Sweep (degrees)')
ylabel('Metric to Minimize')

Figure contains an axes. The axes contains an object of type line.

[~,eulerIndex] = min(metricToMinimize);
eulerSweep(eulerIndex)
ans = 159

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

qMean = slerp(q0,q180,0.5);
q0_q180 = eulerd(qMean,'ZYX','frame')
q0_q180 = 1×3

         0         0   90.0000

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

свернуть все

Кватернион, для которого можно вычислить среднее значение, заданное в виде скаляра, вектора, матрицы или многомерного массива кватернионов.

Типы данных: quaternion

Размерность для работы, заданная как положительный целочисленный скаляр Если значение не задано, то по умолчанию это первое измерение массива, не равный 1.

Размерность dim указывает размерность, длина которого уменьшается до 1. The size(quatAverage,dim) является 1, в то время как размеры всех других размерностей остаются неизменными.

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

NaN условие, заданное как одно из следующих значений:

  • 'includenan' -- Включить NaN значения при вычислении среднего поворота, что приводит к NaN.

  • 'omitnan' -- Игнорировать все NaN значений во входе.

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

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

свернуть все

Среднее вращение Кватерниона, возвращаемое в виде скаляра, вектора, матрицы или многомерного массива.

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

Алгоритмы

meanrot определяет среднее значение кватерниона, q¯, согласно [1]. q¯ - кватернион, который минимизирует квадратную норму Фробениуса различия между матрицами поворота:

q¯=argminqS3i=1nA(q)A(qi)F2

Ссылки

[1] Маркли, Ф. Лэндис, Ян Чен, Джон Лукас Крассидис и Яаков Ошман. «Средние кватернионы». Журнал руководства, управления и динамики. Том 30, Выпуск 4, 2007, стр. 1193-1197.

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

Генерация кода C/C + +
Сгенерируйте код C и C++ с помощью Coder™ MATLAB ®

.
Введенный в R2019b