posts - 0,  comments - 5,  trackbacks - 0
  kalman滤波器听着很深奥的一个东东,其实一点不难。
  我理解的kalman滤波就是通过为对象建立一个特定模型(例如直线匀速运动),来纠正实际观测到的物体运动轨迹到我们认为的运动模型中。
其特点就是随着时间的推移,物体的实际轨迹会逐渐趋近于真实轨迹(与建立的运动模型越来越吻合)。
  一个离散的kalman滤波器可以用2个方程来表示:
  时间更新方程:
 
 空间更新方程:

其中几个参数的细微调节会影响整个滤波器的性能。可以通过尝试去调节参数值。
详细介绍参看:http://www.cs.unc.edu/~welch/kalman/
c++实现的代码如下:
kalman.h
#ifndef __KALMAN_H__
#define __KALMAN_H__

#include 
"Matrix.h"

//discrete kalman filter
class CKalman  
{
public:
    CKalman();
    
~CKalman();

public:
    
/**************Init the param********************/
    
void SetA(CMatrix *pm);
    
void SetB(CMatrix *pm);
    
void SetH(CMatrix *pm);
    
void SetQ(CMatrix *pm);
    
void SetR(CMatrix *pm);

    
/*****************Input variable******************/
    
void InputX0(CMatrix *pm);
    
void InputP0(CMatrix *pm);
    
void InputUkprev(CMatrix *pm);
    
void InputZk(CMatrix *pm);

    
void AssertParam();
public:
    
//time refresh equation
    void RefreshTimeVar();

    
//status refresh equation
    void RefreshStatus();

    
void OutputResult(double *p);

private:
    CMatrix 
*m_pA; //state plus matrix A
    CMatrix *m_pB; //control plus matrix B
    CMatrix *m_pPkPriori; //Priori estimation Pk-
    CMatrix *m_pPkPosteriori; //Posteriori estimation Pk
    CMatrix *m_pPkprev; //Posteriori estimation Pk-1
    CMatrix *m_pH; 
    CMatrix 
*m_pK; //kalman plus matrix
    CMatrix *m_pQ;
    CMatrix 
*m_pR;

    CMatrix 
*m_pXkprev; //Xk-1
    CMatrix *m_pXkPriori; //Priori estimation Xk-
    CMatrix *m_pXkPosteriori; //Posteriori estimation Xk
    CMatrix *m_pUkprev; //control variable;
    CMatrix *m_pZk; //observation variable;


    
bool m_bHasControlVarible;
    
}
;

#endif
kalman.cpp:
#include "kalman.h"
#include 
<assert.h>

CKalman::CKalman()
{
    m_pXkprev 
= NULL; 
    m_pXkPriori 
= NULL; 
    m_pXkPosteriori 
= NULL; 
    m_pUkprev 
= NULL;
    m_pZk 
= NULL;
    m_pA 
= NULL; 
    m_pB 
= NULL; 
    m_pPkPriori 
= NULL; 
    m_pPkPosteriori 
= NULL; 
    m_pPkprev 
= NULL; 
    m_pH 
= NULL; 
    m_pK 
= NULL; 
    m_pQ 
= NULL;
    m_pR 
= NULL;
    m_bHasControlVarible 
= false;
}


CKalman::
~CKalman()
{
    
if (NULL != m_pPkPriori)
    
{
        delete m_pPkPriori;
    }

    
if (NULL != m_pPkPosteriori)
    
{
        delete m_pPkPosteriori;
    }

    
if (NULL != m_pXkPriori)
    
{
        delete m_pXkPriori;
    }

    
if (NULL != m_pXkPosteriori)
    
{
        delete m_pXkPosteriori;
    }

    
}


void CKalman::SetA(CMatrix *pm)
{
    m_pA 
= pm;
}


void CKalman::SetB(CMatrix *pm)
{
    m_pB 
= pm;
}


