Модуль Python GPS: чтение последних данных GPS
Я пытался работать со стандартом GPS (gps.py) модуль в python 2.6. Это должно действовать как клиент и считывать данные GPS из gpsd, запущенного в Ubuntu.
согласно документации от веб-страницы GPSD на дизайне клиента (Gpsd клиент Howto), Я должен иметь возможность использовать следующий код (слегка измененный из примера) для получения последних показаний GPS (lat long-это то, что меня в основном интересует in)
from gps import *
session = gps() # assuming gpsd running with default options on port 2947
session.stream(WATCH_ENABLE|WATCH_NEWSTYLE)
report = session.next()
print report
Если я неоднократно использую next (), он дает мне буферизованные значения из нижней части очереди (с момента запуска сеанса), а не последнее чтение Gps. Есть ли способ получить более свежие значения с помощью этой библиотеки? В некотором смысле, искать поток до последних значений?
у кого-нибудь есть пример кода, использующий эту библиотеку для опроса GPS и получить значение я ищу ?
вот что я пытаюсь сделать:
- начать сеанс
- подождите, пока пользователь вызовет метод gps_poll () в моем коде
- внутри этого метода прочитайте последний отчет TPV (Time Position Velocity) и верните lat long
- вернитесь к ожиданию вызова пользователем gps_poll ()
3 ответов
что вам нужно сделать, это регулярно опрашивать сессии.next ()' - проблема здесь в том, что вы имеете дело с последовательным интерфейсом - вы получаете результаты в том порядке, в котором они были получены. Его до вас, чтобы поддерживать "current_value", который имеет последнее полученное значение.
Если вы не опросите объект сеанса, в конечном итоге ваш UART FIFO заполнится, и вы все равно не получите никаких новых значений.
рассмотрите возможность использования потока для этого, не ждите, пока пользователь вызовет gps_poll (), вы должен быть опрос, и когда пользователь хочет новое значение, они используют " get_current_value ()", который возвращает current_value.
С моей головы это может быть что-то простое, как это:
import threading
import time
from gps import *
class GpsPoller(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.session = gps(mode=WATCH_ENABLE)
self.current_value = None
def get_current_value(self):
return self.current_value
def run(self):
try:
while True:
self.current_value = self.session.next()
time.sleep(0.2) # tune this, you might not get values that quickly
except StopIteration:
pass
if __name__ == '__main__':
gpsp = GpsPoller()
gpsp.start()
# gpsp now polls every .2 seconds for new data, storing it in self.current_value
while 1:
# In the main thread, every 5 seconds print the current value
time.sleep(5)
print gpsp.get_current_value()
добавление моих двух центов.
по какой-то причине мой raspberry pi будет продолжать выполнять поток, и мне придется жестко сбросить pi.
Итак, я объединил sysnthesizerpatel и ответ, который я нашел в блоге Дэна Манделя здесь.
мой класс gps_poller выглядит так:
import os
from gps import *
from time import *
import time
import threading
class GpsPoller(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.session = gps(mode=WATCH_ENABLE)
self.current_value = None
self.running = True
def get_current_value(self):
return self.current_value
def run(self):
try:
while self.running:
self.current_value = self.session.next()
except StopIteration:
pass
и используемый код выглядит так:
from gps_poll import *
if __name__ == '__main__':
gpsp = GpsPoller()
try:
gpsp.start()
while True:
os.system('clear')
report = gpsp.get_current_value()
# print report
try:
if report.keys()[0] == 'epx':
print report['lat']
print report['lon']
time.sleep(.5)
except(AttributeError, KeyError):
pass
time.sleep(0.5)
except(KeyboardInterrupt, SystemExit):
print "\nKilling Thread.."
gpsp.running = False
gpsp.join()
print "Done.\nExiting."
вышеуказанные ответы очень неэффективны и чрезмерно сложны для тех, кто использует современные версии gpsd и нуждается в данных только в определенное время, а не в потоковой передаче.
большинство GPSes отправляют информацию о своей позиции по крайней мере один раз в секунду. Предположительно, поскольку многие приложения на основе GPS желают обновлений в реальном времени, подавляющее большинство примеров клиентов gpsd, которые я видел, используют вышеуказанный метод просмотра потока из gpsd и получения обновлений в реальном времени (более или менее так часто, как gps послать их.)
однако, если (как в случае OP) вы не нужно потоковая информация, но просто нужна последняя сообщенная позиция, когда она запрашивается (т. е. через взаимодействие с пользователем или какое-либо другое событие), есть гораздо более эффективный и простой метод: пусть gpsd кэширует последнюю информацию о позиции и запрашивает ее при необходимости.
на протокол gpsd JSON есть ?POLL;
запрос, который возвращает самую последнюю информацию GPS, что gpsd видел. Вместо того, чтобы повторять за отставание сообщений gps, и постоянно читать новые сообщения, чтобы избежать полных буферов, вы можете отправить ?WATCH={"enable":true}
сообщение в начале сеанса gpsd, а затем запросить последнюю информацию о позиции, когда вам это нужно с ?POLL;
. Ответ представляет собой один объект JSON, содержащий самую последнюю информацию, которую gpsd видел из GPS.
если вы используете Python3, самый простой способ, который я нашел, - использовать gpsd-py3 пакет доступен на pypi. Чтобы подключиться к gpsd, получите последнюю информацию о позиции и распечатайте текущую позицию:
import gpsd
gpsd.connect()
packet = gpsd.get_current()
print(packet.position())
вы можете повторить gpsd.get_current()
звоните, когда вам нужна новая информация о позиции, и за кулисами пакет gpsd выполнит ?POLL;
вызовите gpsd и верните объект, представляющий ответ.
делать это со встроенным gps
модуль не очень прост, но есть ряд других клиентов Python доступно, и это также довольно тривиально делать с чем-либо, что может выполнять связь сокетов, включая этот пример с помощью telnet
:
$ telnet localhost 2947
Trying ::1...
Connected to localhost.
Escape character is '^]'.
{"class":"VERSION","release":"3.16","rev":"3.16","proto_major":3,"proto_minor":11}
?WATCH={"enable":true}
{"class":"DEVICES","devices":[{"class":"DEVICE","path":"/dev/pts/10","driver":"SiRF","activated":"2018-03-02T21:14:52.687Z","flags":1,"native":1,"bps":4800,"parity":"N","stopbits":1,"cycle":1.00}]}
{"class":"WATCH","enable":true,"json":false,"nmea":false,"raw":0,"scaled":false,"timing":false,"split24":false,"pps":false}
?POLL;
{"class":"POLL","time":"2018-03-02T21:14:54.873Z","active":1,"tpv":[{"class":"TPV","device":"/dev/pts/10","mode":3,"time":"2005-06-09T14:34:53.280Z","ept":0.005,"lat":46.498332203,"lon":7.567403907,"alt":1343.165,"epx":24.829,"epy":25.326,"epv":78.615,"track":10.3788,"speed":0.091,"climb":-0.085,"eps":50.65,"epc":157.23}],"gst":[{"class":"GST","device":"/dev/pts/10","time":"1970-01-01T00:00:00.000Z","rms":0.000,"major":0.000,"minor":0.000,"orient":0.000,"lat":0.000,"lon":0.000,"alt":0.000}],"sky":[{"class":"SKY","device":"/dev/pts/10","time":"2005-06-09T14:34:53.280Z","xdop":1.66,"ydop":1.69,"vdop":3.42,"tdop":3.05,"hdop":2.40,"gdop":5.15,"pdop":4.16,"satellites":[{"PRN":23,"el":6,"az":84,"ss":0,"used":false},{"PRN":28,"el":7,"az":160,"ss":0,"used":false},{"PRN":8,"el":66,"az":189,"ss":45,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":51,"az":304,"ss":29,"used":true},{"PRN":4,"el":15,"az":199,"ss":36,"used":true},{"PRN":2,"el":34,"az":241,"ss":41,"used":true},{"PRN":27,"el":71,"az":76,"ss":42,"used":true}]}]}
?POLL;
{"class":"POLL","time":"2018-03-02T21:14:58.856Z","active":1,"tpv":[{"class":"TPV","device":"/dev/pts/10","mode":3,"time":"2005-06-09T14:34:53.280Z","ept":0.005,"lat":46.498332203,"lon":7.567403907,"alt":1343.165,"epx":24.829,"epy":25.326,"epv":78.615,"track":10.3788,"speed":0.091,"climb":-0.085,"eps":50.65,"epc":157.23}],"gst":[{"class":"GST","device":"/dev/pts/10","time":"1970-01-01T00:00:00.000Z","rms":0.000,"major":0.000,"minor":0.000,"orient":0.000,"lat":0.000,"lon":0.000,"alt":0.000}],"sky":[{"class":"SKY","device":"/dev/pts/10","time":"2005-06-09T14:34:53.280Z","xdop":1.66,"ydop":1.69,"vdop":3.42,"tdop":3.05,"hdop":2.40,"gdop":5.15,"pdop":4.16,"satellites":[{"PRN":23,"el":6,"az":84,"ss":0,"used":false},{"PRN":28,"el":7,"az":160,"ss":0,"used":false},{"PRN":8,"el":66,"az":189,"ss":45,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":51,"az":304,"ss":29,"used":true},{"PRN":4,"el":15,"az":199,"ss":36,"used":true},{"PRN":2,"el":34,"az":241,"ss":41,"used":true},{"PRN":27,"el":71,"az":76,"ss":42,"used":true}]}]}