找到你要的答案

Q:why is my headingValue such diffrent from bearingValue while looking at targetLocation?

Q:为什么我的headingvalue等不同于bearingvalue看着目标?

In my Android application I have to use my current heading (using accelerometer and magnetometer) and current bearing to targetLocation (location.bearingTo(targetLocation)).

I already know that using accelerometer and magnetometer to figure out current heading starts at 0° on magnetic North and current Bearing starts on geographical North. So i figured out, that i have to add to headingValue, depending on my current location, a value called declination.

For example, I pick up a certain GPS point from google-maps, adding this point as locationpoint in the application. Starting application, moving before measuring the device like a infinity-sign in the air and holding the device in front of me focused in target direction. So i notice that heading != bearing. Can anyone explain to me the error? Assume that i tried different distances between 50 and 3 meters and that my device is calibrated correctly. Below are important methods of source code:

@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()));

}

UPDATE

Picture: https://pl.vc/1r6ap

The orange marked position is targetLocation. Both position are heading to targetLocation. Can you agree that these results are quiet correctly displayed?

During creation of this pic, i've noticed that both white marks are not equal to positions i was standing at. It seems like bad gps data is the reason because of the problem, isnt it?

在我的Android应用程序我用我目前航向(使用加速度计和磁力计)和当前目标定位(定位轴承。bearingto(目标))。

我已经知道,使用加速度计和磁强计来计算当前航向在磁北0°开始,电流轴承开始于北半球。所以我想通了,我要补充headingvalue,根据我目前的位置,一个称为磁偏角。

例如,我拿起从谷歌地图的GPS点,加上这一点在应用locationpoint。启动应用程序,移动之前测量设备像一个无限的迹象,在空气中,并保持在我前面的设备集中在目标方向。所以我注意到标题!=轴承。谁能向我解释错误?假设我尝试了不同的距离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

The orange marked position is targetLocation. Both position are heading to targetLocation. Can you agree that these results are quiet correctly displayed?

在这张照片的制作过程中,我注意到两个白色的标记都不等于我所站的位置。好像GPS数据不好是因为问题的原因,不是吗?

answer1: 回答1:

Heading is the direction where you look, e.g a tank in which direction it would shoot, while bearing is the direction this vehicle moves. So that should answer why bearing is not heading. They have different names, and meanings, they are different caluclated, they could not be expected to deliver the same value.

More details

You can move North (bearing = North) , but look at NE. (heading)

  • Gps delivers bearing (or course (over ground)), the direction the vehicle moves (altough some Api wrongly call it heading)

  • Compass (=magnetometer) delivers the direction in which you hold the device = (heading)

When you calculate the bearing between the two locations defined as coordinates in lat,lon , as you do in targetLocation (location.bearingTo(targetLocation)). then this is bearing! It is not heading!

And neither the compass not the accelrometer will deliver a decent heading value. Some android device are very wrong in their magnetomter ( I saw +-20 degrees compared to +/- 2 degrees of my iPhone., Always use a traditional high quality compass as reference) The ios devices shows the heading well within +/- 2 degress when well calibrated, (you have to calibrate each time before looking at the decice value, not only when you are asked by the operating system to calibrate).
GPS when moving > 10 km(h delives goot bearing results, but not heading.

Magnetometer can be off by some degree even when calibrated. And usually the declination is smaller than the error. Declination is nearly nothing in europe, 3 degress very north (europe), only a few places have a high declination >6-7°(north alaska)

Update to your further explantion in your graphic:

You have placed two points with a distance of only 15m, while GPS will not be much more acurate than 3-6m. So imagine 6m offset of start or destination: such a triangle where a = 6m, b = 15, has an angle of atan2(6 / 15.0) = 21°. So you have an offset of 21° only by inacuracy of location. However still think at the differnce of heading by compass and bearing by line of sight between two locations.

Heading is the direction where you look, e.g a tank in which direction it would shoot, while bearing is the direction this vehicle moves. So that should answer why bearing is not heading. They have different names, and meanings, they are different caluclated, they could not be expected to deliver the same value.

更多的细节

您可以移动北(轴承=北),但看东北。(标题)

  • GPS提供的轴承(或课程(地)),方向移动(尽管一些API错误称之为标题)

  • 指南针(=磁力计)提供的方向,你持有的设备=(标题)

当你计算两个位置定义为坐标LAT,离子之间的轴承,如你在目标位置(位置。bearingto(目标))。然后这是轴承!它不是标题!

And neither the compass not the accelrometer will deliver a decent heading value. Some android device are very wrong in their magnetomter ( I saw +-20 degrees compared to +/- 2 degrees of my iPhone., Always use a traditional high quality compass as reference) The ios devices shows the heading well within +/- 2 degress when well calibrated, (you have to calibrate each time before looking at the decice value, not only when you are asked by the operating system to calibrate).
GPS when moving > 10 km(h delives goot bearing results, but not heading.

Magnetometer can be off by some degree even when calibrated. And usually the declination is smaller than the error. Declination is nearly nothing in europe, 3 degress very north (europe), only a few places have a high declination >6-7°(north alaska)

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

You have placed two points with a distance of only 15m, while GPS will not be much more acurate than 3-6m. So imagine 6m offset of start or destination: such a triangle where a = 6m, b = 15, has an angle of atan2(6 / 15.0) = 21°. So you have an offset of 21° only by inacuracy of location. However still think at the differnce of heading by compass and bearing by line of sight between two locations.

java  android  gps  heading  bearing