我正在编写一个程序,除其他外,它可以通过 UDP 接收 GPS NMEA 语句。 当我接收数据时,我知道我丢失了数据包。 GPS 每秒发送 ZDA(时间)、VTG(航向和速度)、GGA(WGS84 位置)序列,如屏幕截图所示:
但是,在我编写的课程中,我丢失了数据包,但不明白为什么。 ZDA 每秒都受到热烈欢迎,但 VTG 和 GGA 电报则不然。这是我的输出:
['$GPZDA,204622.00,16,10,2023,,*63', '']
['$GPZDA,204623.00,16,10,2023,,*62', '']
['$GPZDA,204624.00,16,10,2023,,*65', '']
['$GPZDA,204625.00,16,10,2023,,*64', '']
['$GPZDA,204626.00,16,10,2023,,*67', '']
['$GPZDA,204627.00,16,10,2023,,*66', '']
['$GPZDA,204628.00,16,10,2023,,*69', '']
['$GPZDA,204629.00,16,10,2023,,*68', '']
['$GPZDA,204630.00,16,10,2023,,*60', '']
['$GPZDA,204631.00,16,10,2023,,*61', '']
['$GPZDA,204632.00,16,10,2023,,*62', '']
['$GPGGA,204632.00,2918.75039,N,09435.22487,W,5,26,0.6,33.64,M,-27.60,M,010,0481*53', '']
['$GPZDA,204633.00,16,10,2023,,*63', '']
['$GPZDA,204634.00,16,10,2023,,*64', '']
['$GPZDA,204635.00,16,10,2023,,*65', '']
['$GPZDA,204636.00,16,10,2023,,*66', '']
['$GPZDA,204637.00,16,10,2023,,*67', '']
['$GPZDA,204638.00,16,10,2023,,*68', '']
['$GPZDA,204639.00,16,10,2023,,*69', '']
['$GPZDA,204640.00,16,10,2023,,*67', '']
['$GPZDA,204641.00,16,10,2023,,*66', '']
['$GPZDA,204642.00,16,10,2023,,*65', '']
['$GNVTG,286.931,T,286.931,M,0.198,N,0.367,K,D*3A', '']
['$GPZDA,204643.00,16,10,2023,,*64', '']
我的UDP_socket类:
class UDP_socket(object):
''' mode = "utf8" or "binary" '''
def __init__(self, host='', port=0, broadcast=True, mode='utf8'):
self.host = host
self.port = port
self.broadcast = broadcast
self.mode = mode
def read(self):
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
if self.broadcast:
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
s.bind((self.host, self.port))
if self.mode == 'binary':
data = s.recv(1024).hex()
else:
data = s.recv(1024).decode('Utf8', 'replace').split('\r\n')
print(data)
return data
def send(self, input, target):
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
if self.broadcast:
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
s.bind((self.host, self.port))
s.sendto(input.encode('Utf8'), target)
来自我的 GPS 课程:
def connect_socket(self):
'''Create a socket UDP or TCP'''
self.continuous_read = True
self.button.configure(text="Disconnect", command=self.socket_stop)
if self.tcpudp.get(): #0 for TCP
# print(self.gps_address.get(), int(self.gps_port.get()))
self.socket = UDP_socket(self.gps_address.get(), int(self.gps_port.get()), True)
else:
self.socket = TCP_socket(self.gps_address.get(), int(self.gps_port.get()) )
self.gps_marker = Map_Marker(app.map, color = self.marker_color)
readT = threading.Thread(target= lambda: self.socket_read(FALSE))
readT.start()
def socket_read(self, terminal):
telegram = nmea_oi()
while self.continuous_read:
received_msg = self.socket.read()
del received_msg[-1]
for j in range(len(received_msg)):
if telegram.decode(received_msg[j], 'All', terminal)[0] == 'GGA':
lat = telegram.decode(received_msg[j], 'All', terminal)[1][0]
long = telegram.decode(received_msg[j], 'All', terminal)[1][1]
self.gps_marker.update_marker(lat, long)
self.update_displayed_lines(received_msg[j])
它可能看起来有点幼稚,但我对 python 和对象编程还很陌生。我尝试自己编写所有内容,进行实验和学习。除了那些丢失的数据包之外,一切都有效。
我尝试了不同的方法,例如将缓冲区大小增加到 2048。 我不使用任何延迟。通过使用软件可视化同一台计算机上收到的数据包,不会丢失电报。一定是我的代码... 可能是线程问题,还是某个时间问题?
我知道 UDP 并不可靠,但是,这是船上当前的设置。 GPS 数据通过 UDP 广播,所有使用此输出的软件都不会丢失任何数据包(我指的是 15 台以上的机器)。在许多这样的机器上,10 秒内没有 GGA 输入就会发出警报,但这种情况永远不会发生
任何想法将不胜感激。
确实如此!感谢您的帮助。
我修改了UDP类:
class UDP_socket(object):
''' mode = "utf8" or "binary" '''
def __init__(self, host='', port=0, broadcast=True, mode='utf8'):
self.host = host
self.port = port
self.broadcast = broadcast
self.mode = mode
self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
if self.broadcast:
self.s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
self.s.bind((self.host, self.port))
def read(self):
if self.mode == 'binary':
data = self.s.recv(1024).hex()
else:
data = self.s.recv(1024).decode('Utf8', 'replace').split('\r\n')
print(data)
return data
def send(self, input, target):
self.s.sendto(input.encode('Utf8'), target)
def close(self):
self.s.close()