applehacker的个人博客分享 http://blog.sciencenet.cn/u/applehacker

博文

C#平台的卡尔曼滤波的实验

已有 8830 次阅读 2013-9-24 11:19 |系统分类:科研笔记| 卡尔曼滤波

最佳线性滤波理论起源于40年代美国科学家Wiener和前苏联科学家Kолмогоров等人的研究工作,后人统称为维纳滤波理论。从理论上说,维纳滤波的最大缺点是必须用到无限过去的数据,不适用于实时处理。为了克服这一缺点,60年代Kalman把状态空间模型引入滤波理论,并导出了一套递推估计算法,后人称之为卡尔曼滤波理论。卡尔曼滤波是以最小均方误差为估计的最佳准则,来寻求一套递推估计的算法,其基本思想是:采用信号与噪声的状态空间模型,利用前一时刻地估计值和现时刻的观测值来更新对状态变量的估计,求出现时刻的估计值。它适合于实时处理和计算机运算。卡尔曼滤波在工程计算中十分有用,所以想去尝试一下卡尔曼滤波器的实现。通过C#平台,采用确定范围内的随机数的方法模拟实际测量值,进行卡尔曼滤波的计算,最后成图。

模拟温度的测量:

最后实际效果图如下:



贴上源代码:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using System.Windows.Forms.DataVisualization.Charting;


namespace 折线图

{

   public partial class Form1 : Form

   {

       public Form1()

       {

           InitializeComponent();

       }

       double[] CanShu = { 23, 9, 16, 16, 1, 0, 0, 0 };

       //double[] Observ = { 22, 24, 24, 25, 24, 26, 21, 26, };

       //double[] Observ = { 25, 26 };

       double[] ObsRand = new double[100];

       private void button1_Click(object sender, EventArgs e)

       {

            //产生随机数列

           

           for (int i = 0; i < 100; i++)

           {

               //Random Random1 = new Random();//这样声明的话,如果多次调用rnd则会会出现每次的随机数值都一样

               Random Random1 = new Random((int)DateTime.Now.Ticks);   //利用系统日期作为参数传进去之后可以解决上面出现的问题

               double i1 = Random1.Next(20, 30);

               double result = Random1.NextDouble() * (-0.99) + 0.99;//随机生成-0.90至0.99的随机双精度数值

               ObsRand[i] = i1+result;

               this.richTextBox2.Text += ObsRand[i].ToString() + "n";

           }

           chart1.Series.Clear();

           graphPoint(chart1, "测量值", ObsRand, Color.PowderBlue);


           double[] True = GetKalMan(CanShu, ObsRand);

           

           graph(chart1, "滤波后值",True, Color.Black);

           double[] Ave = new double[ObsRand.Length];

           for (int i = 0; i < ObsRand.Length; i++)

           {

               Ave[i] = Average;

           }

           graph(chart1, "平均值", Ave, Color.Red);

       }

       //画图函数

       protected void graph(Chart c, string name, double[] vals, Color clr)

       {

           Series s = new Series(name);

           s.ChartType = SeriesChartType.Line;

           

           for (int i = 0; i < vals.Length; i++)

           {

               s.Points.Add(new DataPoint(i, vals[i]));

           }

           s.Color = clr;

           c.Series.Add(s);

       }

       //画图函数2

       protected void graphPoint(Chart c, string name, double[] vals, Color clr)

       {

           Series s = new Series(name);

           s.ChartType = SeriesChartType.Point;


           for (int i = 0; i < vals.Length; i++)

           {

               s.Points.Add(new DataPoint(i, vals[i]));

           }

           s.Color = clr;

           c.Series.Add(s);

       }

       //滤波函数

       double Average;

       public double[] GetKalMan(double[] CanShu, double[] Observe)

       {

           double KamanX = CanShu[0];

           double KamanP = CanShu[1];

           double KamanQ = CanShu[2];

           double KamanR = CanShu[3];

           double KamanY = CanShu[4];

           double KamanKg =CanShu[5];

           double KamanSum = CanShu[6];


           double[] True = new double[ObsRand.Length];

           for (int i = 0; i <= ObsRand.Length - 1; i++)

           {

               KamanY = KamanX;

               KamanP = KamanP + KamanQ;

               KamanKg = KamanP / (KamanP + KamanR);

               KamanX = (KamanY + KamanKg * (Observe[i] - KamanY));

               KamanSum += KamanX;

               True[i] = KamanX;

               this.richTextBox1.Text += KamanX.ToString() + "n";

               KamanP = (1 - KamanKg) * KamanP;


           }

           Average = KamanSum / Observe.Length;

           return True;

       }

   }

}


特别注意一点,产生随机数的时候,一定要获取系统时间点,否则在循环后发现很多值表现为连续一样,不符合实际测量规律

具体算法可以参照维基百科




https://blog.sciencenet.cn/blog-1060307-727434.html

上一篇:星下点卫星轨迹图的生成
收藏 IP: 58.49.103.*| 热度|

0

该博文允许注册用户评论 请点击登录 评论 (0 个评论)

数据加载中...

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-5-4 03:14

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部