如何从旋转向量中获取欧拉角 (Sensor.TYPE_ROTATION_VECTOR)
How to get the euler-angles from the rotation vector (Sensor.TYPE_ROTATION_VECTOR)
我在 x 方向(从 -180 度到 180 度)旋转了我的 android 设备,见下图。
我假设只有旋转向量 x 值发生了变化。 Y 和 z 可能有一些噪音,但应该相差不大。
但是,我收到了这个。请看
https://docs.google.com/spreadsheets/d/1ZLoSKI8XNjI1v4exaXxsuMtzP0qWTP5Uu4C3YTwnsKo/edit?usp=sharing
我怀疑我的传感器有问题。
有什么想法吗?非常感谢。
吉米
您的传感器没问题。
嗯,旋转矢量条目不能简单地与围绕特定轴的旋转角度相关。 SensorEvent 结构由时间戳、传感器、精度和值组成。根据矢量,values
的 float[] 的大小在 1-5 之间变化。
旋转矢量值基于单位四元数,它们一起形成一个矢量,表示这个世界坐标系相对于您的智能手机在上方固定框架
它们是无量纲且逆时针为正的。
The orientation of the phone is represented by the rotation necessary to align the East-North-Up coordinates with the phone's coordinates. That is, applying the rotation to the world frame (X,Y,Z) would align them with the phone coordinates (x,y,z).
如果向量是旋转矩阵,可以将其写为
v_body = R_rot_vec * v_world (<--)
将世界向量推入智能手机固定描述中。
此外关于矢量:
The three elements of the rotation vector are equal to the last three components of a unit quaternion <cos(θ/2), xsin(θ/2), ysin(θ/2), z*sin(θ/2)>.
问:那怎么办呢?
根据您的欧拉角约定(可能的 24 个序列,有效的 12 个),您可以通过例如计算相应的角度 u := [ψ,θ,φ]应用
123 序列:
If you already have the rotation matrix entries get euler like so:
321 序列:
其中 q1-3 始终是 values[0-2]
(不要被 u_ijk
混淆,因为 ref(Diebel) 使用不同的约定 comp. 标准)
但是等等,您的链接 table 只有 3 个值,这与我得到的相似。这是我的一个SensorEvent
,后三个打印自values[]
timestamp sensortype accuracy values[0] values[1] values[2]
23191581386897 11 -75 -0.0036907701 -0.014922042 0.9932963
4q - 3 个值 = 1q 未知。第一个 q0 是冗余信息(也是 doku says it should be there under values[3]
, depends on your API-level). So we can use the norm (=length) to calculate q0 from the other three.
设置方程 ||q|| = 1 并求解 q0。现在所有 q0-3 都是已知的。
此外,我的android 4.4.2没有value[4]
内的第四个估计航向精度(以弧度为单位),所以我评估event.accuracy
:
for (SensorEvent e : currentEvent) {
if (e != null) {
String toMsg = "";
for(int i = 0; i < e.values.length;i++) {
toMsg += " " + String.valueOf(e.values[i]);
}
iBinder.msgString(String.valueOf(e.timestamp) + " "+String.valueOf(e.sensor.getType()) + " " + String.valueOf(e.accuracy) + toMsg, 0);
}
}
将这些方程式写成代码,你就会把事情整理好。
这是一个简短的转换助手,可以转换 Quat。使用 XYZ 或 ZYX。它可以是 运行 来自 shell github。 (BSD 许可)
XYZ 的相关部分
/*quaternation to euler in XYZ (seq:123)*/
double* quat2eulerxyz(double* q) {
/*euler-angles*/
double psi = atan2( -2.*(q[2]*q[3] - q[0]*q[1]) , q[0]*q[0] - q[1]*q[1]- q[2]*q[2] + q[3]*q[3] );
double theta = asin( 2.*(q[1]*q[3] + q[0]*q[2]) );
double phi = atan2( 2.*(-q[1]*q[2] + q[0]*q[3]) , q[0]*q[0] + q[1]*q[1] - q[2]*q[2] - q[3]*q[3] );
/*save var. by simply pushing them back into the array and return*/
q[1] = psi;
q[2] = theta;
q[3] = phi;
return q;
}
这里有一些将 quats 应用于 euls 的示例:
**问:**序列ijk代表什么?
将两个坐标系 A 和 B 相互叠加(所有轴都在彼此内)并开始旋转坐标系 B 通过具有角度 `psi` 的 i 轴,然后是具有角度 `theta` 的 j 轴和最后一个 z -轴有 `phi`。对于 i、j、k,它也可以是 α、β、γ。 *我没有选择数字,因为它们令人困惑(Diebel 与其他论文)。*
R(psi,theta,phi) = R_z(phi)R_y(theta)R_x(psi) (<--)
诀窍是从右到左应用基本旋转,尽管我们从左到右读取序列。
这些是您要经历的三个基本旋转
A to B: *v_B = R(psi,theta,phi) v_A*
**Q:** 那么如何让欧拉 angles/quats 从 [0°,0°,0°] 转向例如。 [0°,90°,0°]?
首先将图片中的两个帧对齐,分别将已知设备帧 B 与 "invisible" 世界帧 A 对齐。当角度都达到 [ 0°,0°,0°]。只要弄清楚你现在坐的地方是北、南和东,然后将设备框架 B 指向这些方向。现在,当您围绕 y 轴逆时针旋转 90° 时,您将在转换四元数时得到所需的 [0°,90°,0°]。
*朱利安*
*运动学来源:[Source Diebel(Stanford)][11] 具有可靠的力学背景信息(注意:对于 Diebel,XYZ 表示为 u_321 (1,2,3),而 ZYX 表示为 u_123( 3,2,1)),[this][12] 是一个很好的起点。
我在 x 方向(从 -180 度到 180 度)旋转了我的 android 设备,见下图。
我假设只有旋转向量 x 值发生了变化。 Y 和 z 可能有一些噪音,但应该相差不大。
但是,我收到了这个。请看
https://docs.google.com/spreadsheets/d/1ZLoSKI8XNjI1v4exaXxsuMtzP0qWTP5Uu4C3YTwnsKo/edit?usp=sharing
我怀疑我的传感器有问题。
有什么想法吗?非常感谢。
吉米
您的传感器没问题。
嗯,旋转矢量条目不能简单地与围绕特定轴的旋转角度相关。 SensorEvent 结构由时间戳、传感器、精度和值组成。根据矢量,values
的 float[] 的大小在 1-5 之间变化。
旋转矢量值基于单位四元数,它们一起形成一个矢量,表示这个世界坐标系相对于您的智能手机在上方固定框架
The orientation of the phone is represented by the rotation necessary to align the East-North-Up coordinates with the phone's coordinates. That is, applying the rotation to the world frame (X,Y,Z) would align them with the phone coordinates (x,y,z).
如果向量是旋转矩阵,可以将其写为
v_body = R_rot_vec * v_world (<--)
将世界向量推入智能手机固定描述中。
此外关于矢量:
The three elements of the rotation vector are equal to the last three components of a unit quaternion <cos(θ/2), xsin(θ/2), ysin(θ/2), z*sin(θ/2)>.
问:那怎么办呢?
根据您的欧拉角约定(可能的 24 个序列,有效的 12 个),您可以通过例如计算相应的角度 u := [ψ,θ,φ]应用
123 序列:
If you already have the rotation matrix entries get euler like so:
321 序列:
其中 q1-3 始终是 values[0-2]
(不要被 u_ijk
混淆,因为 ref(Diebel) 使用不同的约定 comp. 标准)
但是等等,您的链接 table 只有 3 个值,这与我得到的相似。这是我的一个SensorEvent
,后三个打印自values[]
timestamp sensortype accuracy values[0] values[1] values[2]
23191581386897 11 -75 -0.0036907701 -0.014922042 0.9932963
4q - 3 个值 = 1q 未知。第一个 q0 是冗余信息(也是 doku says it should be there under values[3]
, depends on your API-level). So we can use the norm (=length) to calculate q0 from the other three.
设置方程 ||q|| = 1 并求解 q0。现在所有 q0-3 都是已知的。
此外,我的android 4.4.2没有value[4]
内的第四个估计航向精度(以弧度为单位),所以我评估event.accuracy
:
for (SensorEvent e : currentEvent) {
if (e != null) {
String toMsg = "";
for(int i = 0; i < e.values.length;i++) {
toMsg += " " + String.valueOf(e.values[i]);
}
iBinder.msgString(String.valueOf(e.timestamp) + " "+String.valueOf(e.sensor.getType()) + " " + String.valueOf(e.accuracy) + toMsg, 0);
}
}
将这些方程式写成代码,你就会把事情整理好。
这是一个简短的转换助手,可以转换 Quat。使用 XYZ 或 ZYX。它可以是 运行 来自 shell github。 (BSD 许可)
XYZ 的相关部分
/*quaternation to euler in XYZ (seq:123)*/
double* quat2eulerxyz(double* q) {
/*euler-angles*/
double psi = atan2( -2.*(q[2]*q[3] - q[0]*q[1]) , q[0]*q[0] - q[1]*q[1]- q[2]*q[2] + q[3]*q[3] );
double theta = asin( 2.*(q[1]*q[3] + q[0]*q[2]) );
double phi = atan2( 2.*(-q[1]*q[2] + q[0]*q[3]) , q[0]*q[0] + q[1]*q[1] - q[2]*q[2] - q[3]*q[3] );
/*save var. by simply pushing them back into the array and return*/
q[1] = psi;
q[2] = theta;
q[3] = phi;
return q;
}
这里有一些将 quats 应用于 euls 的示例:
**问:**序列ijk代表什么?
将两个坐标系 A 和 B 相互叠加(所有轴都在彼此内)并开始旋转坐标系 B 通过具有角度 `psi` 的 i 轴,然后是具有角度 `theta` 的 j 轴和最后一个 z -轴有 `phi`。对于 i、j、k,它也可以是 α、β、γ。 *我没有选择数字,因为它们令人困惑(Diebel 与其他论文)。*
R(psi,theta,phi) = R_z(phi)R_y(theta)R_x(psi) (<--)
诀窍是从右到左应用基本旋转,尽管我们从左到右读取序列。 这些是您要经历的三个基本旋转
A to B: *v_B = R(psi,theta,phi) v_A*
**Q:** 那么如何让欧拉 angles/quats 从 [0°,0°,0°] 转向例如。 [0°,90°,0°]?
首先将图片中的两个帧对齐,分别将已知设备帧 B 与 "invisible" 世界帧 A 对齐。当角度都达到 [ 0°,0°,0°]。只要弄清楚你现在坐的地方是北、南和东,然后将设备框架 B 指向这些方向。现在,当您围绕 y 轴逆时针旋转 90° 时,您将在转换四元数时得到所需的 [0°,90°,0°]。
*朱利安*
*运动学来源:[Source Diebel(Stanford)][11] 具有可靠的力学背景信息(注意:对于 Diebel,XYZ 表示为 u_321 (1,2,3),而 ZYX 表示为 u_123( 3,2,1)),[this][12] 是一个很好的起点。