我一直在尝试使用python 2.6中的标准GPS(gps.py)模块.这应该充当客户端并从Ubuntu中运行的gpsd读取GPS数据.
根据客户端设计的GPSD网页(GPSD Client Howto)的文档,我应该能够使用以下代码(从示例中略微修改)获取最新的GPS读数(lat long是我主要感兴趣的)
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
Run Code Online (Sandbox Code Playgroud)
如果我重复使用next(),它会从队列底部(从会话开始时)开始给出缓冲值,而不是LATEST Gps读取.有没有办法使用这个库获取更新的值?在某种程度上,寻求流的最新价值?
有没有人有一个代码示例使用这个库来轮询gps并获得我正在寻找的价值?
这是我想要做的:
syn*_*tel 17
您需要做的是定期轮询'session.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()
Run Code Online (Sandbox Code Playgroud)
对于使用现代版本的gpsd且仅在特定时间而不是流式传输数据的任何人,上述答案的效率非常低且过于复杂。
大多数GPS每秒至少发送一次其位置信息。大概由于许多基于GPS的应用程序都需要实时更新,因此我所见过的绝大多数gpsd客户端示例都使用上述方法来观看来自gpsd的流并接收实时更新(与gps发送更新的频率差不多) 。
但是,如果(例如,在OP中)您不需要流信息,而仅在需要时(例如,通过用户交互或其他事件)仅需要最后报告的位置,那么有一种更有效,更简单的方法:让gpsd缓存最新的位置信息,并在需要时查询。
所述GPSD JSON协议具有?POLL;请求,其返回最近的GPS信息GPSD已经看到。您无需遍历gps消息的积压,并不断读取新消息来避免缓冲区已满?WATCH={"enable":true},而无需在gpsd会话开始时发送一条消息,然后在需要时随时查询最新的位置信息?POLL;。响应是一个JSON对象,其中包含gpsd从GPS中看到的最新信息。
如果您使用的是Python3,我发现的最简单的方法是使用pypi上可用的gpsd-py3软件包。要连接到gpsd,请获取最新的位置信息,并打印当前位置:
import gpsd
gpsd.connect()
packet = gpsd.get_current()
print(packet.position())
Run Code Online (Sandbox Code Playgroud)
您可以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}]}]}
Run Code Online (Sandbox Code Playgroud)