Main Content

Esta página se ha traducido mediante traducción automática. Haga clic aquí para ver la última versión en inglés.

Rotaciones, orientación y cuaterniones

Este ejemplo revisa conceptos de rotaciones tridimensionales y cómo se utilizan los cuaterniones para describir la orientación y las rotaciones. Los cuaterniones son un campo sesgado de números hipercomplejos. Han encontrado aplicaciones en la industria aeroespacial, gráficos por computadora y realidad virtual. En MATLAB®, las matemáticas de cuaterniones se pueden representar manipulando la clase quaternion .

La clase HelperDrawRotation se utiliza para ilustrar varias partes de este ejemplo.

dr = HelperDrawRotation;

Rotaciones en tres dimensiones

Todas las rotaciones en 3-D se pueden definir mediante un eje de rotación y un ángulo de rotación alrededor de ese eje. Considere la imagen tridimensional de una tetera en el gráfico más a la izquierda. La tetera se gira 45 grados alrededor del eje Z en el segundo gráfico. En el tercer gráfico se muestra una rotación más compleja de 15 grados alrededor del eje [1 0 1]. Los cuaterniones encapsulan el eje y el ángulo de rotación y tienen un álgebra para manipular estas rotaciones. La clase quaternion y este ejemplo utilizan la convención de "regla de la mano derecha" para definir rotaciones. Es decir, las rotaciones positivas son en el sentido de las agujas del reloj alrededor del eje de rotación cuando se ven desde el origen.

dr.drawTeapotRotations;

Rotación de puntos

Los vértices de la tetera se rotaron alrededor del eje de rotación en el sistema de referencia. Considere un punto (0,7, 0,5) girado 30 grados alrededor del eje Z.

figure;
dr.draw2DPointRotation(gca);

Rotación de marco

La rotación de cuadros es, en cierto sentido, lo opuesto a la rotación de puntos. En la rotación de marco, los puntos del objeto permanecen fijos, pero el marco de referencia gira. De nuevo, considere el punto (0,7, 0,5). Ahora el marco de referencia se gira 30 grados alrededor del eje Z. Tenga en cuenta que si bien el punto (0,7, 0,5) permanece fijo, tiene coordenadas diferentes en el nuevo marco de referencia rotado.

figure;
dr.draw2DFrameRotation(gca);

Orientación

La orientación se refiere al desplazamiento angular de un objeto con respecto a un marco de referencia. Normalmente, la orientación se describe mediante la rotación que provoca este desplazamiento angular desde una orientación inicial. En este ejemplo, la orientación se define como la rotación que lleva una cantidad en un sistema de referencia principal a un sistema de referencia secundario. La orientación suele darse como un cuaternión, una matriz de rotación, un conjunto de ángulos de Euler o un vector de rotación. Es útil pensar en la orientación como una rotación del marco: el marco de referencia secundario se gira en relación con el marco principal.

Considere un ejemplo en el que el sistema de referencia secundario se gira 30 grados alrededor del vector [1/3 2/3 2/3].

figure;
dr.draw3DOrientation(gca, [1/3 2/3 2/3], 30);

Cuaterniones

Los cuaterniones son números de la forma

dónde

y y son números reales. En el resto de este ejemplo, los cuatro números y se denominan "partes" del cuaternión.

Cuaterniones para rotaciones y orientación.

El eje y el ángulo de rotación están encapsulados en las partes del cuaternión. Para un eje de rotación de vector unitario [ x, y, z] y un ángulo de rotación , el cuaternión que describe esta rotación es

Tenga en cuenta que para describir una rotación utilizando un cuaternión, el cuaternión debe ser un cuaternión unitario. Un cuaternión unitario tiene una norma de 1, donde la norma se define como

Hay varias formas de construir un cuaternión en MATLAB, por ejemplo:

q1 = quaternion(1,2,3,4)
q1 = 

  quaternion


     1 + 2i + 3j + 4k

Los arreglos de cuaterniones se pueden hacer de la misma manera:

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

También se pueden usar arreglos con cuatro columnas para construir cuaterniones, donde cada columna representa una parte de cuaternión:

qmgk = quaternion(magic(4))
qmgk = 

  4x1 quaternion array


     16 +  2i +  3j + 13k
      5 + 11i + 10j +  8k
      9 +  7i +  6j + 12k
      4 + 14i + 15j +  1k

Los cuaterniones se pueden indexar y manipular como cualquier otra arreglo:

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

Matemáticas del cuaternión

Los cuaterniones tienen operaciones aritméticas bien definidas. La suma y la resta son similares a los números complejos: las partes se suman y restan de forma independiente. La multiplicación es más complicada debido a la ecuación anterior:

Esto significa que la multiplicación de cuaterniones no es conmutativa. Es decir, para cuaterniones y . Sin embargo, cada cuaternión tiene un inverso multiplicativo, por lo que los cuaterniones se pueden dividir. Los arreglos de la clase quaternion se pueden sumar, restar, multiplicar y dividir en MATLAB.

q = quaternion(1,2,3,4);
p = quaternion(-5,6,-7,8);

