如何检测Android设备的绝对旋转

时间:2015-10-27 12:23:06

标签: android localization google-project-tango

我正在寻找使用Android设备上运行的软件实现在室内导航的机器人。一个强制性功能是“实时”了解机器人方向。

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

这使我无法使用azimut,这是获得参考角度的最常用方法。使用它是没有意义的:

SensorManager.getRotationMatrixFromVector(mRotationMatrixFromVector, event.values);

然后

SensorManager.getOrientation(mRotationMatrix, orientation);

因为 orientation [0] 应该提供azimut不一致。

我现在正在寻找很长时间,但我在这里找不到任何可接受的解决方案。

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

是否有其他类型的传感器比 TYPE_ROTATION_VECTOR 更适合此用途?我正在尝试使用 TYPE_GYROSCOPE ,但效果不佳......

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

感谢您的帮助

2 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:0)

@Ben : 谢谢你的完整答案。

这解释了为什么我尝试从TYPE_ROTATION_VECTOR获取azimut在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来确定方位角>>你有这个指针或代码示例吗?

感谢您提供任何帮助或建议。