2010-07-20 77 views
2

我試圖寫GPSD一個非常簡單的Python客戶端,但我有 執行腳本的一段時間後此錯誤:GPSD Python客戶端

Traceback (most recent call last): 
File "gps_cap.py", line 13, in <module> 
    g.stream() 
File "/usr/lib/python2.6/site-packages/gps/gps.py", line 348, in stream 
    gpsjson.stream(self, flags) 
File "/usr/lib/python2.6/site-packages/gps/client.py", line 176, in stream 
    return self.send(arg + "}") 
File "/usr/lib/python2.6/site-packages/gps/client.py", line 111, in send 
    self.sock.send(commands) 
socket.error: [Errno 104] Connection reset by peer 

,這是我的Python代碼:

import os 
from gps import * 
from time import * 

g = gps(mode=WATCH_ENABLE) 
while 1: 
     os.system('clear') 
     g.poll() 
     if PACKET_SET: 
       g.stream() 

     print 
     print ' GPS reading' 
     print '----------------------------------------' 
     print 'latitude ' , g.fix.latitude 
     print 'longitude ' , g.fix.longitude 
     print 'time utc ' , g.utc,' + ', g.fix.time 
     print 'altitude ' , g.fix.altitude 
     print 'epc   ' , g.fix.epc 
     print 'epd   ' , g.fix.epd 
     print 'eps   ' , g.fix.eps 
     print 'epx   ' , g.fix.epx 
     print 'epv   ' , g.fix.epv 
     print 'ept   ' , g.fix.ept 
     print 'speed  ' , g.fix.speed 
     print 'climb  ' , g.fix.climb 
     print 'track  ' , g.fix.track 
     print 'mode  ' , g.fix.mode 
     print 
     print 'sats  ' , g.satellites 

     sleep(1) 

也許任何人都可以使用這個問題上需要幫助?我在ArchLinux框中運行Gpsd 2.95。

謝謝!

回答

1

我會把一些錢從這個GPSD怎樣的這段頁;此外,謝謝你的引導代碼。

http://gpsd.berlios.de/client-howto.html

如果你是一個聰明的排序,你已經知道什麼是守護進程,如果在客戶端插座的另一端的應用程序不讀取數據出來的一樣快gpsd向上發貨。答案是這樣的:最終套接字緩衝區填滿,守護進程寫入一個錯誤,守護進程關閉該客戶端套接字。

只要你的應用程序檢查和讀取套接字數據沒少往往比一次第二,你不會 - 第二是大量的時間在來左右你的主循環回來。

2

我知道這個問題是很老,但我仍然在這裏將我的答案,以防有人需要它的未來:

#! /usr/bin/python 
# Written by Dan Mandle http://dan.mandle.me September 2012 
# License: GPL 2.0 
import os 
from gps import * 
from time import * 
import time 
import threading 

gpsd = None #seting the global variable 

os.system('clear') #clear the terminal (optional) 

class GpsPoller(threading.Thread): 
    def __init__(self): 
    threading.Thread.__init__(self) 
    global gpsd #bring it in scope 
    gpsd = gps(mode=WATCH_ENABLE) #starting the stream of info 
    self.current_value = None 
    self.running = True #setting the thread running to true 

    def run(self): 
    global gpsd 
    while gpsp.running: 
     gpsd.next() #this will continue to loop and grab EACH set of gpsd info to clear the buffer 

