Расчет GPS на очень короткие расстояния

gps

В настоящее время я работаю над проектом, включающим создание «системы оповещения о соблюдении дистанции между родителями и детьми» с использованием моей платы Flora + модуля Ultimate GPS (https://www.adafruit.com/product/1059). Я нахожусь на предварительной стадии и просто пытаюсь получить текущее положение модуля GPS, сравнивая его с предварительно зафиксированным положением (выраженным в десятичных координатах GPS, например, 40,779006, -74,289395), вычислить расстояние между этими двумя точками и, если расстояние превышает определенное значение, скажем, 20 метров, вывести на последовательный монитор предупреждающее сообщение. Мне удалось правильно получить местоположение модуля GPS (выраженное в десятичных координатах, как указано выше), но когда я пытаюсь рассчитать расстояние, мне не удается достичь точности в несколько метров.

Итак, мои вопросы:

  1. Существует ли конкретная/лучшая формула для расчета коротких расстояний (максимум 100 метров) на поверхности земли с точностью 2–3 метра? Я пробовал использовать формулу Гаверсина с не такими уж плохими результатами, но из-за дефицита точности Double (в процессорах ATMega она такая же, как и Float, т. е. 32 бита) мне удалось получить точность всего в 6-7 цифр (как указано в https://www.arduino.cc/en/Reference/Float). Эти приближения приводят к большим ошибкам в конечном значении расстояния.
  2. Как я могу быстро и точно обновить свое местоположение во время своего пути? Если я иду в каком-то направлении, я не смогу достаточно быстро получить обновление местоположения в виде координат широты и долготы.

Надеюсь, я выразился максимально ясно и объяснил свою проблему. Заранее спасибо всем, кто даст мне отзыв или предоставит любую информацию. Пожалуйста, проявите терпение к моему плохому английскому.

Филиппо

[ОБНОВЛЕНИЕ]

@EdgarBonet это именно то, что я искал!!! Огромное спасибо!

Подойдет ли мне простая библиотека GPS, ссылку на которую вы дали, если на моей плате Flora установлен процессор AtMega32u4 вместо упомянутого вами ATtiny85?

Последний вопрос: знаете ли вы, как быстрее я могу получить GPS-координаты? Я имею в виду, если я нахожусь в определенной позиции (например, X) и могу правильно получить свои GPS-координаты, затем я перемещаюсь на 5 метров вперед (например, X+5), когда я прибуду в позицию X+5, смогу ли я получить в течение нескольких секунд GPS-координаты X+5?

Еще раз огромное спасибо @EdgarBonet!!

В настоящее время я работаю над проектом, включающим создание «системы оповещения о соблюдении дистанции между родителями и детьми» с использованием моей платы Flora + модуля Ultimate GPS (https://www.adafruit.com/product/1059). Я нахожусь на предварительной стадии и просто пытаюсь получить текущее положение модуля GPS, сравнивая его с предварительно зафиксированным положением (выраженным в десятичных координатах GPS, например, 40,779006, -74,289395), вычислить расстояние между этими двумя точками и, если расстояние превышает определенное значение, скажем, 20 метров, вывести на последовательный монитор предупреждающее сообщение. Мне удалось правильно получить местоположение модуля GPS (выраженное в десятичных координатах, как указано выше), но когда я пытаюсь рассчитать расстояние, мне не удается достичь точности в несколько метров.

Итак, мои вопросы:

  1. Существует ли конкретная/лучшая формула для расчета коротких расстояний (максимум 100 метров) на поверхности земли с точностью 2–3 метра? Я пробовал использовать формулу Гаверсина с не такими уж плохими результатами, но из-за дефицита точности Double (в процессорах ATMega она такая же, как и Float, т. е. 32 бита) мне удалось получить точность всего в 6-7 цифр (как указано в https://www.arduino.cc/en/Reference/Float). Эти приближения приводят к большим ошибкам в конечном значении расстояния.
  2. Как я могу быстро и точно обновить свое местоположение во время своего пути? Если я иду в каком-то направлении, я не смогу достаточно быстро получить обновление местоположения в виде координат широты и долготы.

Надеюсь, я выразился максимально ясно и объяснил свою проблему. Заранее спасибо всем, кто даст мне отзыв или предоставит любую информацию. Пожалуйста, проявите терпение к моему плохому английскому.

Филиппо

[ОБНОВЛЕНИЕ]

@EdgarBonet это именно то, что я искал!!! Огромное спасибо!

Подойдет ли мне простая библиотека GPS, ссылку на которую вы дали, если на моей плате Flora установлен процессор AtMega32u4 вместо упомянутого вами ATtiny85?

Последний вопрос: знаете ли вы, как быстрее я могу получить GPS-координаты? Я имею в виду, если я нахожусь в определенной позиции (например, X) и могу правильно получить свои GPS-координаты, затем я перемещаюсь на 5 метров вперед (например, X+5), когда я прибуду в позицию X+5, смогу ли я получить в течение нескольких секунд GPS-координаты X+5?

Еще раз огромное спасибо @EdgarBonet!!

[ОБНОВЛЕНИЕ 2]

Метод DistanceBetween, рекомендованный мне @EdgarBonet, всегда возвращает мне 0, даже если я перемещусь на пару десятков метров.

Но, возможно, я ошибаюсь в передаче параметров. Должен ли я передавать параметры широты/долготы как десятичные координаты (например: 45.892829, 12.082583)? Если я не прав, в каком формате мне следует передавать параметры широты/долготы в метод DistanceBetween?

, 👍3

Обсуждение

Может быть, вы не сможете получить такую точность с выходными данными определения местоположения обычных GPS-устройств, а вам нужны устройства с поддержкой DGPS (или более сложные схемы), которые могут обмениваться своими необработанными показаниями данных, чтобы вычесть часть присущей системной ошибки, которая по сути одинакова в локальном регионе, оставляя только разницу в положении. Это действительно вопрос дифференциального GPS, а не вопрос Arduino — или, по крайней мере, не пытайтесь сделать это на Arduino, пока вы не убедитесь в другом месте, что вычисления на реальных выборочных данных дают полезный результат., @Chris Stratton

Почему бы не использовать радиосигнал ближнего действия, например Bluetooth. Соедините родителя и ребенка, а затем подавайте импульсный сигнал между ними. Как только несколько импульсов пропущены, поднимите тревогу на родительском конце. Это немного более неуклюже, если у вас 5 детей, но..., @Code Gorilla

У вас возникнут проблемы с получением желаемой точности. GPS с поддержкой SBAS даст вам ошибку определения местоположения около 1 м в идеальных условиях (и при условии, что у вас есть покрытие SBAS). В плохих условиях (неидеальное расположение антенны, много зданий/деревьев вокруг и т. д.) ожидайте погрешности в 5 м. Это для каждого устройства, поэтому удвойте ее для разницы в местоположении., @Andrew

@Filippo не имеет отношения к самому вопросу, но... Пожалуйста, избегайте использования нескольких учетных записей (особенно для добавления информации о вопросе, как вы сделали в ожидающемся редактировании)., @frarugi87

@CodeGorilla Это говорит вам, что они отклонились, но не говорит вам, в каком направлении они пошли. Это также будет очень специфично для окружающей среды, много людей вокруг будут поглощать сигналы и таким образом сокращать диапазон. Не обязательно плохо для этого приложения, но это не будет контролируемым эффектом., @Andrew

У вас есть два аккаунта? Похоже, вы предлагаете правки из аккаунта, который отличается от аккаунта, с которого вы изначально задали свой вопрос. Если вы свяжетесь с модераторами, они смогут объединить два аккаунта для вас., @Greenonline

@FilippoDamuzzo Re Update 2. Как указано на связанной странице Эти процедуры работают в единицах 1e-4 угловых минут. Таким образом, один градус представлен как 600 000 единиц Они делают это для того, чтобы все вычисления выполнялись как целые числа, что намного быстрее. Так что если у вас есть широта и долгота в градусах, то умножьте их на константу DEGREE, чтобы получить правильные результаты., @Andrew


4 ответа


2

Я успешно использовал Arduino + хобби GPS, чтобы получить точность в пределах нескольких метров с обновлением каждую секунду, используя обычную плавающую точку на Arduino. Это должно быть возможно.

32-битное число с плавающей точкой имеет точность 24 бита, а одна 2^24 половины окружности Земли составляет около 1,2 метра, так что теоретический предел примерно равен этому.

Если я правильно помню, вы получите лучшую точность на коротких расстояниях на 32-битном float, используя обычную 2D-тригонометрию, чем гаверсинус, но оба варианта должны работать.

Убедитесь, что вы правильно считываете данные с GPS, и снова просмотрите уравнения. Все ли правильно преобразовано в радианы для тригонометрии? Убедитесь, что в вашей версии PI достаточно цифр. Правильно ли вы анализируете выходное значение GPS как градусы+десятичные минуты? Это не просто число в десятичных градусах (как координаты Google Maps), если оно пришло из сообщения NMEA. Есть ли какие-либо команды запуска конфигурации, которые вам нужно отправить вашему устройству GPS?

Я думаю, что самое быстрое обновление, на которое можно рассчитывать, — это новые координаты каждую секунду, но я не использовал ваш конкретный GPS.

,

Эм... на самом деле, вам не нужно учитывать радиус Земли, а нужно учитывать полуокружность. Это означает, что максимальное разрешение для поплавка составляет около 1,2 метра..., @frarugi87

@frarugi87 вау, да, это глупая ошибка. Спасибо., @BrettAM


3

Формула гаверсина слишком избыточна для ваших нужд. В масштабе, который вы обеспокоены тем, что Земля по сути плоская, поэтому расстояние между двумя точками определяется стандартной декартовой формулой:

d = √(Δx2 + Δy2)

где Δx и Δy — расстояния по направлениям запад–восток и юг–север оси соответственно. Они могут быть вычислены из разниц в широта и долгота как

Δx = R Δλ cos(φ)
Δy = R Δφ

где φ — широта, λ — долгота (обе в радианах), а R — радиус Земли. Термин cos(φ) учитывает тот факт, что вдали от экватор, последовательные меридианы расположены ближе друг к другу, чем последовательные параллели. При вычислении этого косинуса не имеет значения, используйте широту любой точки.

Я предлагаю вам взглянуть на эту простую библиотеку GPS. Это было предназначенный для выполнения именно таких простых вычислений на небольшом Процессор AVR, например ATtiny85. Он должен отлично работать на вашем Flora. Функция, которую вы хотите, это DistanceBetween(). Она использует «локально плоский Приближение «Земли» выше, которое подходит только для расстояний до нескольких сто километров.

Несколько вещей, которые стоит отметить относительно этой библиотеки:

  • библиотека жертвует точностью ради эффективности: все в фиксированной точке и он использует полиномиальные приближения низкого порядка для cos(x) и √(x2 + y2)
  • углы даны в единицах 10−4 угловых минут, так как это что вы обычно получаете из предложения NMEA
  • DistanceBetween() возвращает расстояние как целое число метров, но вы можете легко изменить его, чтобы указать его в единицах полуметры, четверти метра и т.д.: просто замените значение 512 в последняя строка (return ... / 512;) на меньшую степень двойки.
,

Лично я бы не доверял модели "локально плоской Земли" для расстояний, значительно превышающих 10-20 км, и уж точно не для сотен км. Но это во многом зависит от того, что вы считаете достаточно хорошей точностью. Но, безусловно, достаточно хорошей для расстояний в этом вопросе., @Andrew

Но... Вы действительно уверены, что [Земля не плоская](https://wiki.tfes.org/Frequently_Asked_Questions)?, @frarugi87

@Andrew: Библиотека предназначена для приложений с низкой точностью. Например, она использует приближение cos(π/2 ⋅ x) ≈ 0,962(1 – x²), которое имеет максимальную погрешность около 0,038. При таком уровне точности приближение «локально плоской Земли» справедливо для довольно больших расстояний в средних широтах., @Edgar Bonet

@EdgarBonet Я, вероятно, просто слишком привык работать в среде, где погрешность в 1 см неприемлема ;-), @Andrew


0

Часть вопроса, связанная с расчетом разницы позиций, была обработана Эдгаром. Что оставляет заголовок дочерней части.

Чтобы определить, в каком направлении идет родитель, не используйте изменение положения. Используйте данные о направлении и скорости от GPS. Они будут гораздо точнее, чем расчет скорости на основе изменения положения.

Что касается частоты обновления, то она во многом зависит от используемого GPS. Тот, на который вы ссылаетесь, указывает, что поддерживает обновления с частотой 10 Гц, поэтому вы сможете получать обновления местоположения и направления 10 раз в секунду. По умолчанию будет 1 Гц, поэтому вам нужно будет отправить правильную команду конфигурации. Однако это значительно увеличит расход батареи.

Эти недорогие системы GPS обычно имеют значительную задержку, но значения, которые вы получаете в последовательном потоке, не должны быть старше 100 мс, что вполне достаточно для чего-то столь медленного, как идущий человек.

,

0

Возможно, вас заинтересует моя библиотека NeoGPS. Она меньше, быстрее, надежнее и точнее всех других библиотек. Она сохраняет полную точность местоположений GPS (10 значащих цифр) даже при расчетах расстояния и пеленга. NeoGPS использует равнопрямоугольное упрощение, предложенное Эдгаром, на малых расстояниях и переключается на гаверсинус на больших расстояниях. Как вы обнаружили, наивные вычисления с плавающей точкой (как и во всех других библиотеках) теряют эту точность на малых расстояниях.

Если вы хотите попробовать, NeoGPS доступен в менеджере библиотек Arduino IDE, в меню Скетч -> Подключить библиотеку -> Управление библиотеками.

,

Она меньше, быстрее, надежнее и точнее всех других библиотек Неправда. У меня есть библиотека, где позиция всегда 0,0. Она не очень точная, но она намного меньше и намного быстрее., @Andrew

Библиотека, на которую я ссылался в своем ответе, находится где-то между библиотекой @Andrew и NeoGPS, как по скорости, так и по точности., @Edgar Bonet

@Andrew, как и часы, которые показывают точные показания один раз в день, ваша библиотека будет оптимальной только в одном месте на Земле. ;), @slash-dev

@EdgarBonet, мне понравилось читать об этом проекте. Парсер по сути является пользовательским scanf... мило! Мне было любопытно, как версия NeoGPS будет выглядеть в сравнении. Она все еще помещается в ATtiny85, используя примерно половину оперативной памяти TinyNav (67 байт против 119), но почти вдвое больше места для программ (7746 байт против 4084). Подпрограммы NeoGPS Distance & Bearing требуют библиотеку с плавающей точкой., @slash-dev