根据两个经纬度GPS坐标计算速度

问题描述 投票:0回答:2

我正在摆弄我不久前买的 GPS,“GlobalSat GPS 接收器”型号 BU-S353S4。而且看起来效果很好!

在“Cody Wilsons”出色解释的帮助下,我已经能够从设备读取 GPS 信号!并借助优秀的 python 包“Pynmea2”将 GPGGA 输出转换为经度和纬度坐标。

但是我如何从两个位置计算我当前的速度?我发现这个线程指的是这个线程如何使用半正弦公式计算距离。

我的代码如下所示:

from math import radians, cos, sin, asin, sqrt
import serial
import pynmea2

ser = serial.Serial('/dev/ttyUSB0', 4800, timeout = 5)

def haversine(lon1, lat1, lon2, lat2):
    """
    Calculate the great circle distance in kilometers between two points
    on the earth (specified in decimal degrees)
    """
    # convert decimal degrees to radians
    lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])

    # haversine formula
    dlon = lon2 - lon1
    dlat = lat2 - lat1
    a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
    c = 2 * asin(sqrt(a))
    r = 6371 # Radius of earth in kilometers. Use 3956 for miles. Determines return value units.
    return c * r

counter = 0

while 1:
    line = ser.readline().decode('UTF-8')
    splitline = line.split(',')

    if splitline[0] == '$GPGGA':
        counter += 1
        msg = line
        data = pynmea2.parse(msg)
        lat1 = data.latitude
        lon1 = data.longitude
        if counter % 2:
            distance = haversine(lon1, lat1, data.longitude, data.latitude)
            print(distance)

这会输出我走过的大约每个距离。但问题就在这里,它总是返回

0.0
。我可能还没有走够远?

我应该如何计算速度?

我知道公式速度=距离/时间。 Pynmea2 有时间属性 (

msg.timestamp
)。但坦率地说,我不知道该怎么做。

最终结果似乎有效

from math import radians, cos, sin, asin, sqrt, atan2, degrees
import serial
import pynmea2

ser = serial.Serial('/dev/ttyUSB0', 4800, timeout = 5)

def haversine(lon1, lat1, lon2, lat2):
    """
    Calculate the great circle distance in kilometers between two points
    on the earth (specified in decimal degrees)
    """
    # convert decimal degrees to radians
    lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])

    # haversine formula
    dlon = lon2 - lon1
    dlat = lat2 - lat1
    a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
    c = 2 * asin(sqrt(a))
    r = 6371 # Radius of earth in kilometers. Use 3956 for miles. Determines return value units.
    return c * r

prev_data = None

while 1:
    line = ser.readline().decode('UTF-8')
    splitline = line.split(',')

    if splitline[0] == '$GPGGA':
        msg = line
        data = pynmea2.parse(msg)
        if prev_data is not None:
            distance = haversine(data.longitude, data.latitude, prev_data.longitude, prev_data.latitude)
            print('distance', distance)
            print('speed', round(distance*3600, 2))
        prev_data = data

界面每秒更新一次,因此有速度公式。

python python-3.x gps
2个回答
1
投票

你的半正矢公式是正确的。

您的程序中有一个错误,您将

lat1
lon1
设置为
data.longtitude
data.latitude
,然后立即使用它们来测试与
data.longitude
data.latitude
的距离。 当然,您的距离将为零。 您需要将“当前”经度和纬度与“先前”经度和纬度分开。

(尽管有一点小问题。您不是在计算半正弦,而是使用半正弦计算距离。您可能只想将函数命名为

distance
hav(x) = sin(x/2)**2
'

prev_data = None
while True:
     ....
     if prev_data is not None:
        distance = haversine(data.longitude, data.latitude, 
                             prev_data.longitude, prev_data.latitude)
        pre_data = data
     ....

0
投票

GPGGA
具有位置和时间,但
GPRMC
消息具有直接来自 GPS 接收器的地面速度(以节为单位)。

您可以在此处查看大多数 GPS NMEA 字符串描述的内容,包括 RMC 消息。

pnmea2
中创建一个单独的部分来解析
GPRMC
消息以获取以节为单位的速度。

内置 GPS 速度比基于位置的方法能更好地估计。

© www.soinside.com 2019 - 2024. All rights reserved.