if __name__ == '__main__': 
    gpsp = GpsPoller() # create the thread 
    try: 
    gpsp.start() # start it up 
    while True: 
     #It may take a second or two to get good data 
     #print gpsd.fix.latitude,', ',gpsd.fix.longitude,' Time: ',gpsd.utc 

     os.system('clear') 

     print 
     print ' GPS reading' 
     print '----------------------------------------' 
     print 'latitude ' , gpsd.fix.latitude 
     print 'longitude ' , gpsd.fix.longitude 
     print 'time utc ' , gpsd.utc,' + ', gpsd.fix.time 
     print 'altitude (m)' , gpsd.fix.altitude 
     print 'eps   ' , gpsd.fix.eps 
     print 'epx   ' , gpsd.fix.epx 
     print 'epv   ' , gpsd.fix.epv 
     print 'ept   ' , gpsd.fix.ept 
     print 'speed (m/s) ' , gpsd.fix.speed 
     print 'climb  ' , gpsd.fix.climb 
     print 'track  ' , gpsd.fix.track 
     print 'mode  ' , gpsd.fix.mode 
     print 
     print 'sats  ' , gpsd.satellites 

     time.sleep(5) #set to whatever 

    except (KeyboardInterrupt, SystemExit): #when you press ctrl+c 
    print "\nKilling Thread..." 
    gpsp.running = False 
    gpsp.join() # wait for the thread to finish what it's doing 
    print "Done.\nExiting." 

這與線程和代碼工作將給出GPSD的一個不錯的輸出數據到屏幕上。它可以用Ctrl + C.

終止所有學分去http://www.danmandle.com/blog/getting-gpsd-to-work-with-python/

+0

請提供一些此代碼的一般說明及其功能。它會改善你的答案的質量。 – Kris 2014-07-27 10:25:25

+0

@Kris:編輯過,我在代碼中包含了一些簡短的描述。感謝您的建議,我會盡力在我的下一個答案中更詳細。希望我的編輯和代碼中的評論足以滿足將來需要的人。再次感謝 :) – codenameLxL 2014-07-27 10:35:37

0

要保持一個老問題還活着,粘貼下面是https://github.com/wadda/gps3發現GPS3, a Python 2.7-3.5 gpsd client當前狀態。

GPS3具有兩個分量;在GPSDSocket類和修復類。

GPSD提供JSON數據在許多 '類' 的應用,TPV,SKY等連接到GPSD後,解包GPS3那些JSON物體進入字典(Fix.TPV['lat']Fix.SKY['satellites']等)

共同使用將創建一個實例,例如,fix = gps3.Fix(),和所有可用的數據將從本地JSON對象(例如,fix.TPV['speed']fix.TPV['alt']等)

賦予使用的它創建了一個kml文件(/tmp/gps3_live.kml)將該名稱與a demo application gegps3.py導出在Google地球中查看。

#!/usr/bin/env python3 
# coding=utf-8 
""" 
GPS3 (gps3.py) is a Python 2.7-3.5 GPSD interface (http://www.catb.org/gpsd) 
Defaults host='127.0.0.1', port=2947, gpsd_protocol='json' 

GPS3 has two classes. 
1) 'GPSDSocket' to create a GPSD socket connection and request/retreive GPSD output. 
2) 'Fix' unpacks the streamed gpsd data into python dictionaries. 

These dictionaries are literated from the JSON data packet sent from the GPSD. 

Import   import gps3 
Instantiate  gps_connection = gps3.GPSDSocket(host='192.168.0.4') 
       gps_fix = gps3.Fix() 
Iterate   for new_data in gps_connection: 
        if new_data: 
         gps_fix.refresh(new_data) 
Use      print('Altitude = ',gps_fix.TPV['alt']) 
         print('Latitude = ',gps_fix.TPV['lat']) 

Consult Lines 152-ff for Attribute/Key possibilities. 
or http://www.catb.org/gpsd/gpsd_json.html 

Run human.py; python[X] human.py [arguments] for a human experience. 
""" 
from __future__ import print_function 

import json 
import select 
import socket 
import sys 

__author__ = 'Moe' 
__copyright__ = 'Copyright 2015-2016 Moe' 
__license__ = 'MIT' 
__version__ = '0.2' 

HOST = '127.0.0.1' # gpsd 
GPSD_PORT = 2947 # defaults 
PROTOCOL = 'json' # " 


