用螺距,偏航,使用特征滚动创建旋转矩阵
Creating a rotation matrix with pitch, yaw, roll using Eigen
如何使用俯仰,偏航,用特征库来创建旋转矩阵?
看到我找不到这样做的预构建函数,我构建了一个,以防万一有人在将来找到这个问题
Eigen::AngleAxisd rollAngle(roll, Eigen::Vector3d::UnitZ());
Eigen::AngleAxisd yawAngle(yaw, Eigen::Vector3d::UnitY());
Eigen::AngleAxisd pitchAngle(pitch, Eigen::Vector3d::UnitX());
Eigen::Quaternion<double> q = rollAngle * yawAngle * pitchAngle;
Eigen::Matrix3d rotationMatrix = q.matrix();
凯撒答案还可以,但是正如戴维·哈蒙(David Hammen)所说,这取决于您的应用程序。对我(水下或飞机场)而言,获胜组合是:
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 = yawAngle * pitchAngle * rollAngle;
return q;
}
如何使用音高,偏航,用特征库来创建旋转矩阵?
有48种方法可以做到这一点。你想要哪一个?这是:
- 外在的固有。
是固定系统轴(外部)轴的旋转,还是围绕旋转轴(固有)? - 旋转与转换。
您是否要表示物理旋转某些对象的矩阵,还是要表示将向量从一个参考帧转换为另一个参考框的矩阵? - 天文序列。
有六个基本的天文序列。规范的Euler序列涉及围绕Z轴的旋转,然后围绕(旋转)X轴旋转,然后是第三个旋转(再次旋转)Z轴。这些天文学风格的序列中还有五个( x-y-x , x-z-z-x , y-x-y-x-y , y-z-y-z-y 和 z-y-z )除了这个规范 z-x-z 序列。 - 航空航天序列。
为了加上混乱,还有六个基本航空航天序列。例如,俯仰 - 滚子序列与滚动式偏合序列相比。尽管天文学界几乎已经解决了A Z-X-Z序列,但航空航天社区的说法也不能说。在此过程中,您发现人们使用六个可能的序列中的每一个。该组的六个序列是 x-y-z , x-z-z-y , y-z-z-x , y-x-z-z ,>和 z-y-x 。
创建一个旋转矩阵所需的只是螺距,偏航,滚动和执行矩阵乘法的能力。
首先,创建三个旋转矩阵,每个旋转轴一个(即一个用于音高,一个用于偏航,一个用于滚动)。这些矩阵将具有值:
音高矩阵:
1, 0, 0, 0,
0, cos(pitch), sin(pitch), 0,
0, -sin(pitch), cos(pitch), 0,
0, 0, 0, 1
偏航矩阵:
cos(yaw), 0, -sin(yaw), 0,
0, 1, 0, 0,
sin(yaw), 0, cos(yaw), 0,
0, 0, 0, 1
滚动矩阵:
cos(roll), sin(roll), 0, 0,
-sin(roll), cos(roll), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
接下来,将所有这些都乘在一起。这里的顺序很重要。对于正常旋转,您将需要先将滚动矩阵乘以偏航矩阵,然后将产品乘以螺距矩阵。但是,如果您试图通过向后"撤消"旋转,则需要反向顺序执行乘法(除了具有相反值的角度)。
i将其Java实现转换为来自此站点的C :Euler Angle可视化工具
#include <iostream>
#include <math.h>
#include <Eigen/Dense>
Eigen::Matrix3d rotation_from_euler(double roll, double pitch, double yaw){
// roll and pitch and yaw in radians
double su = sin(roll);
double cu = cos(roll);
double sv = sin(pitch);
double cv = cos(pitch);
double sw = sin(yaw);
double cw = cos(yaw);
Eigen::Matrix3d Rot_matrix(3, 3);
Rot_matrix(0, 0) = cv*cw;
Rot_matrix(0, 1) = su*sv*cw - cu*sw;
Rot_matrix(0, 2) = su*sw + cu*sv*cw;
Rot_matrix(1, 0) = cv*sw;
Rot_matrix(1, 1) = cu*cw + su*sv*sw;
Rot_matrix(1, 2) = cu*sv*sw - su*cw;
Rot_matrix(2, 0) = -sv;
Rot_matrix(2, 1) = su*cv;
Rot_matrix(2, 2) = cu*cv;
return Rot_matrix;
}
int main() {
Eigen::Matrix3d rot_mat = rotation_from_euler(0, 0, 0.5*M_PI);
std::cout << rot_mat << std::endl;
return 0;
}
这是使用标准ZYX订单的实现,如Wikipedia
所示template <typename T>
Eigen::Matrix3<T> eulerZYX_2_rot(T roll_rad, T pitch_rad, T yaw_rad) {
// ZYX order, same as rot_z(yaw_rad) * rot_y(pitch_rad) * rot_x(roll_rad)
static_assert(std::is_floating_point_v<T>, "Floating point required.");
T sx = sin(roll_rad);
T cx = cos(roll_rad);
T sy = sin(pitch_rad);
T cy = cos(pitch_rad);
T sz = sin(yaw_rad);
T cz = cos(yaw_rad);
Eigen::Matrix3<T> rot(3, 3);
rot(0, 0) = cz * cy;
rot(0, 1) = cz * sy * sx - sz * cx;
rot(0, 2) = cz * sy * cx + sz * sx;
rot(1, 0) = sz * cy;
rot(1, 1) = sz * sy * sx + cz * cx;
rot(1, 2) = sz * sy * cx - cz * sx;
rot(2, 0) = -sy;
rot(2, 1) = cy * sx;
rot(2, 2) = cy * cx;
return rot;
}
相关文章:
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 使用std::multimap迭代器创建std::list
- 在全局变量中保存类的实例以重新创建类(创建"backup")
- 使用CMake创建QML插件
- 如何在c++中为模板函数实例创建快捷方式
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 与互斥锁相比,旋转锁可以保证上下文切换
- OpenCV EqualizeHist()从彩色图像创建黑白图像
- 试图在visual studio上用C++创建一个桌面应用程序
- std::threads可以从Windows DLL中的全局变量创建/销毁吗?
- 用螺距,偏航,使用特征滚动创建旋转矩阵
- CImg 库在旋转时创建失真的图像
- C++/QT 值创建旋转框小部件时更改(整数)信号
- 在 OpenGL 中创建一个围绕其 y 轴连续旋转的三角形
- 创建一个围绕对象 OpenGL C++旋转的相机
- 制作旋转器的功能,每天每分钟创建一个时间戳
- 无法在WebGL中创建沿轴旋转的3D Koch
- 创建二叉搜索树类,一个节点在旋转后消失
- 从帧缓冲区创建的JPEG被旋转180度