Suma

p + q
ans = 

  quaternion


     -4 +  8i -  4j + 12k

Sustracción

p - q
ans = 

  quaternion


     -6 +  4i - 10j +  4k

Multiplicación

p*q
ans = 

  quaternion


    -28 - 56i - 30j + 20k

Multiplicación en orden inverso (tenga en cuenta el resultado diferente)

q*p
ans = 

  quaternion


    -28 + 48i - 14j - 44k

La división derecha de p por q equivale a .

p./q
ans = 

  quaternion


         0.6 +  2.2667i + 0.53333j - 0.13333k

La división izquierda de q por p equivale a .

p.\q
ans = 

  quaternion


     0.10345 +  0.2069i +       0j - 0.34483k

El conjugado de un cuaternión se forma negando cada una de las partes no reales, similar a la conjugación de un número complejo:

conj(p)
ans = 

  quaternion


    -5 - 6i + 7j - 8k

Los cuaterniones se pueden normalizar en MATLAB:

pnormed = normalize(p)
pnormed = 

  quaternion


    -0.37905 + 0.45486i - 0.53067j + 0.60648k

norm(pnormed)
ans =

     1

Rotaciones de puntos y cuadros con cuaterniones

Los cuaterniones se pueden utilizar para rotar puntos en un marco de referencia estático o para rotar el propio marco de referencia. La función rotatepoint rota un punto usando un cuaternión mediante la siguiente ecuación:

donde es

y indica conjugación de cuaterniones. Tenga en cuenta que la multiplicación de cuaterniones anterior da como resultado un cuaternión con la parte real, , igual a 0. Las , y del resultado forman el punto rotado (, , ).

Considere el ejemplo de rotación de puntos desde arriba. El punto (0,7, 0,5) se giró 30 grados alrededor del eje Z. En tres dimensiones este punto tiene una coordenada Z 0. Usando la formulación eje-ángulo, se puede construir un cuaternión usando [0 0 1] como eje de rotación.

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

De manera similar, la función rotateframe toma un cuaternión y el punto para calcular

Nuevamente, la multiplicación de cuaterniones anterior da como resultado un cuaternión con 0 parte real. Las (, , ) partes del resultado forman la coordenada del punto en el nuevo marco de referencia rotado. Usando la clase quaternion :

ptframerot = rotateframe(q, pt)
ptframerot =

    0.8562    0.0830         0

Un cuaternión y su conjugado tienen efectos opuestos debido a la simetría en las ecuaciones de rotación de puntos y marcos. Girar por el conjugado "deshace" la rotación.

rotateframe(conj(q), ptframerot)
ans =

    0.7000    0.5000         0

Debido a la simetría de las ecuaciones, este código realiza la misma rotación.

rotatepoint(q, ptframerot)
ans =

    0.7000    0.5000         0

Otras representaciones de rotación

A menudo, las rotaciones y orientaciones se describen utilizando medios alternativos: Ángulos de Euler, matrices de rotación y/o vectores de rotación. Todos estos interoperan con cuaterniones en MATLAB.

Los ángulos de Euler se utilizan con frecuencia porque son fáciles de interpretar. Considere un marco de referencia girado 30 grados alrededor del eje Z, luego 20 grados alrededor del eje Y y luego -50 grados alrededor del eje X. Tenga en cuenta que aquí, y en todo momento, las rotaciones alrededor de cada eje son intrínsecas: cada rotación posterior se realiza alrededor del conjunto de ejes recién creado. En otras palabras, la segunda rotación es alrededor del "nuevo" eje Y creado por la primera rotación, no alrededor del eje Y original.

figure;
euld = [30 20 -50];
dr.drawEulerRotation(gca, euld);

Para construir un cuaternión a partir de estos ángulos de Euler con el fin de rotar el marco, use el constructor quaternion . Dado que el orden de las rotaciones es primero alrededor del eje Z, luego alrededor del nuevo eje Y y finalmente alrededor del nuevo eje X, use el indicador 'ZYX' .

qeul = quaternion(deg2rad(euld), 'euler', 'ZYX', 'frame')
qeul = 

  quaternion


      0.84313 -  0.44275i + 0.044296j +  0.30189k

El indicador 'euler' indica que el primer argumento está en radianes. Si el argumento está en grados, utilice el indicador 'eulerd' .

qeuld = quaternion(euld, 'eulerd', 'ZYX', 'frame')
qeuld = 

  quaternion


      0.84313 -  0.44275i + 0.044296j +  0.30189k

Para volver a convertir a ángulos de Euler:

rad2deg(euler(qeul, 'ZYX', 'frame'))
ans =

   30.0000   20.0000  -50.0000

De manera equivalente, se puede utilizar el método eulerd .

eulerd(qeul, 'ZYX', 'frame')
ans =

   30.0000   20.0000  -50.0000

Alternativamente, esta misma rotación se puede representar como una matriz de rotación:

rmat = rotmat(qeul, 'frame')
rmat =

    0.8138    0.4698   -0.3420
   -0.5483    0.4257   -0.7198
   -0.1926    0.7733    0.6040