void CKalman::SetH(CMatrix *pm)
{
    m_pH 
= pm;
}


void CKalman::SetQ(CMatrix *pm)
{
    m_pQ 
= pm;
}


void CKalman::SetR(CMatrix *pm)
{
    m_pR 
= pm;
}


void CKalman::AssertParam()
{
    assert(NULL 
!= m_pXkprev);
    assert(NULL 
!= m_pZk);
    assert(NULL 
!= m_pA);
    assert(NULL 
!= m_pPkprev);
    assert(NULL 
!= m_pH);
    assert(NULL 
!= m_pQ);
    assert(NULL 
!= m_pR);
    
if (m_bHasControlVarible)
    
{
        assert(NULL 
!= m_pUkprev);
        assert(NULL 
!= m_pB);
    }

}


void CKalman::InputX0(CMatrix *pm)
{
    m_pXkprev 
= pm;
    
    
long nWidth = m_pXkprev->getWidth();
    
long nHeight = m_pXkprev->getHeight();

    m_pXkPriori 
= new CMatrix(NULL, nWidth, nHeight);
    m_pXkPosteriori 
= new CMatrix(NULL, nWidth, nHeight);
}


void CKalman::InputP0(CMatrix *pm)
{
    m_pPkprev 
= pm;

    
long nWidth = m_pPkprev->getWidth();
    
long nHeight = m_pPkprev->getHeight();

    m_pPkPriori 
= new CMatrix(NULL, nWidth, nHeight);
    m_pPkPosteriori 
= new CMatrix(NULL, nWidth, nHeight);

}


void CKalman::InputUkprev(CMatrix *pm)
{
    
if (NULL == pm)
    
{
        m_bHasControlVarible 
= false;
    }

    
else
    
{
        m_bHasControlVarible 
= true;
        m_pUkprev 
= pm;
    }

}


void CKalman::InputZk(CMatrix *pm)
{
    m_pZk 
= pm;
}


void CKalman::RefreshTimeVar()
{
    AssertParam();
       
    
if (m_bHasControlVarible)
    
{
        
*m_pXkPriori = (*m_pA)*(*m_pXkprev) + (*m_pB)*(*m_pUkprev);  //1.9
    }

    
else
    
{
        
*m_pXkPriori = (*m_pA)*(*m_pXkprev);
    }

    
    
*m_pPkPriori = (*m_pA)*(*m_pPkprev)*(m_pA->Transpose()) + (*m_pQ); //1.10
}


void CKalman::RefreshStatus()
{
    assert(NULL 
!= m_pZk);
    
    CMatrix mPH;
    mPH 
= (*m_pPkPriori) * (m_pH->Transpose());

    CMatrix mTmp;
    ((
*m_pH) * mPH + (*m_pR)).GetInverse(mTmp);

    
long nHeight = mPH.getHeight();
    
long nWidth = mTmp.getWidth();
    CMatrix mK(NULL, nWidth, nHeight);

    m_pK 
= &mK;
    
*m_pK = mPH * mTmp; //1.11
    *m_pXkPosteriori = *m_pXkPriori + (*m_pK) * (*m_pZk - (*m_pH)*(*m_pXkPriori)); //1.12
    
    CMatrix mUnit(m_pK
->getHeight());
    
*m_pPkPosteriori = (mUnit - (*m_pK)*(*m_pH))*(*m_pPkPriori); //1.13

    
//recursion
    m_pPkprev = m_pPkPosteriori;
    m_pXkprev 
= m_pXkPosteriori;
    m_pZk 
= NULL;
}


void CKalman::OutputResult(double *p)
{
    m_pXkPosteriori
->GetValue(p);
}
其中的matrix实现代码可以参考我以前的文章。
懒了就写到这儿吧
posted on 2011-01-05 15:20 saha 阅读(652) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理



<2024年9月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

常用链接

留言簿

文章分类

文章档案

收藏夹

搜索

  •  

最新评论