android - 如何通过罗盘读数和陀螺仪读数获得手机的方位角?

标签 android sensors android-sensors gyroscope magnetometer

我希望通过以下方法获取手机的当前方向:

  • 首先通过 getRotationMatrix() 获取初始方向(方位角)和 getOrientation() .
  • 添加陀螺仪读数随时间的积分以获得当前方向。

  • 电话定位:

    手机的 x-y 平面与接地平面平行固定。即,处于“边走边发短信”的方向。

    getOrientation()” 返回:

    Android API 让我可以轻松地从 getOrientation() 获取方向,即方位角、俯仰角、滚动角。 .

    注意 这个方法总是 返回范围内的值: [0, -PI] [o, PI] .

    我的问题:

    由于集成了陀螺仪读数,记为dR , 可能很大,所以当我做 CurrentOrientation += dR , CurrentOrientation可能超过 [0, -PI] [o, PI] 范围。

    需要进行哪些操作才能始终在 [0, -PI] 中获取当前方向和 [o, PI]范围?

    我在 Python 中尝试过以下方法,但我高度怀疑它的正确性。
    rotation = scipy.integrate.trapz(gyroSeries, timeSeries) # integration
    if (headingDirection - rotation) < -np.pi:
        headingDirection += 2 * np.pi
    elif (headingDirection - rotation) > np.pi:
        headingDirection -= 2 * np.pi
    # Complementary Filter
    headingDirection = ALPHA * (headingDirection - rotation) + (1 - ALPHA) * np.mean(azimuth[np.array(stepNo.tolist()) == i])
    if headingDirection < -np.pi:
        headingDirection += 2 * np.pi
    elif headingDirection > np.pi:
        headingDirection -= 2 * np.pi
    

    备注

    这不是那么简单,因为它涉及以下麻烦制造者:
  • 方向传感器读数来自 0-PI ,然后是 直接跳转+PI并逐渐回到0通过 +PI/2 .
  • 陀螺仪读数的集成也带来了一些麻烦。我应该添加dR到方向或减去dR .

  • 在给出确认答案之前,请先引用 Android 文档。

    估计的答案无济于事。

    最佳答案

    The orientation sensor actually derives its readings from the real magnetometer and the accelerometer.



    我想这也许是困惑的根源。这在文档中在哪里说明?更重要的是,文档是否明确指出陀螺仪读数被忽略?据我所知,该视频中描述的方法已实现:

    Sensor Fusion on Android Devices: A Revolution in Motion Processing

    这种方法使用陀螺仪并整合它们的读数。这几乎使问题的其余部分变得毫无意义。不过我会尽量回答。

    方向传感器已经为您集成了陀螺仪读数 ,这就是你获得方向的方式。我不明白你为什么要自己做。

    您没有正确集成陀螺仪读数 , 比 CurrentOrientation += dR 更复杂(这是不正确的)。如果您需要集成陀螺仪读数(我不明白为什么,SensorManager 已经为您完成了)请阅读 Direction Cosine Matrix IMU: Theory如何正确执行(公式 17)。

    不要尝试用欧拉角积分 (又名方位角、俯仰角、滚动角),不会有任何好的结果。

    请在计算中使用四元数或旋转矩阵而不是欧拉角。如果您使用旋转矩阵,您始终可以将它们转换为欧拉角,请参阅

    Computing Euler angles from a rotation matrix by Gregory G. Slabaugh

    (四元数也是如此。)(在非退化的情况下)有两种表示旋转的方式,即 你会得到两个欧拉角。选择您需要的范围内的那个。 (在 gimbal lock 的情况下,有无限多个欧拉角,请参见上面的 PDF)。只需保证在将旋转矩阵转换为欧拉角后,您不会在计算中再次开始使用欧拉角。

    目前尚不清楚您在使用互补过滤器做什么。 您可以基于 Direction Cosine Matrix IMU: Theory 实现非常好的传感器融合。手稿,基本上是一个教程。这样做并非易事,但我认为您不会找到比这份手稿更好、更易于理解的教程。

    当我根据这份手稿实现传感器融合时,我必须自己发现一件事是所谓的 integral windup可以发生。我通过绑定(bind) TotalCorrection 来处理它(第 27 页)。如果你实现了这个传感器融合,你就会明白我在说什么。



    更新:在这里,我回答您在接受答案后在评论中发布的问题。

    I think the compass gives me my current orientation by using gravity and magnetic field, right? Is gyroscope used in the compass?



    是的,如果手机或多或少静止至少半秒钟,您可以仅使用重力和指南针来获得良好的方向估计。操作方法如下:Can anyone tell me whether gravity sensor is as a tilt sensor to improve heading accuracy?

    不,指南针中不使用陀螺仪。

    Could you please kindly explain why the integration done by me is wrong? I understand that if my phone's pitch points up, euler angle fails. But any other things wrong with my integration?



    有两件不相关的事情:(i)积分应该以不同的方式进行,(ii)由于万向节锁,欧拉角很麻烦。我再说一遍,这两个是无关的。

    至于集成:这是一个简单的示例,您可以如何实际查看集成有什么问题。设 x 和 y 为房间内水平面的轴。 Handlebars 机拿在手里。将手机绕 x 轴(房间)旋转 45 度,然后绕 y 轴(房间)旋转 45 度。然后,从头开始重复这些步骤,但现在先绕 y 轴旋转,然后绕 x 轴旋转。手机最终以完全不同的方向结束。如果按照 CurrentOrientation += dR 做积分你会发现没有区别!如果您想正确进行积分,请阅读上面链接的方向余弦矩阵 IMU:理论手稿。

    至于欧拉角:它们破坏了应用程序的稳定性,我不使用它们进行 3D 中的任意旋转就足够了。

    我还是不明白你为什么要自己做,为什么不想使用平台提供的方向估计。机会是,你不能做得比这更好。

    关于android - 如何通过罗盘读数和陀螺仪读数获得手机的方位角?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18073680/

    相关文章:

    android - 在android中创建会说话的头像

    android - 如何在没有加速度计传感器的情况下启动相机 Intent ?

    android - 使用 Flutter 从 Wear OS 可穿戴设备读取传感器数据

    后台Android连续加速处理

    java - 通用传感器名称

    android - 加速度计与重力传感器

    java - Android Developer Page中mPlaceHolderBitmap的值是多少?

    c# - 如何从 Xamarin.Forms 中的 AndroidManifest.xml 访问元数据

    安卓数据绑定(bind) : @BindingAdapter in Kotlin does not recognize lambdas

    android - 是否可以仅使用加速度计让智能手机移动距离?