传感器TYPE_ACCELEROMETER / TYPE_MAGNETIC_FIELD和TYPE_ORIENTATION之间不同的值 [英] Different values between sensors TYPE_ACCELEROMETER/TYPE_MAGNETIC_FIELD and TYPE_ORIENTATION

查看:1396
本文介绍了传感器TYPE_ACCELEROMETER / TYPE_MAGNETIC_FIELD和TYPE_ORIENTATION之间不同的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有2种方式来获得3旋转值(方位角,俯仰,滚动)。

There are 2 ways to get the 3 rotation values (azimuth, pitch, roll).

一是注册类型TYPE_ORIENTATION的听众。这是最简单的方法,我也得到一个正确的值范围从每一个旋转的文件说: 方位:[0,359] 间距:[-180,180] 滚动:[-90,90]

One is registering a listener of a type TYPE_ORIENTATION. It's the easiest way and I get a correct range of values from every rotation as the documentation says: azimuth: [0, 359] pitch: [-180, 180] roll: [-90, 90]

另一种,最precise和复杂的了解你第一次看到它。 Android的建议,所以我想用它,但我得到不同的值。

The other one, the most precise and complex to understand the first time you see it. Android recommends it, so I want to use it, but I get different values.

方位:[-180,180]。 -180/180是S,0 I N,90 E和-90 W.
间距:[-90,90]。 90是90°,-90为-90,0是0但-180/180(倒卧屏幕向下)为0
滚动:[-180,180]

azimuth: [-180, 180]. -180/180 is S, 0 i N, 90 E and -90 W.
pitch: [-90, 90]. 90 is 90, -90 is -90, 0 is 0 but -180/180 (lying with the screen downwards) is 0.
roll: [-180, 180].

我应该得到相同的价值观,但带有小数,对吧?

I should get the same values but with decimals, right?

我有以下的code:

aValues = new float[3];
mValues = new float[3];

sensorListener = new SensorEventListener (){
    public void onSensorChanged (SensorEvent event){
        switch (event.sensor.getType ()){
            case Sensor.TYPE_ACCELEROMETER:
                aValues = event.values.clone ();
                break;
            case Sensor.TYPE_MAGNETIC_FIELD:
                mValues = event.values.clone ();
                break;
        }

        float[] R = new float[16];
        float[] orientationValues = new float[3];

        SensorManager.getRotationMatrix (R, null, aValues, mValues);
        SensorManager.getOrientation (R, orientationValues);

        orientationValues[0] = (float)Math.toDegrees (orientationValues[0]);
        orientationValues[1] = (float)Math.toDegrees (orientationValues[1]);
        orientationValues[2] = (float)Math.toDegrees (orientationValues[2]);

        azimuthText.setText ("azimuth: " + orientationValues[0]);
        pitchText.setText ("pitch: " + orientationValues[1]);
        rollText.setText ("roll: " + orientationValues[2]);
    }

    public void onAccuracyChanged (Sensor sensor, int accuracy){}
};

请帮忙。这是非常令人沮丧的。

Please help. It's very frustrating.

我必须把这些价值观或者说我做错了什么?

Do I have to treat with those values or I'm doing something wrong?

感谢。

推荐答案

我知道我打线程死灵在这里,但我一直在做这个东西了很多最近,所以我想我会扔在我的2 ¢。

I know I'm playing thread necromancer here, but I've been working on this stuff a lot lately, so I thought I'd throw in my 2¢.

的装置,不包含罗盘或倾斜计,所以不能测量方位,音调,或直接进行滚。 (我们称这些欧拉角,BTW)。相反,它使用加速度计和磁力计,这两者产生3维空间的XYZ矢量。这些用于计算方位角,等的值。

The device doesn't contain compass or inclinometers, so it doesn't measure azimuth, pitch, or roll directly. (We call those Euler angles, BTW). Instead, it uses accelerometers and magnetometers, both of which produce 3-space XYZ vectors. These are used to compute the azimuth, etc. values.

载体在设备坐标空间:

世界坐标有Ÿ朝北,X面向东方,和Z朝上:

World coordinates have Y facing north, X facing east, and Z facing up:

因此​​,设备的中性方向是平躺在其上的表背,与设备朝北的顶部。

Thus, a device's "neutral" orientation is lying flat on its back on a table, with the top of the device facing north.

加速度计产生的UP方向的矢量。磁力仪产生的北方向的矢量。 (请注意,在北半球,这往往会指向向下,由于磁倾角。)

The accelerometer produces a vector in the "UP" direction. The magnetometer produces a vector in the "north" direction. (Note that in the northern hemisphere, this tends to point downward due to magnetic dip.)

加速度矢量和磁力载体可以在数学上通过SensorManager.getRotationMatrix()返回一个3×3矩阵将映射向量设备坐标为世界坐标或反之亦然组合。在中立位置的装置,该函数将返回身份矩阵

The accelerometer vector and magnetometer vector can be combined mathematically through SensorManager.getRotationMatrix() which returns a 3x3 matrix which will map vectors in device coordinates to world coordinates or vice-versa. For a device in the neutral position, this function would return the identity matrix.

