【问题标题】:How to retrieve high quality compass orientation (as in Google Maps)?如何检索高质量的指南针方向(如在谷歌地图中)?
【发布时间】:2017-05-25 11:43:06
【问题描述】:

我发现所有在 Android 中获取指南针方向的指南都有一个错误:当您以纵向模式握住手机并“看”地平线上方时,指南针箭头会从正确的方向旋转 180 度。

谷歌地图方向指示器没有这个问题。

谷歌地图的另一个好处是他们以某种方式估计罗盘的准确性。知道他们是怎么做到的吗?

【问题讨论】:

  • 我认为这个库可以给你一个很好的想法来实现一个指南针并自己计算方向。我在使用时没有遇到您的问题。它总是向我展示正确的方向。 github.com/artemiygrn/Compass-View 对于指南针精度,我不知道如何实现。对不起兄弟。
  • 几行代码就可以解决手机“pitch”方向的问题,见here。然而,即使经过多天的搜索,我也没有发现谷歌地图确定准确性的能力。 Android API 不断报告SENSOR_STATUS_ACCURACY_HIGH

标签: android android-sensors compass-geolocation


【解决方案1】:

您问的错误是由于欧拉角引起的或称为万向节锁定。

为了解决非常大的角度差,您应该检查您的设备是否平坦或在使用重力传感器获得倾斜度或从带有低通滤波器的加速度计获得重力后不检查倾斜度。如果它不是平坦的(AR 应用程序或倾斜度>25 || 倾斜度

SensorManager.getRotationMatrixFromVector(rotationMatrix, event.values);
SensorManager.remapCoordinateSystem(rotationMatrix, SensorManager.AXIS_X, SensorManager.AXIS_Z, remappedRM);
SensorManager.getOrientation(remappedRM, orientation);

这解决了万向节锁定问题,但是,我在 Play 商店中看到的 3D 罗盘(普通罗盘不会给出正确的结果,因为它们只映射到 x,y 并发生万向节锁定),这里的每个代码都有差异当您将设备平放或屏幕指向您时。这种差异有时会达到 10 度。我无法解决它。大多数差异在 1-5 度之间,但我有时会看到它上升到 10 度,这是不可接受的。

Google 从您的位置测量方位角。有一个代码可以找到方位。

currentLocation.getBearing();

经纬度的准确度(您当前位置的准确度)决定方位的准确度。

按顺序排列指南针最准确到最少的方法

  1. 使用 GPS/Wife(Google 的融合位置)位置并从位置获取方位
  2. 使用旋转矢量(需要磁场传感器,你应该检查它是否可用),它是一个融合传感器(磁场+陀螺仪+加速度计和软件部分)并使用卡尔曼滤波器来平滑值,但检查倾斜度以重新映射方向李>
  3. 重力/加速度计+磁场传感器。这会附加一个可怕的噪音,为了平滑它,你应该使用移动平均或低通滤波器(这不是为了隔离重力,它是为了使用阈值频率来防止跳高)

【讨论】:

    【解决方案2】:
    1. 俯视地平线时出现错误。

    使用指南针时有一些棘手的部分。 指南针方向取决于磁场和手机方向,因此,为了纠正偏差,您需要进行一些矩阵运算。

    查看这篇文章,它提供了一个简单的例子 -> https://www.journal.deviantdev.com/android-compass-azimuth-calculating/

    对文章的解释是:“因此,如果设备没有保持平坦(∓45° 偏差),您必须以一种有用的方式使用 remapCoordinateSystem() 以获得正确的结果。”

    1. 准确度。

    首先,准确性取决于设备中存在的物理组件。碎片化是这里的一个常见问题。三星的磁力计与 LG 的不同,Android 系统不会将您抽象出来。

    另一方面,设备可能依赖于不同类型的传感器:硬件或传感器融合。因此,您将尝试一种设备与其他设备之间的差异。

    所以这是一团糟。但它存在一些您可以应用的技术,以便从传感器获取准确性和统一的数据(不仅适用于指南针,也可能适用于 GPS)。

    1. 有些人会丢弃最初几秒钟的传感器数据。校准信号需要一些时间,因此检索到的第一个数据使用有一些偏差。需要丢弃的时间再次取决于制造商,购买我会在 5 秒左右尝试。

    2. 使用插值器和外插器。 android 中的许多传感器为您提供了一种每隔特定毫秒检索数据的方法。但这是Android提供的抽象。 Harward 传感器有自己的时间,它们会在认为有必要时更新信号。其余时间,当 Android 向传感器询问信号数据时,传感器返回最后一个值,或者可能是对制造商提供的最后一个信号数据的某种操作(再次)。

    所以,有一些抽象层(插值器/外插器)很有趣,它们每 20、50、1000 次从 Android 系统接收数据......这个层为了有一定的一致性而进行一些操作,然后与数据到您的应用程序。

    这里的操作可以是当前值和上一个值之间的某种平均值、累积平均值或者可能是另一种归一化。

    【讨论】:

      【解决方案3】:

      好的,我自己想通了。首先,您需要从指南针计算方位。然后可以旋转 Maps api-2 相机。

      public void updateCamera(float bearing) {
                  CameraPosition currentPlace = new CameraPosition.Builder()
                          .target(new LatLng(centerLatitude, centerLongitude))
                          .bearing(bearing).tilt(65.5f).zoom(18f).build();
                  googleMap.moveCamera(CameraUpdateFactory.newCameraPosition(currentPlace));
      
          }
      

      在您的代码中设置 SensorListener 并在 onSensorChanged 事件中调用此方法。我添加了一个倾斜值,因此地图将以 3D 旋转。

      [参考:] [Android Maps v2 rotate mapView with compass1

      如果您可以了解更多详情http://www.techotopia.com/index.php/Working_with_the_Google_Maps_Android_API_in_Android_Studio

      【讨论】:

        【解决方案4】:

        指南针会给你你想要的,但它太吵了。噪音有两个原因,其中一个原因是,它正在拾取,真正的噪音,真正的信号。所以,我们生活在一个磁性非常嘈杂的环境中。所以,这个罗盘,捡起所有有磁性的东西。另一个原因是,它没有集成,因此没有降低频率分量的好处。因此,请尝试将您的指南针与陀螺仪数据结合起来。 This 视频将对您使用这些传感器有很大帮助。

        更多细节,您也可以组合加速度计。总而言之,陀螺仪提供方向,加速度计提供重力校正,罗盘提供磁北校正。

        【讨论】:

        • 嘿,谢谢,但这并不能回答我的问题(1. 俯视地平线时出现错误 2. 准确性)。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-09-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多