Картинка постановочная, намекающая, что всякий 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 координат, из-за которой танк то и дело теряет направление и начинает метаться в разные стороны.
Все идет к тому, что без компаса не выжить.
Ссылки
Комментарии (22)
ximik666
11.04.2019 08:09Одно время тоже увлекался такими танками, но до GPS так и не добрался.
FGV
11.04.2019 09:56В целом, самая большая проблема — погрешность GPS координат
Можно же считать курс по скорости.
Stantin Автор
11.04.2019 14:08Что вы имеете в виду?
FGV
11.04.2019 16:11Расчет направления (курса) можно производить по составляющим скорости VN, VE у которых точность лучше чем у координат.
Stantin Автор
12.04.2019 05:25Нет таких полей в моем GPS.
И в протоколе тоже нет:
www.catb.org/gpsd/gpsd_json.htmlFGV
12.04.2019 06:22+1В исходном nmea сообщении есть, и кстати уже "обработанные" в виде курса и скорости. И демон их тоже выдает:
track — numeric Course over ground, degrees from true north.
speed — numeric Speed over ground, meters per second.Stantin Автор
12.04.2019 14:20Так я и писал же про него:
Стоит заметить, что эти же данные можно получить прямо с GPS, там есть поле track
mmMike
11.04.2019 14:40+1А какие проблемы подключить плату c QMC5883L (I2C интерфейс), например?
Определять направление по GPS без компаса — это тупик. Будет все время рыскать, поскольку GPS координата с приемника очень характерно плавает по времени (при фиксированном физическом положении приемника).
Выведите координату с приемника на экран в графическом виде (кривая в 2D координатах) и сразу все поймете (простейшей программой на pyton или чем удобнее).
Но… Хотя, у меня похожая конструкция (https://habr.com/ru/post/424191), но отправлять ее где то шляться я бы не рискнул… сопрут.
Хотя с нынешним блоком аккумуляторов должна минимум 20 км проехать (емкость сборки как у электро самоката)
Stantin Автор
11.04.2019 14:50А чем I2C лучше USB?
>>Определять направление по GPS без компаса — это тупик
Да, пришел к такому же выводу.trapwalker
11.04.2019 19:04+1Есть ещё фильтр Калмана. Модель вашего танка описывается довольно просто. Фильтр будет усреднять координаты с поправкой на проприоцепцию ходовой части вашего танка. Ориентироваться уже нужно не на самые свежие мгновенные координаты с приёмника, а на вектор по отношению к усреднённому (отфильтрованному) предполагаемому положению вашего танка. Координаты положения танка при правильной настройке фильтра должны сходиться.
Ещё можно оценивать погрешность определения своих координат и критерий целесообразности каждого перемещения вычислять в соответствии с:
- допустимой погрешностью координат в точке прибытия
- оценочной погрешностью определения своих координат на текущий момент
- длиной вектора разности координат текущей и целевой точки
- зарядом аккумулятора (видимо роботу стоит быть более ленивым при меньшем заряде?)
Куда эффектиынее подождать пока накопится достаточная точность усреднённых координат и поямается больше спутников, чем в панике метаться по кустам.
mmMike
12.04.2019 05:02+2А чем I2C лучше USB?
- Ценой платки (копейки стоит, поскольку "для арудуино")
- Размерами разъема (подключение к GPIO) и не занимает дефицитный USB с его ограничениями по току (Hub не нужен).
- Не надо никаких специализированных драйверов искать для USB (не факт что есть вообще). Работает напрямую через I2C (библиотеки для Raspberry есть).
Я бы и GPS подключил прямо к GPIO… (но у меня валяется OEM плата GPS с RS-232 TTL 3.3v)
trir
Нужно использовать L5
Stantin Автор
Погуглил, интересно. Однако полагаю, что по цене они будут изрядно дороже, чем массовые девайсы.