Módulo GPS Python: a ler os últimos dados do GPS

Tenho tentado trabalhar com o GPS padrão (gps.py) module in python 2.6. Isto é suposto agir como um cliente e ler dados de GPS da DSGP em execução no Ubuntu.

de acordo com a documentação da página web da DSGP sobre o design do cliente (DSGP Client Howto ), devo ser capaz de usar o seguinte código (ligeiramente modificado a partir do exemplo) para obter as últimas leituras de GPS (lat long é o que mais me interessa)

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

Se eu usar repetidamente o em seguida () ele me dá os valores buffer a partir do fundo da fila (a partir de quando a sessão foi iniciada), e não a última leitura Gps. Existe uma maneira de obter valores mais recentes usando esta biblioteca? De certa forma, procurar o fluxo para os valores mais recentes?

Alguém tem um exemplo de código usando esta biblioteca para pesquisar o gps e obter o valor que procuro ?

eis o que estou a tentar fazer.:

  1. iniciar a sessão
  2. espere que o utilizador ligue para o gps_poll() método no meu código
  3. dentro deste método leia o último relatório do TPV (velocidade da posição no tempo) e devolva lat longo
  4. volte a esperar que o utilizador ligue para o gps_poll ()
Author: TanB, 2011-05-27

3 answers

O que tens de fazer é fazer uma sondagem regular.próximo()' - o problema aqui é que você está lidando com uma interface serial - você obtém resultados na ordem em que eles foram recebidos. Cabe a você manter um "current_value" que tenha o mais recente valor recuperado. {[[2]} Se não pesquisares o objecto da sessão, eventualmente o teu FIFO UART vai encher-se e não terás quaisquer novos valores de qualquer maneira.

Considere usar um tópico para isto, não espere que o utilizador ligue para o gps_poll (), deverá ser a sondagem e quando o Utilizador quer um novo valor, usam o 'get_ current_value ()' que devolve current_value.

Pode ser algo tão simples como isto.
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() 
 17
Author: synthesizerpatel, 2018-01-19 02:44:58
A juntar os meus dois cêntimos. Por alguma razão o meu raspberry pi continuaria a executar uma linha e eu teria de reiniciar o pi. Então combinei sysnthesizerpatel e uma resposta que encontrei no blog de Dan Mandel.

A minha classe gps_poller parece-se com isto:

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

E o código em uso é o seguinte:

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." 

Você também pode encontrar o código aqui: Aqui e Aqui

 2
Author: Tim Reilly, 2016-03-17 23:46:25

As respostas acima são muito ineficientes e excessivamente complexas para qualquer pessoa que utilize versões modernas da DSGP e que precise de dados apenas em momentos específicos, em vez de streaming.

A maioria das GPSes envia as suas informações de posição pelo menos uma vez por segundo. Presumivelmente uma vez que muitas aplicações baseadas no GPS desejam atualizações em tempo real, a grande maioria dos exemplos de clientes da DSGP que eu vi usar o método acima de assistir um fluxo de DSGP e receber atualizações em tempo real (mais ou menos tantas vezes quanto o gps envia-os).

No entanto, se (como no caso do OP) você não precisa de informação de streaming, mas apenas precisa da posição comunicada pela última vez quando é solicitada (isto é, através da interacção do utilizador ou de qualquer outro evento), existe um método muito mais eficiente e simples: deixe a DSGP armazenar a informação de posição mais recente e consultá-la quando necessário.

O protocolo da DSGP JSON tem um pedido ?POLL;, que devolve a informação GPS mais recente que a DSGP viu. Em vez de tendo que iterar o backlog de mensagens de gps, e ler continuamente novas mensagens para evitar buffers completos, você pode enviar uma mensagem ?WATCH={"enable":true} no início da sessão da DSGP, e depois consultar a última informação de posição sempre que precisar dela com ?POLL;. A resposta é um único objeto JSON contendo a informação mais recente que a DSGP viu do GPS.

Se está a usar o Python3, a forma mais fácil que encontrei é usar o pacote DSGP-py3 disponível no pypi. Conectar para a DSGP, obtenha as últimas informações de posição e imprima a posição atual:

import gpsd
gpsd.connect()
packet = gpsd.get_current()
print(packet.position())

Você pode repetir a chamada gpsd.get_current() sempre que quiser novas informações de posição, e nos bastidores o pacote da DSGP irá executar a chamada ?POLL; para a DSGP e devolver um objecto que represente a resposta.

Fazer isto com o módulo embutido gps não é muito simples, mas há uma série de outros clientes Python disponíveis, e também é bastante trivial para fazer com qualquer coisa que possa executar a comunicação do 'socket', incluindo este exemplo usando 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}]}]}
 1
Author: Jason Antman, 2018-03-02 21:18:39