【纯代码复制粘贴即可使用】卡尔曼滤波的C++实现

使用Eigen实现卡尔曼滤波。如果实现扩展卡尔曼滤波只需将H矩阵换成雅可比的求解。

#ifndef _MYKALMAN_H
#define _MYKALMAN_H
#include <Eigen\Dense>


class KalmanFilter
{
public:
    KalmanFilter(int stateSize, int measSize,int uSize);
    ~KalmanFilter() = default;
    void init(Eigen::VectorXd &x, Eigen::MatrixXd& P,Eigen::MatrixXd& R, Eigen::MatrixXd& Q);
    Eigen::VectorXd predict(Eigen::MatrixXd& A);
    Eigen::VectorXd predict(Eigen::MatrixXd& A, Eigen::MatrixXd &B, Eigen::VectorXd &u);
    void update(Eigen::MatrixXd& H,Eigen::VectorXd z_meas);
private:
    int stateSize_; //state variable's dimenssion
    int measSize_; //measurement variable's dimession
    int uSize_; //control variables's dimenssion
    Eigen::VectorXd x_;
    Eigen::VectorXd z_;
    Eigen::MatrixXd A_;
    Eigen::MatrixXd B_;
    Eigen::VectorXd u_;
    Eigen::MatrixXd P_;//coveriance
    Eigen::MatrixXd H_;
    Eigen::MatrixXd R_;//measurement noise covariance
    Eigen::MatrixXd Q_;//process noise covariance
};

KalmanFilter::KalmanFilter(int stateSize = 0, int measSize = 0, int uSize=0) :stateSize_(stateSize), measSize_(measSize), uSize_(uSize)
{
    if (stateSize_ == 0 || measSize_ == 0)
    {
        std::cerr << "Error, State size and measurement size must bigger than 0\n";
    }

    x_.resize(stateSize_);
    x_.setZero();

    A_.resize(stateSize_, stateSize_);
    A_.setIdentity();

    u_.resize(uSize_);
    u_.transpose();
    u_.setZero();

    B_.resize(stateSize_, uSize_);
    B_.setZero();

    P_.resize(stateSize_, stateSize_);
    P_.setIdentity();

    H_.resize(measSize_, stateSize_);
    H_.setZero();

    z_.resize(measSize_);
    z_.setZero();

    Q_.resize(stateSize_, stateSize_);
    Q_.setZero();

    R_.resize(measSize_, measSize_);
    R_.setZero();
}

void KalmanFilter::init(Eigen::VectorXd &x, Eigen::MatrixXd& P, Eigen::MatrixXd& R, Eigen::MatrixXd& Q)
{
    x_ = x;
    P_ = P;
    R_ = R;
    Q_ = Q;
}
Eigen::VectorXd KalmanFilter::predict(Eigen::MatrixXd& A_, Eigen::MatrixXd &B_, Eigen::VectorXd &u)
{
    A = A_;
    B = B_;
    u_ = u;
    x = A*x + B*u_;
    Eigen::MatrixXd A_T = A.transpose();
    P = A*P*A_T + Q;
    return x;
}

Eigen::VectorXd KalmanFilter::predict(Eigen::MatrixXd& A)
{
    A_ = A;
    x_ = A_*x_;
    Eigen::MatrixXd A_T = A_.transpose();
    P_ = A_*P_*A_T + Q_; 
    return x_;
}

void KalmanFilter::update(Eigen::MatrixXd& H,Eigen::VectorXd z_meas)
{
    H_ = H;
    Eigen::MatrixXd temp1, temp2,Ht;
    Ht = H_.transpose();
    temp1 = H_*P_*Ht + R_;
    temp2 = temp1.inverse();
    Eigen::MatrixXd K = P_*Ht*temp2;
    z_ = H_*x_;
    x_ = x_ + K*(z_meas-z_);
    Eigen::MatrixXd I = Eigen::MatrixXd::Identity(stateSize_, stateSize_);
    P_ = (I - K*H_)*P_;
}
posted @ 2023-12-19 11:05  铃灵狗  阅读(333)  评论(0编辑  收藏  举报