Почему мой 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 ° только из-за неточности местоположения. Однако все же подумайте о разнице курса по компасу и направления по прямой видимости между двумя точками.