class GPSDSocket(object): 
    """Establish a socket with gpsd, by which to send commands and receive data.""" 

    def __init__(self, host=HOST, port=GPSD_PORT, gpsd_protocol=PROTOCOL, devicepath=None): 
     self.devicepath_alternate = devicepath 
     self.response = None 
     self.protocol = gpsd_protocol 
     self.streamSock = None 

     if host: 
      self.connect(host, port) 

    def connect(self, host, port): 
     """Connect to a host on a given port. 
     Arguments: 
      port: default port=2947 
      host: default host='127.0.0.1' 
     """ 
     for alotta_stuff in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM): 
      family, socktype, proto, _canonname, host_port = alotta_stuff 
      try: 
       self.streamSock = socket.socket(family, socktype, proto) 
       self.streamSock.connect(host_port) 
       self.streamSock.setblocking(False) 
       self.watch(gpsd_protocol=self.protocol) 
      except OSError as error: 
       sys.stderr.write('\nGPSDSocket.connect OSError is-->', error) 
       sys.stderr.write('\nAttempt to connect to a gpsd at {0} on port \'{1}\' failed:\n'.format(host, port)) 
       sys.exit(1) # TODO: gpsd existence check and start 

    def watch(self, enable=True, gpsd_protocol='json', devicepath=None): 
     """watch gpsd in various gpsd_protocols or devices. 
     Arguments: 
      self: 
      enable: (bool) stream data to socket 
      gpsd_protocol: (str) 'json' | 'nmea' | 'rare' | 'raw' | 'scaled' | 'split24' | 'pps' 
      devicepath: (str) device path - '/dev/ttyUSBn' for some number n or '/dev/whatever_works' 
     Returns: 
      command: (str) e.g., '?WATCH={"enable":true,"json":true};' 
     """ 
     # N.B.: 'timing' requires special attention, as it is undocumented and lives with dragons. 
     command = '?WATCH={{"enable":true,"{0}":true}}'.format(gpsd_protocol) 

     if gpsd_protocol == 'rare': # 1 for a channel, gpsd reports the unprocessed NMEA or AIVDM data stream 
      command = command.replace('"rare":true', '"raw":1') 
     if gpsd_protocol == 'raw': # 2 channel that processes binary data, received data verbatim without hex-dumping. 
      command = command.replace('"raw":true', '"raw",2') 
     if not enable: 
      command = command.replace('true', 'false') # sets -all- command values false . 
     if devicepath: 
      command = command.replace('}', ',"device":"') + devicepath + '"}' 

     return self.send(command) 

    def send(self, commands): 
     """Ship commands to the daemon 
     Arguments: 
      commands: e.g., '?WATCH={{'enable':true,'json':true}}'|'?VERSION;'|'?DEVICES;'|'?DEVICE;'|'?POLL;' 
     """ 
     # The POLL command requests data from the last-seen fixes on all active GPS devices. 
     # Devices must previously have been activated by ?WATCH to be pollable. 
     if sys.version_info[0] < 3: # Not less than 3, but 'broken hearted' because 
      self.streamSock.send(commands) # 2.7 chokes on 'bytes' and 'encoding=' 
     else: 
      self.streamSock.send(bytes(commands, encoding='utf-8')) # It craps out here when there is no gpsd running 
      # TODO: Add recovery, check gpsd existence, re/start, etc.. 

    def __iter__(self): 
     """banana""" # <------- for scale 
     return self 

    def next(self, timeout=0): 
     """Return empty unless new data is ready for the client. 
     Arguments: 
      timeout: Default timeout=0 range zero to float specifies a time-out as a floating point 
     number in seconds. Will sit and wait for timeout seconds. When the timeout argument is omitted 
     the function blocks until at least one file descriptor is ready. A time-out value of zero specifies 
     a poll and never blocks. 
     """ 
     try: 
      waitin, _waitout, _waiterror = select.select((self.streamSock,),(),(), timeout) 
      if not waitin: return 
      else: 
       gpsd_response = self.streamSock.makefile() # '.makefile(buffering=4096)' In strictly Python3 
       self.response = gpsd_response.readline() 
      return self.response 

     except OSError as error: 
      sys.stderr.write('The readline OSError in GPSDSocket.next is this: ', error) 

    __next__ = next # Workaround for changes in iterating between Python 2.7 and 3 

    def close(self): 
     """turn off stream and close socket""" 
     if self.streamSock: 
      self.watch(enable=False) 
      self.streamSock.close() 
     self.streamSock = None 


