Python GPS 数据捕获
因此,我正在使用 GPS 模块 、 Python 和 MySQL 数据库 制作一个应用程序。
因此,我编写了一些代码,尝试从 GPS 捕获数据并将其存储在数据库中。我正在使用一个名为“ pynmea2 ”的插件来解析一些数据(经度和纬度)。但是,我需要更多的数据,因此,我已经尝试了很多不同的方法,但我的程序始终崩溃。有人能帮我解决这个问题吗?
大多数时候,我从串行连接获取所有数据,但我希望能够从中删除数据。因此,我得到的示例为:
[b'$GPGGA,093512.000,,,,,0,3,,,M,,M,,*47\r\n', b'$GPGLL,,,,,093512.000,V,N*76\r\n', b'$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r\n', b'$GPGSV,3,1,11,15,72,214,,24,52,276,,13,48,141,,17,31,093,29*70\r\n', b'$GPGSV,3,2,11,18,28,292,,28,27,049,25,19,24,120,24,12,23,211,13*7E\r\n', b'$GPGSV,3
好吧,从中提取数据并不是那么简单,但使用 pynmea2 库( 唯一 我被 允许 使用的库)效果很好。
所以,我现在需要速度、纬度和经度,但速度现在困扰着我。它给出
ValueError: could not convert string to float: "22*49\\r\\n'"
很多次,因为我没有找到正确的方法来查找数据然后“解析”它。
这是我目前的代码使用;
from model.GPSParser import GPSParser
from model.DB import DB
import serial
import time
import datetime
import pynmea2
#########################################
# This is the main code to setup the
# serial connection with the GPS module.
# it needs to be OR runt as root OR as
# pi with all the root rights.
#########################################
port = "/dev/ttyAMA0"
ser = serial.Serial(port, 9600, timeout=0)
#########################################
# These are all the global variables
# to be used. All defined and set to
# zero or their standard 'Null' value.
#########################################
lat = 0.0
lon = 0.0
cur_speed = 0.0
while True:
try:
# Get the data from the serial monitor.
data = str(ser.readlines()).lstrip("b'")[:-3]
# print(data)
#########################################
# Find the speed, to check if we're
# standing still or not. Save it in a
# @var speed
#########################################
if data.find('$GPVTG') != -1:
cur_speed = data.split(",")[7]
#########################################
# Get the Latitude and Longitude
#########################################
if data.find('$GPGGA') != -1:
print(data)
# Check whether the data strings are empty or not.
if GPSParser.parseLatitude(data) != "" and GPSParser.parseLongitude(data) != "":
lat = GPSParser.parseLatitude(data)
lon = GPSParser.parseLongitude(data)
# Debug printing
# print("Latitude: " + GPSParser.parseLatitude(data))
# print("Longitude: " + GPSParser.parseLongitude(data))
# print("Speed: " + cur_speed)
#########################################
# Insert the coordinates into the database
# Be sure to check of we are really driving
# So when the speed is higher then 5 km/u
# Store everything into the database.
#########################################
if float(cur_speed) > 5.0:
db = DB()
db.insertCoordinates(lat, lon, datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
# Wait a bit to not overload the Serial port
time.sleep(0.5)
############################################################
# The error handling
############################################################
except serial.serialutil.SerialException:
ser.close()
port = "/dev/ttyAMA0"
ser = serial.Serial(port, 9600, timeout=0)
continue
except pynmea2.ParseError:
# print("Error on parsing object, continuing...")
continue
except BlockingIOError:
# print("Blocking I/O error, continuing...")
continue
except TypeError:
# print("Type error, continuing...")
continue
except IndexError:
# print("To catch an error...")
continue
except KeyboardInterrupt:
print("\nProgram stopped.")
exit()
因此,从模型导入不会做太多事情,只有数据库连接,“gps 解析器”只是解析数据字符串然后返回它的 pynmea。
所以我想要的是这样的:
它获取每秒脉冲一次的所有数据,然后将其全部拆分成以
$GP
变量开头的块,然后我可以搜索第二个变量部分,例如
VTG
或
GGA
。然后我可以使用该字符串转换为正确的值,以提取速度、纬度、经度和其他数据(如果需要)。
希望你们能很好地理解我并帮助我。
不确定这是否能解决您的问题,但 pynmea2 具有速度属性,在 talker.py 中定义。
import pynmea2
for i, line in enumerate(open('/tmp/nmea.txt').readlines()):
# parsing via pynmea
msg = pynmea2.parse(line.strip())
if msg.sentence_type == 'VTG':
print ('parsing line %s with pynmea:' % i, float(msg.spd_over_grnd_kmph))
# parsing via manually
if line.startswith('$GPVTG'):
cur_speed = line.split(",")[7]
print ('parsing line %s manually:' % i, float(cur_speed))
返回:
parsing line 1 with pynmea: 91.626
parsing line 1 manually: 91.626
parsing line 10 with pynmea: 90.842
parsing line 10 manually: 90.842
parsing line 19 with pynmea: 89.676
parsing line 19 manually: 89.676
我正在开发一个类似的程序,在这个程序中我从 GLL NMEA 语句中收集数据。我使用 try/except 结构来丢弃不完整的数据,这样您就永远不会有空的或损坏的 NMEA 语句。希望它能有所帮助:
# Libraries
import pynmea2
import serial
import io
# --------------------------------------------------------------------------------------------------------------------------------------------------- #
# Variables
lat_Rover1 = []
lat_Rover2 = []
lon_Rover1 = []
lon_Rover2 = []
# --------------------------------------------------------------------------------------------------------------------------------------------------- #
# Defining serial port to a variable
# ROVER 1
serial_port_Rover1 = 'COM3'
ser_Rover1 = serial.Serial(serial_port_Rover1, timeout=3)
# ROVER 2
serial_port_Rover2 = 'COM4'
ser_Rover2 = serial.Serial(serial_port_Rover2, timeout=3)
sio_Rover1 = io.TextIOWrapper(io.BufferedRWPair(ser_Rover1, ser_Rover1))
sio_Rover2 = io.TextIOWrapper(io.BufferedRWPair(ser_Rover2, ser_Rover2))
# --------------------------------------------------------------------------------------------------------------------------------------------------- #
while True:
# Reading NMEA data from Rovers
line_Rover1 = sio_Rover1.readline()
line_Rover2 = sio_Rover2.readline()
try:
msg_Rover1 = pynmea2.parse(line_Rover1, check=False)
msg_Rover2 = pynmea2.parse(line_Rover2, check=False)
except (pynmea2.ChecksumError, pynmea2.ParseError) as e:
print("Error parsing data: " + repr(line_Rover1))
print("Error parsing data: " + repr(line_Rover2))
# --------------------------------------------------------------------------------------------------------------------------------------------------- #
# Appending data to latitude and longitude list values
if msg_Rover1.sentence_type == 'GLL':
with open("NMEAOutputs_Rover1.txt", "a") as outputs:
# Getting only
# lat and lon as GLL
lat_Rover1.append(msg_Rover1.latitude)
lon_Rover1.append(msg_Rover1.longitude)
print(msg_Rover1.latitude,";",msg_Rover1.longitude,";", msg_Rover1.timestamp, file=outputs)
if msg_Rover2.sentence_type == 'GLL':
with open("NMEAOutputs_Rover2.txt", "a") as outputs:
# Getting only lat and lon as GLL
lat_Rover2.append(msg_Rover2.lat)
lon_Rover2.append(msg_Rover2.lon)
print(msg_Rover2.latitude,";",msg_Rover2.longitude,";", msg_Rover2.timestamp, file=outputs)
要获取速度,您可以使用 VTG NMEA 语句,其中以节为单位显示地速。要解析此数据,您可以使用:
# Filter for only GPS satellites
if msg_Rover1.talker == 'GP':
# Filter for only VTG NMEA Sentences
if msg_Rover1.sentence_type == 'VTG':
print(msg_Rover1.data[4])
我知道您说过要将行拆分成块,然后逐个逗号读取数据。但这是一种更简单的方法。
在此示例中,我将纬度、经度和时间戳值存储在 txt 文件中,但您可以对它们执行任何操作。