Rotate a quaternion by Euler angles input

扶醉桌前 提交于 2019-12-04 01:42:45

问题


I am writing a code to control robotic arm in 3D space. The robotic arm handle the rotation by quaternion but I want user to control it by changing yaw, pitch and roll since its more sensible for human to use these.

I wrote function to get the amount that user wants to rotate the arm in each of directions(roll, pitch, yaw) and output the new quaternion. I saved the 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 many things changing the order of multiplying angles and multiplying UnitX(), UnitY() and UnitZ() by current_q.toRotationMatrix() but non of them worked.


回答1:


Your example is almost identical to the 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 that combined rotation matrix? I will bet it is diagonal 1,1,1 when the angles are zero.

I'm confused about your use of current_q. If roll, pitch, yaw corresponds to some fixed reference direction, then q will be the whole rotation. In that case, this:

current_q=q*current_q;
return current_q;

should just be

current_q=q;
return current_q;

if roll, pitch, yaw are meant as changes to the current euler rotation angles (which start from some fixed reference direction), it's easier to store these 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 a comment by sbabbi




回答2:


Why not build the 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;


来源:https://stackoverflow.com/questions/29830109/rotate-a-quaternion-by-euler-angles-input

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!