简体   繁体   English

Python中车辆位置估计的卡尔曼滤波器参数定义

[英]Kalman Filter Parameter Definition for Vehicle Position Estimation in Python

I'm relatively new to Kalman filter concepts and I would like to use it for estimating and tracking the accuracy of the position of a vehicle with GPS measurements (As a first step).我对卡尔曼滤波器概念比较陌生,我想用它来估计和跟踪具有 GPS 测量值的车辆位置的准确性(作为第一步)。 However, I am not sure of the assumptions and parameter values that I have considered , and would like to know by other users if I'm headed in the right direction.但是,我不确定我考虑过的假设和参数值,并且希望其他用户知道我是否朝着正确的方向前进。 Thanks!!谢谢!!

I've considered a standard motion model: Constant Velocity (Assuming that acceleration plays no effect on this vehicle's position estimation) and therefore, my states consist of only position and velocity.我考虑了一个标准的运动模型:恒速(假设加速度对这辆车的位置估计没有影响),因此,我的状态只包含位置和速度。
𝑥 𝑘+1 = 𝑥 𝑘 + 𝑥˙ 𝑘 Δ𝑡 𝑥𝑘+ 1 =𝑥𝑘+𝑥˙𝑘Δ𝑡
𝑥˙ 𝑘+1 = 𝑥˙ 𝑘 𝑥˙𝑘+ 1 =𝑥˙𝑘

Therefore, the state transition matrix would be (Considering 2D positioning (x,y) with latitude and longitude coordinates):因此,状态转换矩阵将是(考虑具有纬度和经度坐标的 2D 定位 (x,y)):

A = [[1.0, 0.0, Δ𝑡, 0.0],
     [0.0, 1.0, 0.0, Δ𝑡],
     [0.0, 0.0, 1.0, 0.0],
     [0.0, 0.0, 0.0, 1.0]]

Since we only have position measurement data available, we can correspondingly write the measurement matrix as:由于我们只有位置测量数据可用,我们可以相应地将测量矩阵写为:

H = [[1.0, 0.0, 0.0, 0.0],
     [0.0, 1.0, 0.0, 0.0]]

Initial Conditions:初始条件:
For the initial starting vehicle state x 0 , I assumed all zeroes for the position and velocity (I did read a couple of implementations where they've entered a non-zero value for the position (Usually set to 100), but am not sure about the reason for this)对于初始启动车辆状态 x 0 ,我假设位置和速度全为零(我确实阅读了一些实现,其中他们为位置输入了非零值(通常设置为 100),但我不确定关于这个原因)

For the initial uncertainty P 0 , I assumed an identity matrix with diagonals set to 100 since we are uncertain about the initial position and velocity.对于初始不确定性 P 0 ,我假设对角线设置为 100 的单位矩阵,因为我们不确定初始位置和速度。 Should this value be set higher?这个值应该设置得更高吗? What exactly does it mean when the initial position and velocity are known perfectly with respect to the model?当模型的初始位置和速度完全已知时,这究竟意味着什么? Is it the world coordinates or just some arbitrary position?它是世界坐标还是只是某个任意位置?

Time Step ( Δ𝑡 ):时间步长(Δ𝑡):
Since GPS updates at 1 Hz or every 1 second, I have correspondingly assumed the same for the time step of the filter由于 GPS 以 1 Hz 或每 1 秒更新一次,因此我相应地假设滤波器的时间步长相同

Noise Values:噪音值:
Process Noise: I just assumed an identity matrix for the process noise of the model.过程噪声:我只是假设模型的过程噪声有一个单位矩阵。 But in other implementations, it is also assumed that process noise is zero.但在其他实现中,还假设过程噪声为零。 Does that mean, there are no random fluctuations of the system states?这是否意味着系统状态没有随机波动?

Measurement Noise: Since GPS is the measurement under consideration, the standard deviation for a GPS reading is approximately 6 metres and is considered to be the measurement noise for the system.测量噪声:由于 GPS 是所考虑的测量,因此 GPS 读数的标准偏差约为 6 米,被认为是系统的测量噪声。

Measurement:测量:
I'm using a GPX file exported from an app (Strava) that gives the positioning for latitude and longitude.我正在使用从应用程序 (Strava) 导出的 GPX 文件,该文件提供纬度和经度的定位。 Should this be converted to metres or can I directly use the positioning data from the GPX file?这应该转换为米还是我可以直接使用 GPX 文件中的定位数据?

Please let me know if the above assumptions and implementations are correct :)请让我知道上述假设和实现是否正确:)

UPDATE更新

