1 votos

Quaternion a ángulos de Euler

Quiero poder convertir entre euler y cuaterniones. He probado muchos enfoques diferentes, pero ninguno me permite convertir de euler a cuaternión y viceversa. La fórmula más prometedora se presentó aquí: ¿Cómo convertir ángulos de Euler a cuaterniones y obtener los mismos ángulos de Euler de vuelta de los cuaterniones?.
Sin embargo, todavía no me da una solución completa a mi problema. Funciona al convertir de euler a cuaternión y de nuevo del mismo cuaternión a euler, pero cuando creo un cuaternión a partir de un ángulo de eje usando esta ecuación:

qx = ax * sin(angle/2)
qy = ay * sin(angle/2)
qz = az * sin(angle/2)
qw = cos(angle/2)

y lo convierto en ángulos de euler obtengo resultados completamente incorrectos.

Supongamos que tengo 3 vectores: $a, b$ y $r$
$a = [1, 2, 3]$
$r = [\pi/2, \pi/4, \pi/2]$
$b = a$ rotado por $r = [3.0, 2.12, 0.7]$

Calculo el eje de la rotación usando el producto cruz de $a$ y $b$
Ahora calculo el ángulo entre los vectores usando el producto punto
Calculo el cuaternión a partir del eje y el ángulo usando la fórmula anterior
$$q = [0.91, -0.19, 0.32, -0.15]$$ Cuando convierto q a ángulos de euler usando el código del enlace anterior obtengo $$[-28.42, 32.25, -32.29]$$ Al girar mi vector $[1, 2, 3]$ con esos ángulos no da el mismo resultado que girándolo con r, por lo que la conversión no está funcionando correctamente.
Sin embargo, al girar $[1, 2, 3]$ con el cuaternión $q$ me da el mismo resultado que girándolo con los ángulos $q$, por lo que la conversión debe estar mal.

Por otro lado, convertir $r$ a cuaternión y de vuelta usando el código del enlace me da los ángulos correctos, ¿entonces dónde está el problema con esas fórmulas?
Quiero poder calcular $q$ y $r$ sabiendo solo $a$ y $b$.

3 votos

Mientras es muy probable que haya un problema matemático sobre la conversión entre representaciones, la formulación como código Java pone un enfoque en la depuración de software. Si no era tu intención, por favor edita el cuerpo de la pregunta para proporcionar contexto del problema matemático con el que buscas ayuda.

1 votos

¿No es un problema que los cuaterniones no se hayan convertido en cuaterniones unitarios en cierto paso?

1voto

rschwieb Puntos 60669

Creo que lo máximo que podemos esperar hacer aquí en math.se es determinar cuál, de hecho, es el cuaternión correcto para la representación de ángulos de Euler. Si hay algún error en el código, tendrás que llevar esa pregunta a un stackexchange de programación.

Pero en cuanto a la parte matemática de esta tarea:

Interpreté $r = [pi/2, pi/4, pi/2]$ como "rotar por $\pi/2$ en el eje x, luego por $\pi/4$ en el eje $y$, luego por $\pi/2$ en el eje $z$."

Usando la teoría involucrada en la conversión de ángulo de eje a cuaterniones, se pueden convertir esos tres fácilmente como $\cos(\theta/2)+\sin(\theta/2)u$ donde $u$ es el vector unitario que apunta a lo largo del eje de rotación.

Usé la librería numpy-quaternion en python para verificar que estos fueran correctos:

>>> x
quaternion(0.707106781186548, 0.707106781186547, 0, 0)
>>> y
quaternion(0.923879532511287, 0, 0.38268343236509, 0)
>>> z
quaternion(0.707106781186548, 0, 0, 0.707106781186547)
>>> q=z*y*x
>>> q*a*q.inverse()
quaternion(-4.44089209850063e-16, 3, 2.12132034355964, 0.707106781186548)

Dado que esa última parte (-4.44089209850063e-16, 3, 2.12132034355964, 0.707106781186548) coincide con lo que reportaste, supongo que estoy en el camino correcto. (Realmente debería ser $(0, 3,3/\sqrt{2},\sqrt{2}/2)$)

Pero

>>> q
quaternion(0.653281482438188, 0.270598050073099, 0.653281482438188, 0.270598050073098)

