卡尔曼滤波---C语言实现(二)

简介

本小节,使用C语言来实现卡尔曼滤波。
测试部分待补充。

准备工作

时间更新方程

x^kˉ=Ax^k1+Buk1                {\hat{x}}_{\bar{k}}=A{\hat{x}}_{{k-1}}+Bu_{k-1} ~~~~~~~~~~~~~~~ ①
Pkˉ=APk1AT+Q                P_{\bar{k}}=AP_{k-1}A^T+Q ~~~~~~~~~~~~~~~ ②

状态更新方程

Kk=PkˉHTHPkˉHT+R                K_k=\frac {P_{\bar{k}}H^T} {HP_{\bar{k}}H^T+R}~~~~~~~~~~~~~~~ ③
x^k=x^kˉ+Kk(zkHx^kˉ)                {\hat{x}}_{k}={\hat{x}}_{\bar{k}}+K_k(z_k-H{\hat{x}}_{\bar{k}})~~~~~~~~~~~~~~~ ④
Pk=IKkHPkˉ                P_k=(I-K_kH)P_{\bar{k}}~~~~~~~~~~~~~~~ ⑤

变量对应关系

变量 说明
nn 状态量个数
mm 观测量个数
x^kˉ{\hat{x}}_{\bar{k}} xn×1{x \atop n×1 } 外部输入
PkˉP_{\bar{k}} xn×1{x \atop n×1 } 外部输入
HH Hm×n{H \atop m×n } 外部输入
v=zkHx^kˉv=z_k-H{\hat{x}}_{\bar{k}} vm×1{v \atop m×1 } 外部输入
RR Rm×mR \atop m×m 外部输入
x^k{\hat{x}}_{k} xpn×1{xp \atop n×1 } 输出
PkP_k Ppn×n{Pp \atop n×n } 输出
KkK_k Kn×mK \atop n×m 临时变量
F=PkˉHTF=P_{\bar{k}}H^T Fn×mF \atop n×m 临时变量
S=HPkˉHT+RS=HP_{\bar{k}}H^T+R Sm×mS \atop m×m 临时变量

实现

函数定义

int filter_kalman(const double *x, const double *P, const double *H,
	const double *v, const double *R, int n, int m,
	double *xp, double *Pp)

临时变量

double *F = mat(n, m), *S = mat(m, m), *K = mat(n, m), *I = eye(n);

计算F

matmul("NT", n, m, n, 1.0, P, H, 0.0, F);       /* F = P*H' */

计算S

matcpy(S, R, m, m);
matmul("NN", m, m, n, 1.0, H, F, 1.0, S);		/* S = H*P*H'+R =HF+R  */

计算K

 matinv(S, m)
 matmul("NN", n, m, m, 1.0, F, S, 0.0, K);   /* K = F/S */

计算xp

matcpy(xp, x, n, 1);
matmul("NN", n, 1, m, 1.0, K, v, 1.0, xp);  /* xp = x+K*v */

计算Pp

matmul("NN", n, n, m, -1.0, K, H, 1.0, I);  
matmul("NN", n, n, n, 1.0, I, P, 0.0, Pp);/* Pp = (I-K*H)*P */

完整实现

int filter_kalman(const double *x, const double *P, const double *H,
	const double *v, const double *R, int n, int m,
	double *xp, double *Pp)
{
	double *F = mat(n, m), *S = mat(m, m), *K = mat(n, m), *I = eye(n);
	int info;

	matmul("NT", n, m, n, 1.0, P, H, 0.0, F);       /* F = P*H' */

	matcpy(S, R, m, m);
	matmul("NN", m, m, n, 1.0, H, F, 1.0, S);		/* S = H*P*H'+R =HF+R  */
	if (!(info = matinv(S, m))) {
		matmul("NN", n, m, m, 1.0, F, S, 0.0, K);   /* K = F/S */
		matcpy(xp, x, n, 1);
		matmul("NN", n, 1, m, 1.0, K, v, 1.0, xp);  /* xp = x+K*v */
		matmul("NN", n, n, m, -1.0, K, H, 1.0, I);  
		matmul("NN", n, n, n, 1.0, I, P, 0.0, Pp);/* Pp = (I-K*H)*P */
	}
	free(F); free(S); free(K); free(I);
	return info;
}

测试(暂无,之后补充)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章