-1

I'm given quaternion data of an object [w, x, y, z] in the Forward Left Up (FLU) coordinate system and I would like to convert it to quaternion data in the Forward Right Down (FRD) coordinate system. What is the most efficient way of doing this in C++14?

I've tried flipping the sign on the y and z values, but I've read conflicting information on if that's the correct way to do it.

#include <Eigen/Eigen>
#include <iostream>

using namespace Eigen;

Eigen::Quaterniond FLUtoFRD(const Eigen::Quaterniond& flu) {
  double angle = M_PI; // pi radians for 180 degrees

  Eigen::Vector3d rotationAxis = Eigen::Vector3d::UnitX();
  Eigen::AngleAxisd rotX_axis(angle, rotationAxis);

  Eigen::Quaterniond rotX(rotX_axis);

  return rotX * flu * rotX.inverse();

}


int main() {
    Eigen::Quaterniond flu(0.7071, 0.69, 0.77, 0);

    Eigen::Quaterniond frd = FLUtoFRD(flu);

    std::cout << "FRD quaternion: \n" << frd.coeffs() << std::endl;

    return 0;
}
4
  • 1
    This question should belong to mathoverflow.net if I'm not mistaken Commented May 13, 2024 at 8:41
  • 1
    forget about efficiency before you know how it can be done correctly. A wrong result can be obtained in 0 time, but is useless. Commented May 13, 2024 at 8:45
  • Essentially you need to multiply with a quaternion which transforms from FLU to FRD. Figure out what quaternion does that. If this contains only a single 1 entry, you can optimize the multiplication to a shuffle and (a/some) sign change(s). Be very careful with the order of multiplication and test your code thoroughly. Commented May 13, 2024 at 9:07
  • Please provide enough code so others can better understand or reproduce the problem. Commented May 13, 2024 at 12:14

1 Answer 1

0

The quaternion transformation for this 180 deg rotation about x is:

qFLU2FRD = (w,x,y,z) = (cos(pi/2),sin(pi/2),0,0) = (0,1,0,0)

Then it is a question of what convention your original quaternion is in. If your original qFLU represents a Hamilton passive coordinate system transformation, then successive coordinate system transformations stack up on the right and you would get:

qFRD = qFLU * qFLU2FRD

Otherwise you will get:

qFRD = qFLU2FRD * qFLU

I am not familiar with the quaternion convention of the Eigen package, so can't advise you as to which one of these is correct for your particular problem. To see that this quaternion flips the signs of the y and z elements, an example using MATLAB assuming passive Hamilton convention:

>> a = 1:3 % an arbitrary vector in FLU
a =
     1     2     3

>> qa = quaternion([0,a]) % a as quaternion
qa = 
  quaternion
     0 + 1i + 2j + 3k

>> qFLU2FRD = quaternion(cosd(180/2), sind(180/2), 0, 0)
qFLU2FRD = 
  quaternion
     0 + 1i + 0j + 0k
 
>> conj(qFLU2FRD) * qa * qFLU2FRD % rotate the vector a coordinates
ans = 
  quaternion
     0 + 1i - 2j - 3k

As you can see, the y and z elements flipped signs as expected.

Since we know the form of qFLU2FRD, we can simply do the qFLU * qFLU2FRD symbolically to see how the quaternion changes, again using MATLAB:

>> syms qw qx qy qz % the elements of qFLU

>> qv = [qx,qy,qz] % the vector part of qFLU
qv =
[ qx, qy, qz]

>> pw = 0 % the scalar part of qFLU2FRD
pw =
     0

>> pv = [1 0 0] % the vector part of qFLU2FRD
pv =
     1     0     0

>> qpw = qw*pw - sum(qv.*pv) % the scalar part of qFLU * qFLU2FRD
qpw =
-qx

>> qpv = qw*pv + pw*qv + cross(qv,pv) % the vector part of qFLU * qFLU2FRD
qpv =
[ qw, qz, -qy]

So, if qFLU = (qw,qx,qy,qz), then qFRD = (-qx,qw,qz,-qy). I.e., you can do some simple element + sign swapping to get the new quaternion. But, again, this assumes a passive Hamilton quaternion convention. If the Eigen package has a different convention, then you would have to switch the order of multiplication in my example to get the matching result for that case.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.