Почему мой headingValue отличается от BearingValue при взгляде на targetLocation?

В моем приложении для Android я должен использовать свой текущий курс (с использованием акселерометра и магнитометра) и текущий азимут для targetLocation (location.bearingTo(targetLocation)).

Я уже знаю, что использование акселерометра и магнитометра для определения текущего курса начинается при 0° на магнитном севере, а текущий подшипник начинается на географическом севере. Итак, я понял, что я должен добавить к headingValue, в зависимости от моего текущего местоположения, значение называется склонением.

Например, я выбираю определенную точку GPS из Google-карт, добавляя эту точку в качестве точки местоположения в приложении. Запускаю приложение, двигаюсь перед тем, как измерять устройство, как знак бесконечности в воздухе, и держу устройство передо мной, сфокусированное в направлении цели. Так что я заметил, что заголовок!= Подшипник. Может кто-нибудь объяснить мне ошибку? Предположим, что я пробовал разные расстояния между 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://stackru.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 являются причиной из-за проблемы, не так ли?

1 ответ

Решение

Направление - это направление, в котором вы смотрите, например танк, в каком направлении он будет стрелять, а направление - это направление движения этого транспортного средства. Так что это должно ответить, почему подшипник не движется. У них разные имена и значения, они рассчитаны по-разному, от них нельзя ожидать, что они дадут одно и то же значение.

Подробнее

Вы можете двигаться на север (азимут = север), но посмотрите на NE. (Заголовок)

  • GPS обеспечивает направление (или курс (над землей)), направление движения автомобиля (хотя некоторые Api ошибочно называют его курсом)

  • Компас (= магнитометр) выдает направление, в котором вы держите устройство = (курс)

Когда вы вычисляете направление между двумя точками, определенными как координаты в широте, долготе, как вы делаете в targetLocation (location.bearingTo(targetLocation)). тогда это подшипник! Это не заголовок!

И ни компас, ни акселерометр не дадут достойного значения курса. Некоторые андроид-устройства очень не правы в своем магнитометре (я видел +-20 градусов по сравнению с +/- 2 градусами моего iPhone. Всегда используйте в качестве эталона традиционный высококачественный компас) Устройства ios показывают курс в пределах +/- 2 спада при правильной калибровке (необходимо выполнять калибровку каждый раз, прежде чем смотреть значение дециметра, а не только тогда, когда операционная система запрашивает калибровку).
GPS при движении> 10 км (h показывает результаты, полученные с помощью Goot, но не курс.

Магнитометр может быть отключен в некоторой степени даже при калибровке. И обычно склонение меньше ошибки. Склонение почти ничто в Европе, 3 градуса на севере (Европа), только в нескольких местах высокое склонение>6-7°(север Аляски)

Обновите свое дальнейшее объяснение на графике:

Вы разместили две точки на расстоянии всего 15 метров, в то время как GPS будет не более точным, чем 3-6 метров. Итак, представьте смещение на 6 м от начала или пункта назначения: такой треугольник, где a = 6 м, b = 15, имеет угол atan2(6 / 15,0) = 21°. Таким образом, у вас есть смещение 21 ° только из-за неточности местоположения. Однако все же подумайте о разнице курса по компасу и направления по прямой видимости между двумя точками.

Другие вопросы по тегам