【问题标题】:gpsd python clientgpsd python客户端
【发布时间】:2011-03-18 17:27:19
【问题描述】:

我正在尝试为 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。

谢谢!

【问题讨论】:

    标签: python gps gpsd


    【解决方案1】:

    我知道这个问题已经很老了,但我还是把我的答案放在这里以防将来有人需要它:

    #! /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/

    【讨论】:

    • 请在此处提供此代码及其功能的一般描述。这将提高您的回答质量。
    • @Kris:已编辑,我在代码中包含了一些简短的描述。感谢您的建议,我将在下一个答案中尝试更详细。希望我的编辑和代码中的 cmets 对将来有需要的人来说已经足够了。再次感谢:)
    【解决方案2】:

    我会在 gpsd 如何分页的这个片段上投入一些钱;另外,感谢您的引导代码。

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

    如果你是一个聪明的人,你已经想知道如果客户端套接字另一端的应用程序没有像 gpsd 向上传送数据那样快地从中读取数据,守护进程会做什么。答案是这样的:最终套接字缓冲区被填满,来自守护进程的写入会引发错误,并且守护进程会关闭该客户端套接字。

    只要您的应用程序检查和读取套接字数据的频率不少于每秒一次,您就不会 — 而且一秒钟是很多时间来回到您的主循环。

    【讨论】:

      【解决方案3】:

      为了保留一个老问题,下面粘贴的是GPS3, a Python 2.7-3.5 gpsd client 的当前状态https://github.com/wadda/gps3

      GPS3 有两个组件; GPSDSocket 类和 Fix 类。

      GPSD 在许多“类”、TPV、SKY 等中提供 JSON 数据。连接到 GPSD 后,GPS3 将这些 JSON 对象解包到字典中(Fix.TPV['lat']Fix.SKY['satellites'] 等)

      通常会创建一个实例,例如fix = gps3.Fix(),所有可用的数据都将派生自本机 JSON 对象的名称(例如,fix.TPV['speed']fix.TPV['alt'] 等)

      使用a demo application gegps3.py 来创建一个kml 文件(/tmp/gps3_live.kml),以便在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
      

      【讨论】:

        猜你喜欢
        • 2023-03-14
        • 1970-01-01
        • 2016-04-07
        • 2016-10-07
        • 2011-12-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多