卡尔曼滤波器

Date:

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


class KalmanFilter
{
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
public:
	KalmanFilter(int stateSize_, int measSize_,int uSize_);
	~KalmanFilter(){}
	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);
};
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; 
//	cout << "P-=" << P<< endl;
	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();//(H*P*H'+R)^(-1)
	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;
//	cout << "P=" << P << endl;
}

Julia

using LinearAlgebra

struct KalmanFilter
    stateSize::Int
    measSize::Int
    uSize::Int
    x::Vector{Float64}
    z::Vector{Float64}
    A::Matrix{Float64}
    B::Matrix{Float64}
    u::Vector{Float64}
    P::Matrix{Float64}
    H::Matrix{Float64}
    R::Matrix{Float64}
    Q::Matrix{Float64}
end

function KalmanFilter(stateSize::Int = 0, measSize::Int = 0, uSize::Int = 0)
    if stateSize == 0 || measSize == 0
        throw(ArgumentError("Error, State size and measurement size must be bigger than 0"))
    end

    x = zeros(stateSize)
    A = Matrix{Float64}(I, stateSize, stateSize)
    u = zeros(uSize)
    B = zeros(stateSize, uSize)
    P = Matrix{Float64}(I, stateSize, stateSize)
    H = zeros(measSize, stateSize)
    z = zeros(measSize)
    Q = zeros(stateSize, stateSize)
    R = zeros(measSize, measSize)

    KalmanFilter(stateSize, measSize, uSize, x, z, A, B, u, P, H, R, Q)
end

function init!(kf::KalmanFilter, x::Vector{Float64}, P::Matrix{Float64}, R::Matrix{Float64}, Q::Matrix{Float64})
    kf.x = x
    kf.P = P
    kf.R = R
    kf.Q = Q
end

function predict!(kf::KalmanFilter, A::Matrix{Float64}, B::Matrix{Float64}, u::Vector{Float64})
    kf.A = A
    kf.B = B
    kf.u = u
    kf.x .= A * kf.x .+ B * kf.u
    kf.P .= A * kf.P * A' .+ kf.Q
    return kf.x
end

function predict!(kf::KalmanFilter, A::Matrix{Float64})
    kf.A = A
    kf.x .= A * kf.x
    kf.P .= A * kf.P * A' .+ kf.Q
    return kf.x
end

function update!(kf::KalmanFilter, H::Matrix{Float64}, z_meas::Vector{Float64})
    kf.H = H
    temp1 = kf.H * kf.P * kf.H' .+ kf.R
    temp2 = inv(temp1)
    K = kf.P * kf.H' * temp2
    kf.z .= kf.H * kf.x
    kf.x .+= K * (z_meas .- kf.z)
    I = Matrix{Float64}(I, kf.stateSize, kf.stateSize)
    kf.P = (I .- K * kf.H) * kf.P
end