class Fix(object): 
    """Retrieve JSON Object(s) from GPSDSocket and unpack it into respective 
    gpsd 'class' dictionaries, TPV, SKY, etc. yielding hours of fun and entertainment. 
    """ 

    def __init__(self): 
     """Potential data packages from gpsd for a generator of class attribute dictionaries""" 

     packages = {'VERSION': {'release', 'proto_major', 'proto_minor', 'remote', 'rev'}, 
        'TPV': {'alt', 'climb', 'device', 'epc', 'epd', 'eps', 'ept', 'epv', 'epx', 'epy', 'lat', 'lon', 'mode', 'speed', 'tag', 'time', 'track'}, 
        'SKY': {'satellites', 'gdop', 'hdop', 'pdop', 'tdop', 'vdop', 'xdop', 'ydop'}, 
        # Subset of SKY: 'satellites': {'PRN', 'ss', 'el', 'az', 'used'} # is always present. 
        'GST': {'alt', 'device', 'lat', 'lon', 'major', 'minor', 'orient', 'rms', 'time'}, 
        'ATT': {'acc_len', 'acc_x', 'acc_y', 'acc_z', 'depth', 'device', 'dip', 'gyro_x', 'gyro_y', 'heading', 'mag_len', 'mag_st', 'mag_x', 
          'mag_y', 'mag_z', 'pitch', 'pitch_st', 'roll', 'roll_st', 'temperature', 'time', 'yaw', 'yaw_st'}, 
        # 'POLL': {'active', 'tpv', 'sky', 'time'}, 
        'PPS': {'device', 'clock_sec', 'clock_nsec', 'real_sec', 'real_nsec', 'precision'}, 
        'TOFF': {'device', 'clock_sec', 'clock_nsec','real_sec', 'real_nsec' }, 
        'DEVICES': {'devices', 'remote'}, 
        'DEVICE': {'activated', 'bps', 'cycle', 'mincycle', 'driver', 'flags', 'native', 'parity', 'path', 'stopbits', 'subtype'}, 
        # 'AIS': {} # see: http://catb.org/gpsd/AIVDM.html 
        'ERROR': {'message'}} # TODO: Full suite of possible GPSD output 

     for package_name, dataset in packages.items(): 
      _emptydict = {key: 'n/a' for key in dataset} 
      setattr(self, package_name, _emptydict) 

     self.DEVICES['devices'] = {key: 'n/a' for key in packages['DEVICE']} # How does multiple listed devices work? 
     # self.POLL = {'tpv': self.TPV, 'sky': self.SKY, 'time': 'n/a', 'active': 'n/a'} 

    def refresh(self, gpsd_data_package): 
     """Sets new socket data as Fix attributes in those initialied dictionaries 
     Arguments: 
      self: 
      gpsd_data_package (json object): 
     Provides: 
     self attribute dictionaries, e.g., self.TPV['lat'], self.SKY['gdop'] 
     Raises: 
     AttributeError: 'str' object has no attribute 'keys' when the device falls out of the system 
     ValueError, KeyError: most likely extra, or mangled JSON data, should not happen, but that 
     applies to a lot of things. 
     """ 
     try: 
      fresh_data = json.loads(gpsd_data_package) # The reserved word 'class' is popped from JSON object class 
      package_name = fresh_data.pop('class', 'ERROR') # gpsd data package errors are also 'ERROR'. 
      package = getattr(self, package_name, package_name) # packages are named for JSON object class 
      for key in package.keys(): # TODO: Rollover and retry. It fails here when device disappears 
       package[key] = fresh_data.get(key, 'n/a') # Updates and restores 'n/a' if key is absent in the socket 
       # response, present --> 'key: 'n/a'' instead.' 
     except AttributeError: # 'str' object has no attribute 'keys' 
      print('No Data') 
      return 

     except (ValueError, KeyError) as error: 
      sys.stderr.write(str(error)) # Look for extra data in stream 
      return 


if __name__ == '__main__': 
    print('\n', __doc__) 

# 
# Someday a cleaner Python interface will live here 
# 
# End