android – 如何从旋转矢量获取欧拉角(Sensor.TYPE_ROTATION_VECTOR)
作者:互联网
我在x方向上旋转我的Android设备(从-180度到180度),见下图.
并且我假设只有旋转矢量x值被改变. Y和z可能有一些噪音,但值之间差别不大.
但是,我收到了这个.请注意
https://docs.google.com/spreadsheets/d/1ZLoSKI8XNjI1v4exaXxsuMtzP0qWTP5Uu4C3YTwnsKo/edit?usp=sharing
我怀疑我的传感器有一些问题.
任何想法?非常感谢你.
吉米
解决方法:
您的传感器很好.好吧,旋转矢量条目不能简单地与特定轴周围的旋转角度相关. SensorEvent结构由时间戳,传感器,精度和值组成.根据向量,浮点数[]的大小在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序列:
如果您已经有旋转矩阵条目,请按以下方式获取euler:
321序列:
与q1-3一直是值[0-2](不要被u_ijk弄糊涂,因为ref(Diebel)使用不同的约定comp.到标准)但等等,你的链表只有3个值,这类似于什么我明白了这是我的一个传感器事件,最后三个是从值[]打印出来的
23191581386897 11 -75 -0.0036907701 -0.014922042 0.9932963
时间戳敏感类型精度值[0]值[1]值[2]
4q-3values = 1q未知.第一个q0是redunant信息(doku也表示它应该在值[3]下,取决于你的API级别).所以我们可以使用范数(= length)来计算其他三个中的q0. 设置方程|| q || = 1并求解q0.现在所有q0-3都是已知的.
此外我的android 4.4.2没有第四个估计标题Accuracy(以弧度表示)内部值[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);
}
}
将这些方程式放入代码中,您将对事物进行排序.
这是一个简短的转换助手,转换Quats.使用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;
}
问:ijk的序列代表什么?取两个坐标框架A和B相互叠加(所有轴彼此叠加)并开始通过具有角度psi的i轴旋转框架B,然后使具有角度θ的j轴和具有phi的最后z轴旋转.对于i,j,k,它也可以是α,β,γ.我不接受这些数字,因为它们令人困惑(Diebel vs其他论文).
R(psi,theta,phi) = R_z(phi)R_y(theta)R_x(psi) (<--)
诀窍是从右到左应用基本旋转,尽管我们从左到右读取序列.
这是你要经历的三个基本轮换
A to B: *v_B = R(psi,theta,phi) v_A*
问:那么如何让欧拉角/ quats从[0°,0°,0°]转到例如. [0°,90°,0°]?首先将图片中的两个帧对齐,将已知的设备帧B分别对准“不可见”的世界帧A.当角度全部达到[0°,0°,0时,完成叠加°].只需弄清楚你现在坐在哪里的北,南和东,然后将设备框架B指向那些方向.现在,当您绕y轴逆时针旋转90°时,转换四元数时将获得所需的[0°,90°,0°].
朱利安
*运动学来源:Source Diebel(Stanford),有关机械背景的实体信息(注意:对于Diebel XYZ表示为u_321(1,2,3),而ZYX表示为u_123(3,2,1)),而this是一个很好的起点.
标签:quaternions,android,rotation,orientation,gyroscope 来源: https://codeday.me/bug/20191001/1839066.html