这矩阵不与屏幕取向变化。这意味着你的应用程序需要知道方向,并赔偿相应。

This matrix does not vary with the screen orientation. This means your application needs to be aware of orientation and compensate accordingly.

SensorManager.getOrientation()采用的变换矩阵,并计算方位,俯仰和翻滚值。这些将在中立位置采取相对于设备

SensorManager.getOrientation() takes the transformation matrix and computes azimuth, pitch, and roll values. These are taken relative to a device in the neutral position.

我不知道不同的是调用此功能,只使用TYPE_ORIENTATION传感器,除了功能,让您第一操纵矩阵之间有什么。

I have no idea what the difference is between calling this function and just using TYPE_ORIENTATION sensor, except that the function lets you manipulate the matrix first.

如果该装置倾斜上升,在90℃或接近它,则采用欧拉角隔开下降。这是一个退化的情况数学。在这一领域,如何在设备应该知道,如果你改变方位或滚动?

If the device is tilted up at 90° or near it, then the use of Euler angles falls apart. This is a degenerate case mathematically. In this realm, how is the device supposed to know if you're changing azimuth or roll?

函数SensorManager.remapCoordinateSystem()可用于操纵的变换矩阵,以补偿可能了解的设备的方向是什么。然而,我的实验已经表明,这并不包括所有的情况下,甚至没有一些常见的。例如,如果你想重新映射直立举行的设备(如拍照),你会希望通过这个矩阵乘以变换矩阵:

The function SensorManager.remapCoordinateSystem() can be used to manipulate the transformation matrix to compensate for what you may know about the orientation of the device. However, my experiments have shown that this doesn't cover all cases, not even some of the common ones. For example, if you want to remap for a device held upright (e.g. to take a photo), you would want to multiply the transformation matrix by this matrix:

1 0 0
0 0 1
0 1 0

调用getOrientation(),这是不定向的一个重映射的remapCoordinateSystem()支持[有人请纠正我,如果我错过了一些东西在这里]之前。

before calling getOrientation(), and this is not one of the orientation remappings that remapCoordinateSystem() supports [someone please correct me if I've missed something here].

好了,这一切一直是说,如果你使用的方向,无论是从TYPE_ORIENTATION传感器或getOrientation(),你可能做错了一口长气路。你的唯一一次真正的希望欧拉角是一个用户友好的形式显示方位信息,注释照片,驾驶飞行仪表显示器,或者类似的东西。

OK, so this has all been a long-winded way of saying that if you're using orientation, either from the TYPE_ORIENTATION sensor or from getOrientation(), you're probably doing it wrong. The only time you actually want the Euler angles is to display orientation information in a user-friendly form, to annotate a photograph, to drive flight instrument display, or something similar.

如果你想要做的与设备方向的计算,你几乎可以肯定最好使用变换矩阵与向量的XYZ工作。

If you want to do computations related to device orientation, you're almost certainly better off using the transformation matrix and working with XYZ vectors.

工作的顾问,每当有人向我提供涉及欧拉角,我回来了,并问他们是什么样的真正的试图做的,然后找到一个方法来做到这一点的一个问题与载体代替。

Working as a consultant, whenever someone comes to me with a problem involving Euler angles, I back up and ask them what they're really trying to do, and then find a way to do it with vectors instead.

回顾你原来的问题,getOrientation()应该(从弧度转换后)在[-180 180] [-90 90]和[-180 180]返回三个值。在实践中,我们认为方位的号码[0 360),所以你应该简单地增加360到您收到任何负数。您的code看起来正确的,因为写的。这将有助于如果我清楚地知道什么样的结果你期待,你都拿到吧。

Looking back at your original question, getOrientation() should return three values in [-180 180] [-90 90] and [-180 180] (after converting from radians). In practice, we think of azimuth as numbers in [0 360), so you should simply add 360 to any negative numbers you receive. Your code looks correct as written. It would help if I knew exactly what results you were expecting and what you were getting instead.

编辑补充:一对夫妇更多的心思。 Android的现代版本都使用一种叫传感器融合,这基本上意味着所有可用的输入 - acceleromter,磁强计,陀螺仪 - 结合在一起的数学黑盒子(通常是卡尔曼滤波器,而是取决于供应商)。所有不同的传感器 - 加速,磁场,陀螺仪,重力,线性加速度和方向 - 从这个黑匣子作为输出

Edited to add: A couple more thoughts. Modern versions of Android use something called "sensor fusion", which basically means that all available inputs -- acceleromter, magnetometer, gyro -- are combined together in a mathematical black box (typically a Kalman filter, but depends on vendor). All of the different sensors -- acceleration, magnetic field, gyros, gravity, linear acceleration, and orientation -- are taken as outputs from this black box.

只要有可能,你应该使用TYPE_GRAVITY,而不是TYPE_ACCELEROMETER作为输入到getRotationMatrix()。

Whenever possible, you should use TYPE_GRAVITY rather than TYPE_ACCELEROMETER as the input to getRotationMatrix().

这篇关于传感器TYPE_ACCELEROMETER / TYPE_MAGNETIC_FIELD和TYPE_ORIENTATION之间不同的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