I directly considered the Lat Long data given by the GPS as a measurement input to the Kalman without first converting it to Cartesian.我直接将 GPS 给出的 Lat Long 数据视为卡尔曼的测量输入,而没有先将其转换为笛卡尔。 In the below code implementation, the data is now first converted to UTM before given as a measurement Input.在下面的代码实现中,数据现在首先转换为 UTM,然后作为测量输入给出。 As suggested by Kani, I will check the calculation conversion given for latitude and longitude and the difference obtained between the 2 techniques.正如 Kani 所建议的,我将检查为纬度和经度给出的计算转换以及两种技术之间获得的差异。

import gpxpy
import pandas as pd
import numpy as np
import utm
import matplotlib.pyplot as plt

with open('test3.gpx') as fh:
    gpx_file = gpxpy.parse(fh)
segment = gpx_file.tracks[0].segments[0]
coords = pd.DataFrame([
    {'lat': p.latitude,
     'lon': p.longitude,
     'ele': p.elevation,
     'time': p.time} for p in segment.points])
coords.head(3)
plt.plot(coords.lon[::18], coords.lat[::18],'ro')
plt.show()
#plt.plot(coords.lon, coords.lat)

def lat_log_posx_posy(coords):

     px, py = [], []
     for i in range(len(coords.lat)):
         dx = utm.from_latlon(coords.lat[i], coords.lon[i])
         px.append(dx[0])
         py.append(dx[1])
     return px, py

def kalman_xy(x, P, measurement, R,
              Q = np.array(np.eye(4))):

    return kalman(x, P, measurement, R, Q,
                  F=np.array([[1.0, 0.0, 1.0, 0.0],
                              [0.0, 1.0, 0.0, 1.0],
                              [0.0, 0.0, 1.0, 0.0],
                              [0.0, 0.0, 0.0, 1.0]]),
                  H=np.array([[1.0, 0.0, 0.0, 0.0],
                              [0.0, 1.0, 0.0, 0.0]]))

def kalman(x, P, measurement, R, Q, F, H):

    y = np.array(measurement).T - np.dot(H,x)
    S = H.dot(P).dot(H.T) + R  # residual convariance
    K = np.dot((P.dot(H.T)), np.linalg.pinv(S))
    x = x + K.dot(y)
    I = np.array(np.eye(F.shape[0]))  # identity matrix
    P = np.dot((I - np.dot(K,H)),P)

    # PREDICT x, P
    x = np.dot(F,x)
    P = F.dot(P).dot(F.T) + Q

    return x, P

def demo_kalman_xy():

    px, py = lat_log_posx_posy(coords)
    plt.plot(px[::18], py[::18], 'ro')
    plt.show()

    x = np.array([px[0], py[0], 0.01, 0.01]).T
    P = np.array(np.eye(4))*1000 # initial uncertainty
    result = []
    R = 0.01**2
    for meas in zip(px, py):
        x, P = kalman_xy(x, P, meas, R)
        result.append((x[:2]).tolist())
    kalman_x, kalman_y = zip(*result)
    plt.plot(px[::18], py[::18], 'ro')
    plt.plot(kalman_x, kalman_y, 'g-')
    plt.show()

demo_kalman_xy()

For the Kalman filter, as with any physics related porblem, the unit of the measurement matters.对于卡尔曼滤波器,与任何与物理相关的问题一样,测量单位很重要。 If you are using velocity as meters per second, the position should not be in latitude/longitude.如果您使用以米每秒为单位的速度,则位置不应位于纬度/经度。 You must convert them to meters.您必须将它们转换为米。

One way you can do that is by selecting the first latitude/longitude pair as the base point and treating all the other points as a distance traveled from the base point.一种方法是选择第一个纬度/经度对作为基点,并将所有其他点视为从基点出发的距离。 This is not a simple calculation as it is a function of multiple things.这不是一个简单的计算,因为它是多种事物的函数。

For really short distances, you can approximate the relative position in meters using the following equations with r being the radius of the earth:对于非常短的距离,您可以使用以下公式来近似以米为单位的相对位置,其中r是地球的半径:

  • distance along latitude = r * deg_to_rad(latitude - base latitude)
  • distance along longitude = 2 * r * asin(cos(base latitude)) * sin(pi / 180 / 2)) * deg_to_rad(longitude - base longitude)

This is tricky for two main reasons though.这很棘手,主要有两个原因。

  1. This is only valid for short distances.这仅适用于短距离。
  2. Earth's radius changes with latitude.地球半径随纬度变化。

Setting Q - process noise covariance matrix, R - measurement noise covariance matrix and P - error covariance matrix depends on what you are trying to track and its conditions and its quite difficult.设置 Q - 过程噪声协方差矩阵,R - 测量噪声协方差矩阵和 P - 误差协方差矩阵取决于您要跟踪的内容及其条件,并且非常困难。 Especially error covariance matrix (P).特别是误差协方差矩阵(P)。

I suggest that you take a look at the jupyter notebook the creator of filterpy library has created to explain how correctly implement Kalman filters.我建议您查看filterpy库的创建者创建的 jupyter notebook,以解释如何正确实现卡尔曼滤波器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM