Этот пример рассматривает концепции в 3D вращениях и как кватернионы используются, чтобы описать ориентацию и вращения. Кватернионы являются скошенным полем гиперкомплексных чисел. Они нашли применение в космосе, компьютерной графике и виртуальной реальности. В MATLAB® математика кватерниона может быть представлена путем управления классом quaternion
.
Класс HelperDrawRotation
используется, чтобы проиллюстрировать несколько фрагментов этого примера.
dr = HelperDrawRotation;
Все вращения в 3-D могут быть заданы осью вращения и углом вращения вокруг той оси. Рассмотрите 3-D изображение заварного чайника в крайнем левом графике. Заварной чайник вращается 45 градусами вокруг оси Z во втором графике. Более комплексное вращение 15 градусов вокруг оси [1 0 1] показывают в третьем графике. Кватернионы инкапсулируют ось и угол вращения и имеют алгебру для управления этими вращениями. Класс quaternion
и этот пример, используют соглашение "правила правой руки" задать вращения. Таким образом, положительные вращения по часовой стрелке вокруг оси вращения, когда просматривается от источника.
dr.drawTeapotRotations;
Вершины заварного чайника вращались об оси вращения в ссылочном кадре. Рассмотрите вопрос (0.7, 0.5) вращал 30 градусов об оси Z.
figure; dr.draw2DPointRotation(gca);
Вращение кадра, в некотором смысле, противоположности вращения точки. Во вращении кадра вращаются точки объектного зафиксированного пребывания, но система отсчета. Снова, рассмотрите вопрос (0.7, 0.5). Теперь ссылочный кадр вращается 30 градусами вокруг оси Z. Обратите внимание на то, что, в то время как точка (0.7, 0.5) остается фиксированной, она имеет различные координаты в новой, вращаемой системе отсчета.
figure; dr.draw2DFrameRotation(gca);
Ориентация относится к угловому смещению объекта относительно системы отсчета. Как правило, ориентация описана вращением, которое вызывает это угловое смещение от стартовой ориентации. В Sensor Fusion and Tracking Toolbox™ ориентация задана как вращение, которое берет количество в родительском ссылочном кадре к дочернему ссылочному кадру. Ориентация обычно дается как кватернион, матрица вращения, набор Углов Эйлера или вектор вращения. Полезно думать об ориентации как вращение кадра: дочерний ссылочный кадр вращается относительно родительского кадра.
Рассмотрите пример, где дочерний ссылочный кадр вращается 30 градусов вокруг вектора [1/3 2/3 2/3].
figure; dr.draw3DOrientation(gca, [1/3 2/3 2/3], 30);
Кватернионы являются количествами формы
где
и и вещественные числа. В остальной части этого примера, этих четырех чисел и упоминаются как части кватерниона.
Ось и угол вращения инкапсулируются в частях кватерниона. Для оси единичного вектора вращения [x, y, z], и угол поворота, кватернион, описывающий это вращение,
Обратите внимание на то, что, чтобы описать вращение с помощью кватерниона, кватернион должен быть модульным кватернионом. Модульный кватернион имеет норму 1, где норма задана как
Существует множество способов создать кватернион в MATLAB, например:
q1 = quaternion(1,2,3,4)
q1 = quaternion 1 + 2i + 3j + 4k
Массивы кватернионов могут быть сделаны таким же образом:
quaternion([1 10; -1 1], [2 20; -2 2], [3 30; -3 3], [4 40; -4 4])
ans = 2x2 quaternion array 1 + 2i + 3j + 4k 10 + 20i + 30j + 40k -1 - 2i - 3j - 4k 1 + 2i + 3j + 4k
Массивы с четырьмя столбцами могут также использоваться, чтобы создать кватернионы с каждым столбцом, представляющим часть кватерниона:
qmgk = quaternion(magic(4))
qmgk = 4x1 quaternion array 16 + 2i + 3j + 13k 5 + 11i + 10j + 8k 9 + 7i + 6j + 12k 4 + 14i + 15j + 1k
Кватернионы могут индексироваться и управляться точно так же, как любой другой массив:
qmgk(3)
ans = quaternion 9 + 7i + 6j + 12k
reshape(qmgk,2,2)
ans = 2x2 quaternion array 16 + 2i + 3j + 13k 9 + 7i + 6j + 12k 5 + 11i + 10j + 8k 4 + 14i + 15j + 1k
[q1; q1]
ans = 2x1 quaternion array 1 + 2i + 3j + 4k 1 + 2i + 3j + 4k
Кватернионы начинают четко определенные арифметические операции. Сложение и вычитание подобны комплексным числам: части добавляются/вычитаются независимо. Умножение более сложно из-за более раннего уравнения:
Это означает, что умножение кватернионов не является коммутативным. Таким образом, для кватернионов и. Однако каждый кватернион имеет мультипликативную инверсию, таким образом, кватернионы могут быть разделены. Массивы класса quaternion
могут быть добавлены, вычтены, умножены и разделены на MATLAB.
q = quaternion(1,2,3,4); p = quaternion(-5,6,-7,8);
Сложение
p + q
ans = quaternion -4 + 8i - 4j + 12k
Вычитание
p - q
ans = quaternion -6 + 4i - 10j + 4k
Умножение
p*q
ans = quaternion -28 - 56i - 30j + 20k
Умножение в обратном порядке (отмечают различный результат),
q*p
ans = quaternion -28 + 48i - 14j - 44k
Правильное деление p
q
эквивалентно.
p./q
ans = quaternion 0.6 + 2.2667i + 0.53333j - 0.13333k
Покинутое деление q
p
эквивалентно.
p.\q
ans = quaternion 0.10345 + 0.2069i + 0j - 0.34483k
Сопряженный из кватерниона формируется путем отрицания каждой из недействительных частей, подобных спряжению для комплексного числа:
conj(p)
ans = quaternion -5 - 6i + 7j - 8k
Кватернионы могут быть нормированы в MATLAB:
pnormed = normalize(p)
pnormed = quaternion -0.37905 + 0.45486i - 0.53067j + 0.60648k
norm(pnormed)
ans = 1
Кватернионы могут использоваться, чтобы вращать точки в статической системе отсчета или вращать саму систему отсчета. Функция rotatepoint
вращает точку с помощью кватерниона q посредством следующего уравнения:
где
и указывает на спряжение кватерниона. Отметьте вышеупомянутые результаты умножения кватерниона в кватернионе с действительной частью, равной 0., и части результата формируют вращаемую точку ().
Рассмотрите пример вращения точки сверху. Точка (0.7, 0.5) вращалась 30 градусов вокруг оси Z. В трех измерениях эта точка имеет 0 Z-координат. Используя формулировку угла оси, кватернион может быть создан с помощью [0 0 1] как ось вращения.
ang = deg2rad(30);
q = quaternion(cos(ang/2), 0, 0, sin(ang/2));
pt = [0.7, 0.5, 0]; % Z-coordinate is 0 in the X-Y plane
ptrot = rotatepoint(q, pt)
ptrot = 0.3562 0.7830 0
Точно так же функция rotateframe
берет кватернион и точку, чтобы вычислить
Снова вышеупомянутое умножение кватерниона приводит к кватерниону с 0 действительными частями., части результата формируют координату точки в новом, вращали ссылочный кадр. Используя класс quaternion
:
ptframerot = rotateframe(q, pt)
ptframerot = 0.8562 0.0830 0
Кватернион и его сопряженное имеют противоположные эффекты из-за симметрии в точке и структурируют уравнения вращения. Вращение сопряженными "отменами" вращение.
rotateframe(conj(q), ptframerot)
ans = 0.7000 0.5000 0
Из-за симметрии уравнений этот код выполняет то же вращение.
rotatepoint(q, ptframerot)
ans = 0.7000 0.5000 0
Часто вращения и ориентации описаны с помощью альтернативных средних значений: Углы Эйлера, матрицы вращения и/или векторы вращения. Все они взаимодействуют с кватернионами в MATLAB.
Углы Эйлера часто используются, потому что их легко интерпретировать. Считайте систему отсчета вращаемой 30 градусами вокруг оси Z, затем 20 градусами вокруг Оси Y, и затем-50 градусами вокруг Оси X. Отметьте здесь, и повсюду, вращения вокруг каждой оси являются внутренними: каждое последующее вращение вокруг недавно созданного набора осей. Другими словами, второе вращение вокруг "новой" Оси Y, созданной первым вращением, не вокруг исходной Оси Y.
figure; euld = [30 20 -50]; dr.drawEulerRotation(gca, euld);
Чтобы создать кватернион из этих Углов Эйлера в целях вращения кадра, используйте конструктора quaternion
. Поскольку порядок вращений вокруг оси Z сначала, затем вокруг новой Оси Y, и наконец вокруг новой Оси X, используйте флаг 'ZYX'
.
qeul = quaternion(deg2rad(euld), 'euler', 'ZYX', 'frame')
qeul = quaternion 0.84313 - 0.44275i + 0.044296j + 0.30189k
Флаг 'euler'
указывает, что первый аргумент исчисляется в радианах. Если аргумент в градусах, используйте флаг 'eulerd'
.
qeuld = quaternion(euld, 'eulerd', 'ZYX', 'frame')
qeuld = quaternion 0.84313 - 0.44275i + 0.044296j + 0.30189k
Преобразовывать назад в Углы Эйлера:
rad2deg(euler(qeul, 'ZYX', 'frame'))
ans = 30.0000 20.0000 -50.0000
Эквивалентно, метод eulerd
может использоваться.
eulerd(qeul, 'ZYX', 'frame')
ans = 30.0000 20.0000 -50.0000
Также это то же вращение может быть представлено как матрица вращения:
rmat = rotmat(qeul, 'frame')
rmat = 0.8138 0.4698 -0.3420 -0.5483 0.4257 -0.7198 -0.1926 0.7733 0.6040
Преобразование назад в кватернионы подобно:
quaternion(rmat, 'rotmat', 'frame')
ans = quaternion 0.84313 - 0.44275i + 0.044296j + 0.30189k
Так же, как кватернион может использоваться или для точки или для вращения кадра, это может быть преобразовано в матрицу вращения (или набор Углов Эйлера) специально для вращения кадра или точки. Матрица вращения для вращения точки является транспонированием матрицы для вращения кадра. Чтобы преобразовать между представлениями вращения, необходимо задать 'point'
или 'frame'
.
Матрица вращения для раздела вращения точки этого примера:
rotmatPoint = rotmat(q, 'point')
rotmatPoint = 0.8660 -0.5000 0 0.5000 0.8660 0 0 0 1.0000
Чтобы найти местоположение вращаемой точки, право - умножает rotmatPoint
на транспонированный массив pt
.
rotmatPoint * (pt')
ans = 0.3562 0.7830 0
Матрица вращения для раздела вращения кадра этого примера:
rotmatFrame = rotmat(q, 'frame')
rotmatFrame = 0.8660 0.5000 0 -0.5000 0.8660 0 0 0 1.0000
Чтобы найти местоположение точки во вращаемом ссылочном кадре, право - умножает rotmatFrame
на транспонированный массив pt
.
rotmatFrame * (pt')
ans = 0.8562 0.0830 0
Вектор вращения является альтернативной, компактной инкапсуляцией вращения. Вектор вращения является просто трехэлементным вектором, который представляет ось единичной длины вращения, увеличенного углом вращения в радианах. Нет никакого мыса кадра или мыса точки, сопоставленного с вектором вращения. Преобразовывать в вектор вращения:
rv = rotvec(qeul)
rv = -0.9349 0.0935 0.6375
Преобразовывать в кватернион:
quaternion(rv, 'rotvec')
ans = quaternion 0.84313 - 0.44275i + 0.044296j + 0.30189k
Одним преимуществом кватернионов по Углам Эйлера является отсутствие разрывов. Углы Эйлера имеют разрывы, которые отличаются в зависимости от используемого соглашения. Функция dist
сравнивает эффект вращения двумя различными кватернионами. Результатом является номер в области значений 0 к pi
. Считайте два кватерниона созданными из Углов Эйлера:
eul1 = [0, 10, 0]; eul2 = [0, 15, 0]; qdist1 = quaternion(deg2rad(eul1), 'euler', 'ZYX', 'frame'); qdist2 = quaternion(deg2rad(eul2), 'euler', 'ZYX', 'frame');
Вычитая Углы Эйлера, вы видите, что нет никакого вращения вокруг оси Z или Оси X.
eul2 - eul1
ans = 0 5 0
Различием между этими двумя вращениями являются пять градусов вокруг Оси Y. dist
показывает различие также.
rad2deg(dist(qdist1, qdist2))
ans = 5.0000
Для Углов Эйлера, таких как eul1
и eul2
, вычисляя угловое расстояние тривиально. Более комплексный пример, который охватывает разрыв Угла Эйлера:
eul3 = [0, 89, 0]; eul4 = [180, 89, 180]; qdist3 = quaternion(deg2rad(eul3), 'euler', 'ZYX', 'frame'); qdist4 = quaternion(deg2rad(eul4), 'euler', 'ZYX', 'frame');
Хотя eul3
и eul4
представляют почти ту же ориентацию, простое вычитание Угла Эйлера производит впечатление, которое эти две ориентации очень далеко друг от друга.
euldiff = eul4 - eul3
euldiff = 180 0 180
Используя функцию dist
на кватернионах показывает, что существует только различие 2D степени в этих вращениях:
euldist = rad2deg(dist(qdist3, qdist4))
euldist = 2.0000
Кватернион и его отрицание представляют то же вращение. Это не очевидно из вычитания кватернионов, но функция dist
проясняет.
qpos = quaternion(-cos(pi/4), 0 ,0, sin(pi/4))
qpos = quaternion -0.70711 + 0i + 0j + 0.70711k
qneg = -qpos
qneg = quaternion 0.70711 + 0i + 0j - 0.70711k
qdiff = qpos - qneg
qdiff = quaternion -1.4142 + 0i + 0j + 1.4142k
dist(qpos, qneg)
ans = 0
Класс quaternion
позволяет вам эффективно описать вращения и ориентации в MATLAB. Полный список поддержанных кватернионом функций может быть найден с функцией methods
:
methods('quaternion')
Methods for class quaternion: cat ismatrix power classUnderlying isnan prod compact isrow quaternion conj isscalar rdivide ctranspose isvector reshape disp ldivide rotateframe dist length rotatepoint double log rotmat eq meanrot rotvec euler minus rotvecd eulerd mtimes single exp ndims size horzcat ne slerp iscolumn norm times isempty normalize transpose isequal numel uminus isequaln parts validateattributes isfinite permute vertcat isinf plus Static methods: ones zeros