После экспериментов с искуственным интеллектом автопилот моего танка решил сделать шаг назад и научиться ориентироваться по старым добрым спутникам.

Картинка постановочная, намекающая, что всякий GPS транспорт умеет самостоятельно топиться под управлением навигатора.



Raspberry Pi + GPS


Сначала был закуплен простой USB-модуль GPS.

Руководствуясь статьей на Адафрукте, я приступил к внедрению.

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

Не совпали лишь некоторые нюансы:

  • железяка была обнаружена как /dev/ttyACM0 вместо /dev/ttyUSB0
  • при установке gpsd не нашел девайс самостоятельно, оказалось надо прописать в /etc/default/gpsd:
    DEVICES="/dev/ACM0"
  • для python-3 gps пакет надо доставлять руками, он не идет вместе с gpsd

Сам девайс выглядит как обычная USB-флешка:



А дальше я надолго застрял, так как мой GPS не видел координат.

Девайс работал, сообщал версию, производителя и прочую полезную информацию, но ничего больше.

Сначала я думал, что он все же бракованный. С прежних экспериментов у меня осталась SD-карта с Raspbian 2017 года, на котором GPS работал.

Загрузился с нее и — о чудо — GPS ожил и заморгал лампочкой, и посыпались в лог координаты.
Я ломал голову неделю, сравнил все конфиги, стал грешить на новый глючный Raspbian и уже готовился пересобирать в дебаге gpsd, как вдруг на Raspberry-форуме в одной из тем по проблемам GPS (а их там не мало) я набрел на совет вынести девайс на улицу в ясную погоду и дать ему найти спутники, что может занять до получаса.

Такая идея мне уже в голову приходила, но, видимо, погода была недостаточно ясная, а тут все совпало, и девайс ожил. Если копнуть чуть глубже, оказывается, что необходимая информация о спутниках кэшируется в прошивке девайса и не поддается контролю Raspbian.

How can my application get almanac/ephemeris/pseudorange data?


Sorry, there's no easy way to do these things through GPSD yet. The reason is that there is no consistent way to make GPS receivers report this information.

Many don't ship it at all. Others (including some but not all devices shipping SiRF binary packets) ship it occasionally in SUBFRAME information, but you have to know exactly how to grovel through the SUBFRAME fields to get it and the documentation of those in IS-GPS-200E (the over-the-air protocol used by GPS satellites) is extremely obscure. Still others report varying subsets of almanac/ephemeris/pseudorange data in reasonably straightforward ways, but in vendor-proprietary sentences that are extremely specific to individual receiver types, poorly documented or undocumented, and often needing to be activated by control sequences that are equally specific and even worse documented.
Хитрый механизм заработал и настало время извлечь из этого пользу.
Скрипт для чтения данных с gpsd на питоне очень прост:

import gps

gs = gps.gps("localhost", "2947")
gs.stream(gps.WATCH_ENABLE | gps.WATCH_NEWSTYLE)

for i in range(0,10):
    report = gs.next()
    print (report)

Google Maps API


Танком я управляю с телефона, так что пришлось изучать работу с Google Maps.
Гугл хорошо поработал над упрощением работы с картами, так что здесь проблем не возникло.
Android Studio умеет создать пустой проект с картой, откуда надо аккуратно перенести все важные детали в основной проект.

Гугл требует регистрации ключа для работы с Maps API, делается это бесплатно (пока).

Расширил REST-интерфейс танка, чтобы он отдавал свои координаты, передал координаты в карту, нарисовал танко-иконку и все выглядит вполне пристойно.

Дальше надо проложить путь.

Тычком на карте выбирается цель и скармливается в Directions API.

Directions — это веб-сервис, который принимает координаты двух точек и в ответ вываливает кучу информации о проложенном маршруте, включая адреса, примечательные названия и пояснения. Но мне нужна была только последовательность шагов. Выбираем координаты и отрисовываем их на карте.

Теперь для визуального контроля и управления есть все необходимое.



GPS Навигация


Дальше с телефона на танк передается первая точка маршрута.

У танка есть небольшая проблема — в начальный момент времени, он не знает свое направление.
Проблема легко решается компасом, но с компасом то любой справится…

Удалось выкрутиться тем, что первые несколько секунд танк проезжает просто вперед, получая координаты начала и конца пути и вычисляя по ним свое направление. Стоит заметить, что эти же данные можно получить прямо с GPS, там есть поле track, которое и показывает отклонение от угла на северный полюс.

Но в любом случае, чтобы это после заполнялось, нужно движение.

Расчет направления:

def azimuth(pos1, pos2):
    lat1 = toRadians(pos1["lat"])
    lon1 = toRadians(pos1["lon"])

    lat2 = toRadians(pos2["lat"])
    lon2 = toRadians(pos2["lon"])

    dlat = lat2 - lat1
    dlon = lon2 - lon1

    x = math.sin(dlon) * math.cos(lat2)
    y = math.cos(lat1) * math.sin(lat2) - math.sin(lat1) * math.cos(lat2) * math.cos(dlon)
    return math.atan2(x, y)

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

При этот GPS отдает направление через track довольно достоверно, поэтому это поле использовалось по умолчанию, а если его не было — приходилось ориентироваться по разнице координат.

Сориентировавшись на местности, танк поворачивает приблизительно куда надо (приблизительно — потому что без компаса или гироскопа точно измерить направление затруднительно) и движется несколько секунд. После чего опять получает координаты, сверяет направление, поворачивает, едет. И так до тех пор, пока цель не будет в радиусе погрешности.

В целом, самая большая проблема — погрешность GPS координат, из-за которой танк то и дело теряет направление и начинает метаться в разные стороны.

