Rotate the quaternion over Euler's corner inputs

I am writing code to control a robotic arm in 3D space. The robotic arm controls the quaternion pivot, but I want the user to control it by changing the yaw, pitch and throw as it is more intelligent for a human to use them.

I wrote a function to get the amount the user wants to rotate his hand in each direction (roll, pitch, yaw) and output a new quaternion. I have saved current_quaternion as a global variable.

I am using C ++ and Eigen.

Eigen::Quaterniond euler2Quaternion( const double roll,
              const double pitch,
              const double yaw)
{

Eigen::AngleAxisd rollAngle(roll,Eigen::Vector3d::UnitX());
Eigen::AngleAxisd pitchAngle(pitch,Eigen::Vector3d::UnitY());
Eigen::AngleAxisd yawAngle(yaw,Eigen::Vector3d::UnitZ());

Eigen::Quaterniond q = rollAngle*pitchAngle*yawAngle;
current_q=q*current_q;
return current_q;
}

      

I tried a lot of things, changing the angles multiplication order and multiplying UnitX (), UnitY () and UnitZ () by current_q.toRotationMatrix (), but didn't work.

+3


source to share


2 answers


Your example is almost identical to example

Matrix3f m;
m = AngleAxisf(0.25*M_PI, Vector3f::UnitX())
  * AngleAxisf(0.5*M_PI,  Vector3f::UnitY())
  * AngleAxisf(0.33*M_PI, Vector3f::UnitZ());

      

Have you tried printing the result of this combined rotation matrix? I'll bet it's a 1,1,1 diagonal when the angles are zero.

I am confused about your use of current_q. If roll, pitch, yaw correspond to some fixed reference direction, then q will be all rotations. In this case it is:

current_q=q*current_q;
return current_q;

      



it should be

current_q=q;
return current_q;

      

if roll, pitch, yaw

intended as changes to the current angles of rotation (Euler that start at some fixed reference direction), it's easier to store those angles and change them accordingly:

double m_roll=0, m_pitch=0, m_yaw=0;
 . . .
Eigen::Quaterniond euler2Quaternion(double roll,
              double pitch,
              double yaw)
{
 m_roll+=roll;
 m_pitch+=pitch;
 m_yaw+=yaw;

 Eigen::AngleAxisd rollAngle(m_roll,Eigen::Vector3d::UnitX());
 Eigen::AngleAxisd pitchAngle(m_pitch,Eigen::Vector3d::UnitY());
 Eigen::AngleAxisd yawAngle(m_yaw,Eigen::Vector3d::UnitZ());

 Eigen::Quaterniond q = rollAngle*pitchAngle*yawAngle;
 current_q=q;
 return current_q;
}

      

This is also suggested in sbabbi's comment

+3


source


Why not build quaternions directly?



Eigen::Quaterniond rollQuaternion(cos(0.5*roll), sin(0.5*roll), 0.0, 0.0);
Eigen::Quaterniond pitchQuaternion(cos(0.5*roll), 0.0, sin(0.5*roll), 0.0);
Eigen::Quaterniond yawQuaternion(cos(0.5*roll), 0.0, 0.0, sin(0.5*roll));
Eigen::Quaterniond finalOrientation = rollQuaternion*pitchQuaternion*yawQuaternion*current_q;

      

0


source







All Articles