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.
source to share
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
source to share
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;
source to share