【问题标题】:How to detect an absolute rotation of an android device如何检测安卓设备的绝对旋转
【发布时间】:2015-10-27 12:23:05
【问题描述】:

我希望使用在安卓设备上运行的软件来实现一个在室内导航的机器人。一项强制性功能是“实时”了解机器人的方向。

我有一个主要限制:android 设备应该在重力轴上放置一个屏幕(这意味着:垂直,就像用设备上的相机拍照一样)

这使我无法使用方位角,这是获取参考角度的最常用测量方法。使用没有意义:

SensorManager.getRotationMatrixFromVector(mRotationMatrixFromVector, event.values);

然后

SensorManager.getOrientation(mRotationMatrix, orientation);

因为应该提供方位角的orientation[0]不一致。

我一直在寻找,但在这里我没有找到任何可以接受的解决方案。

“可接受的解决方案”是系统响应在 100 毫秒内且精度接近 5°。参考不一定是磁北,但它必须随着时间的推移保持稳定。它可以是一个起始位置(但有一些漂移问题......)

除了 TYPE_ROTATION_VECTOR 之外,还有其他类型的传感器更适合这种用途吗?我正在尝试使用 TYPE_GYROSCOPE,但效果不佳...

我的安卓设备是 Google Tango 平板电脑。

感谢您的帮助

【问题讨论】:

    标签: android localization google-project-tango


    【解决方案1】:

    如果您只关心任何参考帧中的方位角,那么 Tango 提供的信息就是您想要的——具体来说,Tango.OnTangoUpdateListener.onPoseAvailable 提供的TangoPoseData(在请求帧对 COORDINATE_FRAME_AREA_DESCRIPTION、COORDINATE_FRAME_DEVICE 之后)包含一个四元数,表示相对于区域描述参考框架的设备方向。四元数基本上是一种旋转操作。如果您在设备的框架中选择所需的向量(例如,指向屏幕外的向量),四元数将允许您将该向量旋转到区域描述(世界)参考框架中。该旋转向量是原始向量指向世界的方向,您可以通过取向量的两个水平分量的 atan2 来确定方位角。有关 Tango 参考框架的更多信息,请参阅here

    这个问题也应该有一个更简单的答案。磁力计传感器应该能够提供平板电脑相对于地球磁场的绝对方向,地球磁场大致指向北方——这几乎是任何 Android 设备都可以做到的。您可以根据三个原始磁力计传感器值构建自己的方向,但 Android 提供了一种更方便的方式来访问融合传感器:SensorManager 中的Sensor.TYPE_ROTATION_VECTOR。但是,Tango 平板电脑存在软件问题,导致其磁力计无法工作;有关详细信息,请参阅here。专为导航设计的设备无法确定其绝对方位角,这真是令人失望。

    如果 SensorManager 的 TYPE_ROTATION_VECTOR 确实在 Tango 平板电脑上工作,您可以使用 SensorManager.getRotationMatrixFromVector 从 onSensorChanged 中返回的四元数中获取 3x3 旋转矩阵,然后使用 SensorManager.getOrientation 获取设备的“方位角”(如您所示在你的问题中)。但是,这种方法有些限制,因为当平板电脑的屏幕朝上时,这种方法有gimbal lock。当您选择自己的矢量并使用四元数将其旋转到世界坐标时,然后根据三个坐标中的两个计算方位角,这样您就可以更具体地了解“方位角”的确切含义。

    【讨论】:

      【解决方案2】:

      @Ben : 感谢您的完整回答。

      这解释了为什么我尝试从 TYPE_ROTATION_VECTOR 获取方位角在 Tango 平板电脑上失败(部署在其他设备上的相同代码运行良好)

      您建议的解决方案与我在浏览 Tango 库代码时根据经验找到的解决方案很接近:

      float[] position = pose.getTranslationAsFloats(); Quaternion q = new Quaternion(pose.rotation[3], pose.rotation[0], pose.rotation[1], pose.rotation[2]); double currentRoll = Math.toDegrees(q.getRoll()); robotCommander.updateCoordonates(position[0], position[1], currentRoll);

      X 是position[0],Y 是position[1]currentRoll 是机器人的当前方向。

      我对这个解决方案有一些问题:

      • 这是一个相对测量,我第一次得到四元数时,currentRoll 设置为 0,下一个角度是相对于原始位置的。当我的机器人丢失时,我没有绝对重新定位测量值。

      • 有一个重要的偏差。我仍然没有尝试将我的代码与区域描述文件 (ADF) 一起使用:这是下一步(可能对上一点也有用)

      • currentRoll 永远不会达到 180° (?)

      • 我不能 100% 确定我的代码是使用姿势数据的正确方法。

      你提到旋转的向量是原始向量指向世界的方向,你可以通过向量的两个水平分量的atan2来确定方位 >>你有吗任何指针或代码示例?

      感谢您的任何帮助或建议。

      【讨论】:

        猜你喜欢
        • 2017-04-13
        • 1970-01-01
        • 2013-01-12
        • 1970-01-01
        • 2018-10-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多