La conversión a cuaterniones es similar:

quaternion(rmat, 'rotmat', 'frame')
ans = 

  quaternion


      0.84313 -  0.44275i + 0.044296j +  0.30189k

Así como un cuaternión se puede usar para rotación de punto o marco, se puede convertir en una matriz de rotación (o conjunto de ángulos de Euler) específicamente para rotación de punto o marco. La matriz de rotación para la rotación de puntos es la transpuesta de la matriz para la rotación de cuadros. Para convertir entre representaciones de rotación, es necesario especificar 'point' o 'frame'.

La matriz de rotación para la sección de rotación de puntos de este ejemplo es:

rotmatPoint = rotmat(q, 'point')
rotmatPoint =

    0.8660   -0.5000         0
    0.5000    0.8660         0
         0         0    1.0000

Para encontrar la ubicación del punto rotado, multiplique por la derecha rotmatPoint por el arreglo transpuesta pt.

rotmatPoint * (pt')
ans =

    0.3562
    0.7830
         0

La matriz de rotación para la sección de rotación del marco de este ejemplo es:

rotmatFrame = rotmat(q, 'frame')
rotmatFrame =

    0.8660    0.5000         0
   -0.5000    0.8660         0
         0         0    1.0000

Para encontrar la ubicación del punto en el marco de referencia rotado, multiplique a la derecha rotmatFrame por el arreglo transpuesta pt.

rotmatFrame * (pt')
ans =

    0.8562
    0.0830
         0

Un vector de rotación es una encapsulación de rotación compacta y alternativa. Un vector de rotación es simplemente un vector de tres elementos que representa el eje de rotación de longitud unitaria ampliado por el ángulo de rotación en radianes. No hay ningún marco ni punto asociado con un vector de rotación. Para convertir a un vector de rotación:

rv = rotvec(qeul)
rv =

   -0.9349    0.0935    0.6375

Para convertir a un cuaternión:

quaternion(rv, 'rotvec')
ans = 

  quaternion


      0.84313 -  0.44275i + 0.044296j +  0.30189k

Distancia

Una ventaja de los cuaterniones sobre los ángulos de Euler es la falta de discontinuidades. Los ángulos de Euler tienen discontinuidades que varían según la convención que se utilice. La función dist compara el efecto de rotación de dos cuaterniones diferentes. El resultado es un número en el rango de 0 a pi. Considere dos cuaterniones construidos a partir de ángulos de Euler:

eul1 = [0, 10, 0];
eul2 = [0, 15, 0];
qdist1 = quaternion(deg2rad(eul1), 'euler', 'ZYX', 'frame');
qdist2 = quaternion(deg2rad(eul2), 'euler', 'ZYX', 'frame');

Restando los ángulos de Euler, se puede ver que no hay rotación alrededor del eje Z o del eje X.

eul2 - eul1
ans =

     0     5     0

La diferencia entre estas dos rotaciones es de cinco grados alrededor del eje Y. El dist también muestra la diferencia.

rad2deg(dist(qdist1, qdist2))
ans =

    5.0000

Para ángulos de Euler como eul1 y eul2, calcular la distancia angular es trivial. Un ejemplo más complejo, que abarca una discontinuidad del ángulo de Euler, es:

eul3 = [0, 89, 0];
eul4 = [180, 89, 180];
qdist3 = quaternion(deg2rad(eul3), 'euler', 'ZYX', 'frame');
qdist4 = quaternion(deg2rad(eul4), 'euler', 'ZYX', 'frame');

Aunque eul3 y eul4 representan casi la misma orientación, la simple resta de ángulos de Euler da la impresión de que estas dos orientaciones están muy separadas.

euldiff = eul4 - eul3
euldiff =

   180     0   180

El uso de la función dist en los cuaterniones muestra que solo hay una diferencia de dos grados en estas rotaciones:

euldist = rad2deg(dist(qdist3, qdist4))
euldist =

    2.0000

Un cuaternión y su negativo representan la misma rotación. Esto no es obvio al restar cuaterniones, pero la función dist lo deja claro.

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

Funciones admitidas

La clase quaternion le permite describir efectivamente rotaciones y orientaciones en MATLAB. La lista completa de funciones compatibles con cuaterniones se puede encontrar con la función methods :

methods('quaternion')
Methods for class quaternion:

angvel              ismatrix            prod                
cat                 isnan               quaternion          
classUnderlying     isrow               rdivide             
compact             isscalar            reshape             
conj                isvector            rotateframe         
ctranspose          ldivide             rotatepoint         
disp                length              rotmat              
dist                log                 rotvec              
double              meanrot             rotvecd             
eq                  minus               single              
euler               mtimes              size                
eulerd              ndims               slerp               
exp                 ne                  times               
horzcat             norm                transpose           
iscolumn            normalize           uminus              
isempty             numel               underlyingType      
isequal             parts               validateattributes  
isequaln            permute             vertcat             
isfinite            plus                
isinf               power               

Static methods:

ones                zeros