获取旋转并以度数显示

11

我需要的东西非常简单,但我找不到一个合适的例子来学习。我的唯一目的是:


设备平放在桌子上时,X和Y轴应该显示为0(或接近于0)。当我从顶部(扬声器所在部分)抬起它时,底部(麦克风所在部分)保持不动 - 它应该向我显示手机倾斜的角度。数学上描述 - 显示手机背面与桌子之间的夹角,其中一个轴线上。当我举起底部(而顶部保持不动)时,显示负度数。

对于另一个轴也是如此 - 围绕其长边旋转手机。


我尝试从不同的示例中组装应用程序,使用陀螺仪、加速度计或旋转向量传感器,但无法得到正常工作的东西。

有人能给我一个onSensorChanged函数的例子(因为所有的工作都在这里完成),并告诉我使用了哪个传感器,以便我知道要注册哪个传感器吗?

2个回答

19

网络上有一些示例和教程,但要小心。 Sensor.TYPE_ORIENTATION 已被弃用。您需要通过监听这两个传感器 Sensor.TYPE_ACCELEROMETERSensor.TYPE_MAGNETIC_FIELD 来计算旋转。

在注册接收这些传感器的通知后,棘手的部分就是如何处理从它们接收到的数据。关键部分如下:

public void onSensorChanged(SensorEvent event) {
    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
       mGravity = event.values;

    if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
       mGeomagnetic = event.values;

    if (mGravity != null && mGeomagnetic != null) {
       float R[] = new float[9];
       float I[] = new float[9];

       boolean success = SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic);
       if (success) {
          float orientation[] = new float[3];
          SensorManager.getOrientation(R, orientation);
          azimuth = orientation[0]; // orientation contains: azimuth, pitch and roll
          pitch = orientation[1];
          roll = orientation[2];
       }
    }
}

onSensorChanged(SensorEvent event) 回调函数中计算设备的方位角、俯仰角和翻滚角时,需要注意 "三个角度都是以弧度表示,并且以逆时针方向为正方向"。你可以使用 Math.toDegrees() 简单地将它们转换为度数。

如 Louis CAD 在评论中指出的那样,最好将 I、R 和 orientation 数组的初始化移出 onSensorChanged 回调函数,因为该函数会频繁调用。创建这些数组再将其留给 GC 处理不利于应用程序性能。为了简单起见,我在此处保留了它们。

根据设备的旋转方式,您可能需要重新映射坐标以获得所需的结果。您可以在Android文档中阅读有关remapCoordinateSystemgetRotationMatrixgetOrientation的更多信息。

示例代码:http://www.codingforandroid.com/2011/01/using-orientation-sensors-simple.html


1
嗨Csaba,我按照你的示例进行了操作,它提供了非常可靠的值,但是我想让这些值在顺时针方向上为正,这可能吗?我需要对您现有的代码进行哪些更改? - Parag Kadam
@ParagKadam 我猜你只需要从360中减去逆时针度数,就可以得到顺时针度数,如下所示: float clockwise = 360 - counterClockwise; 因此,如果逆时针值为15,则顺时针值为345。 - Csaba Szugyiczki
2
在性能方面,频繁调用方法中创建新对象(new float[])是不好的。您应该将这些本地数组移动到成员中。 - Louis CAD
1
谢谢@LouisCAD,这是一个很好的观点。我已经在答案中加入了一条注释,指出使用局部数组而不是成员数组会带来性能惩罚。 - Csaba Szugyiczki
你好朋友 - 我测试过了,传感器方向很好。@CsabaSzugyiczki 你知道我如何使结果更平滑吗? - ehsan wwe
1
@ehsanwwe 你可以使用一个简单的低通滤波器来解决这个问题。如果你搜索“平滑传感器数据”,你可以找到很多很好的答案,例如这个链接:link - Csaba Szugyiczki

0

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