Все идет к тому, что без компаса не выжить.

Ссылки


  1. Вводная статья о настройке GPS модуля для Raspberry Pi
  2. Сервис для работы с GPS по Linux
  3. Полезный сайт с формулами расчета расстояния и направления по координатам двух точек
  4. Исходный код прошивки танка с поддержкой GPS
  5. Документация по Google Maps для Android

Комментарии (22)


  1. trir
    11.04.2019 07:40

    В целом, самая большая проблема — погрешность GPS координат

    Нужно использовать L5


    1. Stantin Автор
      11.04.2019 14:15

      Погуглил, интересно. Однако полагаю, что по цене они будут изрядно дороже, чем массовые девайсы.


  1. Javian
    11.04.2019 07:57

    с Maps API, делается это бесплатно (пока).

    Есть альтернативы вроде OpenstreetMap.


    1. Stantin Автор
      11.04.2019 14:18

      Тоже думал об этом, но документация Гугла гораздо прозрачнее и позволяет добиться цели совсем небольшими усилиями.


  1. ximik666
    11.04.2019 08:09

    Одно время тоже увлекался такими танками, но до GPS так и не добрался.

    Фото




    1. Stantin Автор
      11.04.2019 14:08

      Танки — они почти как котики)


  1. FGV
    11.04.2019 09:56

    В целом, самая большая проблема — погрешность GPS координат

    Можно же считать курс по скорости.


    1. Stantin Автор
      11.04.2019 14:08

      Что вы имеете в виду?


      1. FGV
        11.04.2019 16:11

        Расчет направления (курса) можно производить по составляющим скорости VN, VE у которых точность лучше чем у координат.


        1. Stantin Автор
          12.04.2019 05:25

          Нет таких полей в моем GPS.
          И в протоколе тоже нет:
          www.catb.org/gpsd/gpsd_json.html


          1. FGV
            12.04.2019 06:22
            +1

            В исходном nmea сообщении есть, и кстати уже "обработанные" в виде курса и скорости. И демон их тоже выдает:


            track — numeric Course over ground, degrees from true north.
            speed — numeric Speed over ground, meters per second.


            1. Stantin Автор
              12.04.2019 14:20

              Так я и писал же про него:

              Стоит заметить, что эти же данные можно получить прямо с GPS, там есть поле track


  1. ginkage
    11.04.2019 10:38

    Нью-Джерси детектед.


  1. mmMike
    11.04.2019 14:40
    +1

    А какие проблемы подключить плату c QMC5883L (I2C интерфейс), например?
    Определять направление по GPS без компаса — это тупик. Будет все время рыскать, поскольку GPS координата с приемника очень характерно плавает по времени (при фиксированном физическом положении приемника).


    Выведите координату с приемника на экран в графическом виде (кривая в 2D координатах) и сразу все поймете (простейшей программой на pyton или чем удобнее).


    Но… Хотя, у меня похожая конструкция (https://habr.com/ru/post/424191), но отправлять ее где то шляться я бы не рискнул… сопрут.


    Хотя с нынешним блоком аккумуляторов должна минимум 20 км проехать (емкость сборки как у электро самоката)


    1. Stantin Автор
      11.04.2019 14:50

      А чем I2C лучше USB?

      >>Определять направление по GPS без компаса — это тупик
      Да, пришел к такому же выводу.


      1. Stantin Автор
        11.04.2019 14:51

        А, уже увидел что это про компас


      1. trapwalker
        11.04.2019 19:04
        +1

        Есть ещё фильтр Калмана. Модель вашего танка описывается довольно просто. Фильтр будет усреднять координаты с поправкой на проприоцепцию ходовой части вашего танка. Ориентироваться уже нужно не на самые свежие мгновенные координаты с приёмника, а на вектор по отношению к усреднённому (отфильтрованному) предполагаемому положению вашего танка. Координаты положения танка при правильной настройке фильтра должны сходиться.
        Ещё можно оценивать погрешность определения своих координат и критерий целесообразности каждого перемещения вычислять в соответствии с:

        • допустимой погрешностью координат в точке прибытия
        • оценочной погрешностью определения своих координат на текущий момент
        • длиной вектора разности координат текущей и целевой точки
        • зарядом аккумулятора (видимо роботу стоит быть более ленивым при меньшем заряде?)

        Куда эффектиынее подождать пока накопится достаточная точность усреднённых координат и поямается больше спутников, чем в панике метаться по кустам.


        1. Stantin Автор
          12.04.2019 05:16

          Благодарю, очень интересная информация


      1. mmMike
        12.04.2019 05:02
        +2

        А чем I2C лучше USB?

        1. Ценой платки (копейки стоит, поскольку "для арудуино")
        2. Размерами разъема (подключение к GPIO) и не занимает дефицитный USB с его ограничениями по току (Hub не нужен).
        3. Не надо никаких специализированных драйверов искать для USB (не факт что есть вообще). Работает напрямую через I2C (библиотеки для Raspberry есть).

        Я бы и GPS подключил прямо к GPIO… (но у меня валяется OEM плата GPS с RS-232 TTL 3.3v)


  1. chnav
    11.04.2019 22:30

    (del)


  1. LRC
    12.04.2019 08:59

    Рекомендую вам погуглить следующие вещи:
    1. Истинный курс
    2. Компасный курс
    3. Девиация
    4. Движение по азимутам
    Я бы делал движение по азумуту, который корректируется раз 10 секунд и gps использовать как справочную систему


    1. Stantin Автор
      12.04.2019 14:21

      Будем изучать, спасибо