0

在我的 Android 应用程序中,我必须使用当前航向(使用加速度计和磁力计)和当前方位targetLocationlocation.bearingTo(targetLocation))。

我已经知道使用加速度计和磁力计来确定当前航向从磁北的 0° 开始,当前方位从地理北开始。所以我发现,我必须headingValue根据我当前的位置添加一个称为偏角的值。

例如,我从 google-maps 中获取了某个 GPS 点,并将该点作为位置点添加到应用程序中。开始应用程序,在测量设备之前移动,就像空中的无限符号一样,将设备放在我面前,专注于目标方向。所以我注意到标题!=轴承。谁能向我解释这个错误?假设我尝试了 50 到 3 米之间的不同距离,并且我的设备已正确校准。以下是源代码的重要方法:

@Override
public void onSensorChanged(SensorEvent event) {

        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
            mGravity = event.values.clone();
        if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
            mGeomagnetic = event.values.clone();
        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);

                double tempAzimuth = Math.toDegrees(orientation[0]); // orientation contains: azimut, pitch and roll

                if(tempAzimuth < 0){
                    currentHeading = tempAzimuth + 360;
                } else {
                    currentHeading = tempAzimuth;
                }
                TVheadingMag.setText(""+String.format( "%.2f",currentHeading)+"°");
            }
        }

    }

@Override
public void onLocationChanged(Location location) {

    //Declination http://stackoverflow.com/questions/4308262/calculate-compass-bearing-heading-to-location-in-android
    geoField = new GeomagneticField(
            Double.valueOf(location.getLatitude()).floatValue(),
            Double.valueOf(location.getLongitude()).floatValue(),
            Double.valueOf(location.getAltitude()).floatValue(),
            System.currentTimeMillis());

    if(location.bearingTo(this.target)<0){
        currentBearing = location.bearingTo(this.target)+360;
    } else {
        currentBearing = location.bearingTo(this.target);
    }

    headingWithDeclination = currentHeading;
    headingWithDeclination += geoField.getDeclination();


    currentDistance = location.distanceTo(this.target);

    TVheading.setText(""+String.format( "%.2f", headingWithDeclination)+"°");
    TVheadingMag.setText(""+String.format( "%.2f",currentHeading)+"°");

    TVbearing.setText(""+String.format( "%.2f",currentBearing)+"°");
    TVgps.setText(""+ String.format( "%.6f",location.getLatitude()) + "   " + String.format( "%.6f",location.getLongitude()));

}

更新

图片:https ://pl.vc/1r6ap

橙色标记的位置是 targetLocation。两个位置都指向 targetLocation。您是否同意这些结果正确显示?

在创建这张照片期间,我注意到两个白色标记都不等于我站立的位置。看起来糟糕的gps数据是问题的原因,不是吗?

4

1 回答 1

1

航向是您看的方向,例如坦克将朝哪个方向射击,而方位是该车辆移动的方向。所以这应该回答为什么轴承没有标题。它们有不同的名称和含义,它们的计算方式不同,不能期望它们提供相同的价值。

更多细节

您可以向北移动 (bearing = North) ,但看看 NE。(标题)

  • Gps 提供方位(或航向(在地面上)),车辆移动的方向(尽管有些 Api 错误地将其称为航向)

  • 指南针(=磁力计)提供您握住设备的方向=(航向)

当您计算定义为 lat,lon 坐标的两个位置之间的方位角时,就像您在其中所做的那样, targetLocation (location.bearingTo(targetLocation)).这就是方位角!它不是标题!

指南针和加速度计都不会提供不错的航向值。一些 android 设备的磁力计非常错误(我看到 +-20 度,而我的 iPhone 的 +/- 2 度。始终使用传统的高质量指南针作为参考) ios 设备在 +/- 2 内显示航向校准良好时下降,(您必须每次在查看 decice 值之前进行校准,而不仅仅是在操作系统要求您校准时)。
GPS 移动 > 10 公里(h 提供良好的方位结果,但不是航向。

即使校准后,磁力计也可能会在一定程度上关闭。并且通常偏角小于误差。在欧洲,磁偏角几乎为零,极北 3 度(欧洲),只有少数地方的磁偏角 > 6-7°(阿拉斯加北部)

更新您在图形中的进一步解释:

您已经放置了两个距离仅为 15m 的点,而 GPS 不会比 3-6m 更准确。所以想象一下起点或终点的 6m 偏移:这样一个三角形,其中 a = 6m,b = 15,角度为 atan2(6 / 15.0) = 21°。因此,仅由于位置不准确,您的偏移量为 21°。然而,仍然认为两个位置之间的指南针航向和视线方位的差异。

于 2015-08-15T14:23:22.217 回答