东方耀AI技术分享

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 3343|回复: 0
打印 上一主题 下一主题

[通信原理] 卡尔曼滤波算法Python代码实践

[复制链接]

1365

主题

1856

帖子

1万

积分

管理员

Rank: 10Rank: 10Rank: 10

积分
14435
QQ
跳转到指定楼层
楼主
发表于 2021-1-28 09:27:00 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式


卡尔曼滤波算法Python代码实践
卡尔曼认为导弹速度、导弹位置、雷达测距的测量值(误差)这些都服从正态分布 随机变量
卡尔曼滤波算法为了融合雷达测量值和上个时刻的导弹状态数据来减少误差
“两步走”战略:
1、根据上一秒导弹的位置 和 导弹的速度估计出当前时刻导弹的位置粗略估计值
2、将雷达测得导弹位置测量值和我们计算出的导弹位置粗略估计值根据这两种数据可信度来进行线性加权和得到准确的导弹位置估计值


计算粗略估计值(这个是做了一个硬假设:导弹是保持匀速运动


  1. # -*- coding: utf-8 -*-
  2. """
  3. https://zhuanlan.zhihu.com/p/77327349    参考
  4. 卡尔曼滤波算法Python代码实践
  5. 卡尔曼认为导弹速度、导弹位置、雷达测距的测量值(误差)这些都服从正态分布   随机变量
  6. 卡尔曼滤波算法为了融合雷达测量值和上个时刻的导弹状态数据来减少误差
  7. “两步走”战略:
  8. 1、根据上一秒导弹的位置 和 导弹的速度估计出当前时刻导弹的位置粗略估计值
  9. 2、将雷达测得导弹位置测量值和我们计算出的导弹位置粗略估计值根据这两种数据可信度来进行线性加权和得到准确的导弹位置估计值

  10. 计算粗略估计值(这个是做了一个硬假设:导弹是保持匀速运动
  11. """
  12. import numpy as np

  13. # 模拟数据
  14. t = np.linspace(1, 100, 100)
  15. a = 0.5
  16. # 抛物线:模拟真实导弹运动轨迹
  17. position = (a * t ** 2) / 2

  18. # 雷达观测值 加上了雷达的噪声误差  均值为0 标准差为std=120
  19. position_noise_radar = position + np.random.normal(0, 120, size=(t.shape[0]))
  20. import matplotlib.pyplot as plt

  21. plt.plot(t, position, label='truth distance', linestyle='-', color='black', linewidth=4)
  22. plt.plot(t, position_noise_radar, label='radar measured distance', color='blue')

  23. # 初始的估计导弹的位置就直接用雷达测量的位置
  24. # 开始卡尔曼滤波去预测,需要第一个时刻的 距离(第一个没办法,直接用 雷达的观测值) 只能完全相信仪器的
  25. predicts = [position_noise_radar[0]]   # 卡尔曼的预测值 列表 为了画图
  26. position_predict = predicts[0]   # 每一个时刻的 卡尔曼预测值 单个

  27. predict_var = 0   # 估计值的方差
  28. radar_var = 120 ** 2  # 雷达观测的方差,越大则测量值占比越低  var是方差  std是标准差
  29. v_std = 50  # 测量速度仪器的标准差

  30. # 从1开始:不是从0开始   正态分布 均值与方差都需要计算
  31. for i in range(1, t.shape[0]):
  32.     # 仪器读取的速度 = 真实的速度 + 误差(测量速度仪器的)
  33.     dv = (position[i] - position[i - 1]) + np.random.normal(0, v_std)  # 模拟从IMU读取出的速度
  34.     # 这里是计算:粗略估计值的均值(上一个时刻精确估计值 + 速度*时间=当前时刻的粗略估计值的均值)
  35.     position_predict = position_predict + dv*1  # 利用上个时刻的位置和速度预测当前位置
  36.     # 上一个时刻精确估计值的方差 +  速度的方差 = 当前时刻 粗略估计值的方差
  37.     predict_var += v_std ** 2  # 更新方差
  38.     # 下面是Kalman滤波  有个公式:方差为权重

  39.     # 当前时刻的精确预测(计算均值 概率最大的地方)  观测值(雷达)的方差 + 粗略估计值的方差
  40.     # 观测值与当前时刻粗略估计值的融合 = 当前时刻的精确 估计值
  41.     # 根据这两种数据可信度来进行线性加权和得到,当然加权和的权重之和应该等于1,所以除以方差之和
  42.     position_predict = position_predict * radar_var / (predict_var + radar_var) + position_noise_radar[i] * predict_var / (
  43.             predict_var + radar_var)
  44.     # 当前时刻的精确估计值的方差predict_var  (方差之积)除以(方差之和的平方)
  45.     predict_var = (predict_var * radar_var) / (predict_var + radar_var) ** 2
  46.     # 当前时刻的精确 估计值 的均值position_predict
  47.     predicts.append(position_predict)


  48. plt.plot(t, predicts, label='kalman filtered distance', color='red')
  49. plt.xlabel("time(s)")
  50. plt.ylabel("distance(m)")
  51. plt.legend()
  52. # plt.savefig('calman.png', dpi=200)
  53. plt.show()
复制代码


calman.png (97.13 KB, 下载次数: 140)

calman.png
让天下人人学会人工智能!人工智能的前景一片大好!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|人工智能工程师的摇篮 ( 湘ICP备2020019608号-1 )

GMT+8, 2024-4-27 08:07 , Processed in 0.187880 second(s), 21 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表