python卡尔曼多维_Python 实现 卡尔曼滤波器 --非常简单

整体思路很简单,卡尔曼滤波器就是做数据融合的,先给一个GPS的数据(z)和一个里程计数据(u),让他们融合吧。

#!/usr/bin/env python3

# -*- coding: utf-8 -*-

"""

Created on Tue Dec 18 19:37:13 2018

@author: sc

args explanition:

p:covariance

x:state

z:observation

u:control

Pred:predict

Est:estatemation

Q:表示过程激励噪声的协方差,它是状态转移矩阵与实际过程之间的误差。

R:表示测量噪声协方差,和仪器相关的一个特性,

"""

import numpy as np

import math

import matplotlib.pyplot as plt

Q=np.diag([0.1,0.1,math.radians(1.0),1.0])**2

R=np.diag([1.0,math.radians(40.0)])**2

dt=0.1

def motion_model(x,u):

B=np.matrix([[dt*math.cos(x[2,0]),0.0],

[dt*math.sin(x[2,0]),0.0],

[0.0,dt],

[1.0,0.0]])

x=x+B*u

return x

#def observe_model(z):

# H=

# pass

#def JacoMo(xEst,u):

# return jMo

#def JacoOb(xEst):

# return jOb

def JacoMo(x, u):

"""

Jacobian of Motion Model

motion model

x_{t+1} = x_t+v*dt*cos(yaw)

y_{t+1} = y_t+v*dt*sin(yaw)

yaw_{t+1} = yaw_t+omega*dt

v_{t+1} = v{t}

so

dx/dyaw = -v*dt*sin(yaw)

dx/dv = dt*cos(yaw)

dy/dyaw = v*dt*cos(yaw)

dy/dv = dt*sin(yaw)

"""

yaw = x[2, 0]

v = u[0, 0]

jF = np.matrix([[1.0, 0.0, -dt * v * math.sin(yaw), dt * math.cos(yaw)],

[0.0, 1.0, dt * v * math.cos(yaw), dt * math.sin(yaw)],

[0.0, 0.0, 1.0, 0.0],

[0.0, 0.0, 0.0, 1.0]])

return jF

def JacoOb(x):

# Jacobian of Observation Model

jH = np.matrix([

[1, 0, 0, 0],

[0, 1, 0, 0]

])

return jH

def ekf_estimation(xEst,pEst,z,u):

# yu ce predict

xPre=motion_model(xEst,u)

jMo=JacoMo(xEst,u) # Jacobin of motion model

jOb=JacoOb(xEst)

pPre=jMo*pEst*jMo.T+Q

s=jOb*pPre*jOb.T+R

k=pPre*jOb.T*np.linalg.inv(s)

# update estimate

H=np.matrix([

[1,0,0,0],

[0,1,0,0]

])

zPre=H*xPre

xEst=xPre+k*(z-zPre)

pEst=(np.eye(len(xEst)) - k*jOb)*pPre

return xEst,pEst

def input_data(xTrue,xImu):

u=np.matrix([1.0,0.1]).T#jiaosudu he xiansudu

xTrue=motion_model(xTrue,u)

Qsim=np.diag([0.5,0.5])**2

Rsim=np.diag([1.0,math.radians(5.0)])**2

#GPS

z=np.matrix([xTrue[0,0]+np.random.randn()*Qsim[0,0],

xTrue[1,0]+np.random.randn()*Qsim[1,1]]).T

ud=np.matrix([u[0,0]+np.random.randn()*Rsim[0,0],

u[1,0]+np.random.randn()*Rsim[1,1]]).T

xImu=motion_model(xImu,ud)

return ud,z,xTrue,xImu

if __name__=="__main__":

xEst=np.matrix(np.zeros((4,1)))

xTrue=xEst

xImu=xTrue

pEst=np.eye(4)

t=0.1

hTrue=xTrue

hEst=xEst

hz=np.zeros((2,1))

hImu=xImu

for i in range(1000):

u,z,xTrue,xImu=input_data(xTrue,xImu)

xEst,pEst=ekf_estimation(xEst,pEst,z,u)

hTrue=np.hstack((hTrue,xTrue))

