Loading [MathJax]/jax/element/mml/optable/GeneralPunctuation.js

6 votos

Convertir de rotaciones de eje fijoXYZ a rotaciones de EulerZXZ

Porque soy un usuario nuevo, no puedo publicar imágenes, hipervínculos o links, hay una versión completa con imágenes aquí:

http://stackoverflow.com/questions/9774958/converting-from-a-euler-zxz-rotation-to-fixed-axis-xyz-rotations

El problema que tengo, es que necesito para convertir de XYZ eje fijo de rotación, a Euler rotaciones Z,, a continuación,X,, a continuación,Z.

Aquí los matricies:

X = \left(\begin{matrix} 1 & 0 & 0 \\ 0 & \cos(\theta) & -\sin(\theta) \\ 0 & \sin(\theta) & \cos(\theta)\end{matrix}\right)

Y = \left(\begin{matrix} \cos(\phi) & 0 & \sin(\phi) \\ 0 & 1 & 0 \\ -\sin(\phi) & 0 & \cos(\phi)\end{matrix}\right)

Z = \left(\begin{matrix} \cos(\psi) & -\sin(\psi) & 0 \\ \sin(\psi) & \cos(\psi) & 0 \\ 0 & 0 & 1\end{matrix}\right)

Combined, as R_z(\psi) R_y(\phi) R_x(\theta) = R_{xyz}(\theta,\phi\psi); they give:

R_{xyz}: i.imgur.com/8UQM6.jpg

And the Rotation matrix for the Specific convention of Euler angles I want; is this:

Euler: Euler

So my initial plan, was to compare matrix elements, and extract the angles I wanted that way; I came up with this (actual current code at the end):

But this doesn't work under several circumstances. The most obvious being when \cos(\theta)\cos(\phi) = 1; since then \cos(\beta) = 1, and so \sin(\beta) = 0. Where \sin(\beta) is s2 in the code. This happens only when \cos(\theta) and \cos(\phi) = \pm 1.

So right away I can just rule out the possible situations;

When \theta or \phi = 0, 180, 360, 540, \ldots, then \cos(\theta), and \cos(\phi) are \pm 1;

so I only need to do it differently for these cases;

And I ended up with this code:

public static double[] ZXZtoEuler(double θ, double φ, double ψ){

    θ *= Math.PI/180.0;
    φ *= Math.PI/180.0;
    ψ *= Math.PI/180.0;

    double α = -1;
    double β = -1;
    double γ = -1;

    double c2 = Math.cos(θ) * Math.cos(φ);

    β = Math.acos(r(c2));

    if(eq(c2,1) || eq(c2,-1)){
        if(eq(Math.cos(θ),1)){
            if(eq(Math.cos(φ),1)){
                α = 0.0;
                γ = ψ;
            }else if(eq(Math.cos(φ),-1)){
                α = 0.0;
                γ = Math.PI - ψ;
            }
        }else if(eq(Math.cos(θ),-1)){
            if(eq(Math.cos(φ),1)){
                α = 0.0;
                γ = -ψ;
            }else if(eq(Math.cos(φ),-1)){
                α = 0.0;
                γ = ψ + Math.PI;
            }
        }
    }else{

        //original way

        double s2 = Math.sin(β);

        double c3 = ( Math.sin(θ) * Math.cos(φ) )/ s2;
        double s1 = ( Math.sin(θ) * Math.sin(ψ) + Math.cos(θ) * Math.sin(φ) * Math.cos(ψ) )/s2;

        γ = Math.acos(r(c3));
        α = Math.asin(r(s1));

    }

    α *= 180/Math.PI;
    β *= 180/Math.PI;
    γ *= 180/Math.PI;

    return new double[] {r(α), r(β), r(γ)};
}

Where r and eq are just two simple functions;

public static double r(double a){
    double prec = 1000000000.0;
    return Math.round(a*prec)/prec;
}

static double thresh = 1E-4;
public static boolean eq(double a, double b){
    return (Math.abs(a-b) < thresh);
}

eq is just to compare the numbers for tests, and r is to prevent floating point errors pushing numbers outside the range of Math.acos / Math.asin and giving me NaN results;

(i.e. every now and then I'd end up with Math.acos(1.000000000000000004) or something.)

Which takes into account the 4 cases of having rotations around x and s which leave c2==1.

But now is where the problem occurs;

Everything I have done above, makes sense to me, but it does not give the correct angles;

Here is some output, in each pair, the first are the \theta, \phi \psi angles, and the second of each pair is the corresponding \alpha, \beta \gamma líneas. Ignorando los errores de redondeo, se parece conseguir algunos de los ángulos de aproximadamente

[0.0, 0.0, 0.0] - correcto! [0.0, 0.0, 0.0]

[0.0, 0.0, 45.0] - correcto! [0.0, 0.0, 45.0]

[0.0, 0.0, 90.0] - correcto! [0.0, 0.0, 90.0]

[0.0, 0.0, 135.0] - correcto! [0.0, 0.0, 135.0]

[0.0, 0.0, 180.0] - correcto [0.0, 0.0, 180.0]

[0.0, 0.0, 225.0] - correcto [0.0, 0.0, 225.0]

[0.0, 0.0, 270.0] - correcto [0.0, 0.0, 270.0]

[0.0, 0.0, 315.0] - correcto [0.0, 0.0, 315.0]

[0.0, 45.0, 0.0] - incorrecto: debe ser [90, 45, -90] [90.0, 44.999982, 90.0]

[0.0, 45.0, 45.0] [45.000018, 44.999982, 90.0]

[0.0, 45.0, 90.0] [0.0, 44.999982, 90.0]

[0.0, 45.0, 135.0] [-45.000018, 44.999982, 90.0]

[0.0, 45.0, 180.0] [-90.0, 44.999982, 90.0]

[0.0, 45.0, 225.0] [-45.000018, 44.999982, 90.0]

[0.0, 45.0, 270.0] [0.0, 44.999982, 90.0]

[0.0, 45.0, 315.0] [45.000018, 44.999982, 90.0]

[0.0, 90.0, 0.0] [90.0, 90.0, 90.0]

[0.0, 90.0, 45.0] [45.000018, 90.0, 90.0]

[0.0, 90.0, 90.0] [0.0, 90.0, 90.0]

[0.0, 90.0, 135.0] [-45.000018, 90.0, 90.0]

[0.0, 90.0, 180.0] [-90.0, 90.0, 90.0]

[0.0, 90.0, 225.0] [-45.000018, 90.0, 90.0]

¿Alguien puede pensar en una solución?

EDIT: no sé si esto ayuda, pero hay algunas otras maneras de mirar en estas rotaciones:

Una forma de rotar alrededor de un eje arbitrario, es reorientar que el eje de la Z Eje y, a continuación, hacer la inversa de la reorientación; se puede aplicar una y otra, para obtener las rotaciones de Euler en términos de la original eje fijo rotaciones;

R_{Z^{\prime\prime} X^{\prime} Z}(\alpha,\beta,\gamma) = R_{Z^{\prime\prime}}(\gamma)R_{X^{\prime}}(\beta)R_Z(\alpha)

R_{X^{\prime}}(\beta) = R_Z(\alpha)R_Y(\frac{\pi}{2})R_Z(\beta)R_Y(-\frac{\pi}{2})R_Z(-\alpha)

so

R_{X^{\prime}}(\beta)R_Z(\alpha) = R_Z(\alpha)R_Y(\frac{\pi}{2})R_Z(\beta)R_Y(-\frac{\pi}{2})

R_{Z^{\prime\prime}} = R_Z(\alpha)R_Y(\frac{\pi}{2})R_Z(\beta)R_Y(-\frac{\pi}{2})R_Z(\gamma)R_Y(\frac{\pi}{2})R_Z(-\beta)R_Y(-\frac{\pi}{2})R_Z(-\alpha)

And so the whole thing;

R_{Z^{\prime\prime}}(\gamma)R_{X^{\prime}}(\beta)R_Z(\alpha) = R_Z(\alpha)R_Y(\frac{\pi}{2})R_Z(\beta)R_Y(-\frac{\pi}{2})R_Z(\gamma)R_Y(\frac{\pi}{2})R_Z(-\beta)R_Y(-\frac{\pi}{2})R_Z(-\alpha)R_Z(\alpha)R_Y(\frac{\pi}{2})R_Z(\beta)R_Y(-\frac{\pi}{2})

Which cancels down;

R_{Z^{\prime\prime}}(\gamma)R_{X^{\prime}}(\beta)R_Z(\alpha) = R_Z(\alpha)R_Y(\frac{\pi}{2})R_Z(\beta)R_Y(-\frac{\pi}{2})R_Z(\gamma)R_Y(\frac{\pi}{2})R_Z(-\beta)\mathbf{R_Y(-\frac{\pi}{2})R_Y(\frac{\pi}{2})}R_Z(\beta)R_Y(-\frac{\pi}{2})

R_{Z^{\prime\prime}}(\gamma)R_{X^{\prime}}(\beta)R_Z(\alpha) = R_Z(\alpha)R_Y(\frac{\pi}{2})R_Z(\beta)R_Y(-\frac{\pi}{2})R_Z(\gamma)R_Y(\frac{\pi}{2})\mathbf{R_Z(-\beta)R_Z(\beta)}R_Y(-\frac{\pi}{2})

R_{Z^{\prime\prime}}(\gamma)R_{X^{\prime}}(\beta)R_Z(\alpha) = R_Z(\alpha)R_Y(\frac{\pi}{2})R_Z(\beta)R_Y(-\frac{\pi}{2})R_Z(\gamma)\mathbf{R_Y(\frac{\pi}{2})R_Y(-\frac{\pi}{2})}

R_{Z^{\prime\prime}}(\gamma)R_{X^{\prime}}(\beta)R_Z(\alpha) = R_Z(\alpha)R_Y(\frac{\pi}{2})R_Z(\beta)R_Y(-\frac{\pi}{2})R_Z(\gamma)

Y tenga en cuenta que R_Y(\frac{\pi}{2})R_Z(\beta)R_Y(-\frac{\pi}{2}) = R_X(\beta)

así tenemos R_{Z^{\prime\prime}}(\gamma)R_{X^{\prime}}(\beta)R_Z(\alpha) = R_Z(\alpha)R_X(\beta)R_Z(\gamma)

Ahora no estoy seguro de lo mucho que esto podría ayudar... pero es algo, supongo...

2voto

Kiewic Puntos 2863

Este documento describe exactamente lo que usted necesita.

Leer esto, y luego esto.

Entonces, si usted lee un poco más, vas a encontrar esto:

Aquí hay algunos EulerAngles Código, que se puede tener un vistazo a...

esta búsqueda de google también da un montón de otras soluciones a su problema.

En realidad se puede utilizar estos métodos para recuperar la rotación regular de los ángulos demasiado, como la construcción de la matriz de rotación es trivial, y sólo es necesario invertir el orden de las rotaciones de euler para obtener el regular el ángulo de rotación.

(donde regulares y euler, sólo quiero decir intrínsecos y extrínsecos)

EDIT: solo di cuenta de que me respondió a mi pregunta por accidente...

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