no coincide con tu predicción de cómo debería ser el cuaternión. El ángulo allí en la posición w es una clara señal de que algo no está bien. Dado que estás trabajando con el cuaternión incorrecto, naturalmente no obtendrás de vuelta tu representación de Euler correcta al aplicar el código de conversión.

Te dejo a ti trabajar en el error con la forma en que estás encontrando el cuaternión, y también puedes verificar si este cuaternión que te estoy dando se convierte exitosamente de vuelta usando tu librería.

La librería tiene una implementación de as_euler_angles y from_euler_angles pero creo que usa la convención z-y-z, por lo que no nos ayudará si estás usando la convención x-y-z.


¿Cómo calcularías q sabiendo solo los vectores a y b?

¡Hay un par de formas de hacerlo! ¡Ninguna será con ángulos de Euler, eso seguro!

Me gustaría también enfatizar aquí que no hay un cuaternión único que rote $a$ a $b$. Después de encontrar un cuaternión que lo haga, puedes agregar una rotación alrededor del eje determinado por $b$, y obtienes otra solución.

Aquí hay una forma cercana a lo que estabas intentando, creo, que aprovecha el hecho de que la multiplicación de cuaterniones calcula los productos punto y cruz por ti:

  1. Normaliza $a$ y $b$.
  2. Representa $a$ y $b$ como cuaterniones con parte real cero.
  3. Calcula $ab=\alpha +\beta u$ donde $\alpha,\beta$ son reales y $u$ es un cuaternión de longitud unitaria con parte real cero.
  4. Se sabe que $\alpha=-\cos(\theta)$ y $\beta=\sin(\theta)$ donde $\theta$ es el ángulo entre $a$ y $b$, y $u$ es el normal unitario.
  5. Usa las identidades de medio ángulo para escribir $\cos(\theta/2)+\sin(\theta/2)u$

Una segunda forma, más en el programa de trabajar con cuaterniones, es anticipar que necesitas $\theta/2$, y observar que (¡después de normalizar $a$ y $b$!) el ángulo entre $a$ y $a+b$ es la mitad del ángulo entre $a$ y $b$. Explícitamente:

  1. Normaliza $a$ y $b$.
  2. Calcula $a+b$ y normalízalo. Esa es tu rotación de cuaternión.

Ilustraré el Método #2 ya que es más simple:

>>> q2 = (a.normalized()+b.normalized()).normalized()
>>> q2
quaternion(-6.49653805396711e-17, 0.58515612718089, 0.602903962777294, 0.542309061781284)
>>> q2*a*q2.inverse()
quaternion(-1.11022302462516e-16, 3, 2.12132034355964, 0.707106781186548)

Observa que este segundo cuaternión es sustancialmente diferente al primero que calculamos, con un eje y ángulo diferentes.


Epílogo

Quienquiera que haya escrito la documentación para numpy-quaternion es mi tipo de persona:

Ayuda en la función as_euler_angles en el módulo quaternion:

as_euler_angles(q)
    Abrir la caja de Pandora

    Si alguien intenta hacerte usar ángulos de Euler, dile que no, y
    aléjate, y ve y dile a tu mamá.

    No querrás usar ángulos de Euler. Son terribles. Mantente alejado. Es
    una cosa convertir de ángulos de Euler a cuaterniones; al menos vas en
    la dirección correcta. ¡Pero ir en la dirección opuesta?! Simplemente no
    es correcto.

[...]
 NOTA: Antes de abrir un problema reportando algo "incorrecto" con esta
    función, asegúrate de leer todo lo siguiente, *especialmente* la
    última sección sobre abrir problemas o solicitudes de extracción.

[...]

    Levanta
    ------
    TodoElInfierno
        ...si intentas realmente usar ángulos de Euler, cuando podrías haber
        estado usando cuaterniones como una persona sensata.
(END)

0 votos

Gracias por la respuesta. Soy consciente de que el cuaternión q no es correcto. El punto es que soy capaz de convertir ángulos de Euler a cuaterniones correctamente, pero no puedo obtener un cuaternión correcto a partir del ángulo del eje usando la fórmula qx=... (sabiendo solo a y b), así que me pregunto si esta fórmula es incorrecta o si la estoy utilizando mal. ¿Cómo calcularías q sabiendo solo los vectores a y b?

1 votos

@Jakub Agregué un método que sigue el camino que sugeriste, e incluí también el método (que creo que es el mejor) para encontrar un cuaternio que rota $a$ sobre $b$.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X