hEst=np.hstack((hEst,xEst))

hImu=np.hstack((hImu,xImu))

hz=np.hstack((hz,z))

# plot

plt.cla()

plt.plot(hz[0,:],hz[1,:],".g")

plt.plot(np.array(hTrue[0,:]).flatten(),

np.array(hTrue[1,:]).flatten(),"-b")

plt.plot(np.array(hEst[0,:]).flatten(),

np.array(hEst[1,:]).flatten(),"-r")

plt.plot(np.array(hImu[0,:]).flatten(),

np.array(hImu[1,:]).flatten(),"-k")

plt.pause(0.001)

运行结果:

6ff68bdd946152820cb9a41894da8c57.png

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
卡尔曼滤波是一种用于估计系统状态的算法,它可以有效地处理带有噪声的测量数据,并且可以预测未来的状态。在机器人领域中,卡尔曼滤波可以用于跟踪机器人的位置、速度等状态信息。 下面是一个使用卡尔曼滤波器进行圆周运动跟踪机器人的示例: 1. 首先,我们需要定义机器人的状态量。在这个例子中,我们可以定义机器人的位置和速度: ``` state = np.array([x, y, vx, vy]) ``` 其中,x和y是机器人的坐标,vx和vy是机器人的速度。 2. 接下来,我们需要定义卡尔曼滤波器的状态转移矩阵和测量矩阵。状态转移矩阵描述了系统状态如何随时间推移而变化,测量矩阵描述了如何将系统状态映射到测量值。 对于圆周运动的机器人,我们可以定义状态转移矩阵为: ``` F = np.array([[1, 0, dt, 0], [0, 1, 0, dt], [0, 0, 1, 0], [0, 0, 0, 1]]) ``` 其中,dt是时间步长。该矩阵表示机器人的位置在每个时间步长内根据速度进行更新,速度保持不变。 测量矩阵可以定义为: ``` H = np.array([[1, 0, 0, 0], [0, 1, 0, 0]]) ``` 该矩阵表示测量值是机器人的位置,因此可以将系统状态直接映射到测量值。 3. 接下来,我们需要初始化卡尔曼滤波器的状态和协方差矩阵。状态矩阵表示卡尔曼滤波器对机器人状态的估计,协方差矩阵表示估计的不确定性。 ``` state = np.array([x, y, vx, vy]) P = np.eye(4) * 1000 ``` 其中,P的初始值可以设置为一个较大的值,表示我们对机器人状态的估计相当不确定。 4. 在每个时间步长内,我们需要进行以下操作: - 预测机器人的状态:使用状态转移矩阵来预测机器人的位置和速度,并且更新协方差矩阵。 ``` state = F @ state P = F @ P @ F.T + Q ``` 其中,Q是过程噪声的协方差矩阵,它表示我们对系统的建模有多精确。在这个例子中,我们可以将其设置为: ``` Q = np.array([[0.1, 0, 0, 0], [0, 0.1, 0, 0], [0, 0, 0.1, 0], [0, 0, 0, 0.1]]) ``` - 根据测量值更新机器人的状态:使用测量矩阵将机器人的状态映射到测量值,并且计算测量噪声的协方差矩阵。 ``` z = np.array([measurement_x, measurement_y]) R = np.array([[0.1, 0], [0, 0.1]]) ``` 其中,R是测量噪声的协方差矩阵,它表示我们对测量的精确度有多大。 - 计算卡尔曼增益:卡尔曼增益表示我们对测量值的信任程度。它越大,我们对测量值的信任程度就越高,对预测值的信任程度就越低。 ``` K = P @ H.T @ np.linalg.inv(H @ P @ H.T + R) ``` - 更新机器人的状态和协方差矩阵:使用卡尔曼增益来更新机器人的状态和协方差矩阵。 ``` state = state + K @ (z - H @ state) P = (np.eye(4) - K @ H) @ P ``` 5. 最后,我们可以将机器人的状态用于控制机器人的行动,例如驱动机器人继续进行圆周运动。 这就是使用卡尔曼滤波器进行圆周运动跟踪机器人的基本流程。当然,实际应用中可能需要更复杂的模型和更高级的算法来处理各种噪声和不确定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值