用欧拉角输入旋转四元数

4
我正在编写一段代码来控制三维空间中的机器人臂。机器人臂通过四元数处理旋转,但我希望用户通过改变偏航角、俯仰角和翻滚角来控制它,因为这对人类更加敏感。
我编写了一个函数来获取用户想要在每个方向上旋转臂的量,并输出新的四元数。我将当前的四元数保存为全局变量。
我正在使用C++和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;
}

我尝试了许多方法,改变角度相乘的顺序并将UnitX(),UnitY()和UnitZ()与current_q.toRotationMatrix()相乘,但它们都没有起作用。


1
你说的“它们都没起作用”是什么意思?是指它们没有产生预期的转换效果吗? - Drew McGowen
是的,即使所有输入都为零,旋转角度也会不断变化。 - D3GAN
1
AngleAxisd是什么?Quaterniond又是什么?它们有意义吗? - Avi Ginsburg
1
不妨考虑只存储欧拉角(翻滚、俯仰、偏航),而不是存储 current_q,需要时从欧拉角生成四元数怎么样? - sbabbi
@Avi Ginsburg:我从这个问题中得到了我的代码基础:https://dev59.com/kWEi5IYBdhLWcg3wUKyC - D3GAN
@D3GAN 我的意思是,这些值是什么。 - Avi Ginsburg
2个回答

4
您提供的示例与这个示例几乎完全相同,只是略有不同。
Matrix3f m;
m = AngleAxisf(0.25*M_PI, Vector3f::UnitX())
  * AngleAxisf(0.5*M_PI,  Vector3f::UnitY())
  * AngleAxisf(0.33*M_PI, Vector3f::UnitZ());

您尝试打印组合旋转矩阵的结果了吗?我敢打赌当角度为零时,它会是对角线1,1,1。

我对您对current_q的使用感到困惑。如果横滚、俯仰和偏航对应于某个固定的参考方向,那么q就是整个旋转。在这种情况下,以下内容:

current_q=q*current_q;
return current_q;

应该只是

current_q=q;
return current_q;

如果roll、pitch、yaw表示相对于某个固定参考方向的欧拉旋转角度变化,那么更容易存储这些角度并相应地进行变化。
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;
}

这也是sbabbi在评论中建议的。

输入是用户想要更改旋转次数的小量,而不是旋转本身。 - D3GAN
1
我会尝试并告诉你...谢谢。 - D3GAN

0

为什么不直接构建四元数呢?

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;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接