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

简介

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

准备工作

时间更新方程

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

状态更新方程

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

变量对应关系

变量说明
n n n状态量个数
m m m观测量个数
x ^ k ˉ {\hat{x}}_{\bar{k}} x^kˉ x n × 1 {x \atop n×1 } n×1x外部输入
P k ˉ P_{\bar{k}} Pkˉ x n × 1 {x \atop n×1 } n×1x外部输入
H H H H m × n {H \atop m×n } m×nH外部输入
v = z k − H x ^ k ˉ v=z_k-H{\hat{x}}_{\bar{k}} v=zkHx^kˉ v m × 1 {v \atop m×1 } m×1v外部输入
R R R R m × m R \atop m×m m×mR外部输入
x ^ k {\hat{x}}_{k} x^k x p n × 1 {xp \atop n×1 } n×1xp输出
P k P_k Pk P p n × n {Pp \atop n×n } n×nPp输出
K k K_k Kk K n × m K \atop n×m n×mK临时变量
F = P k ˉ H T F=P_{\bar{k}}H^T F=PkˉHT F n × m F \atop n×m n×mF临时变量
S = H P k ˉ H T + R S=HP_{\bar{k}}H^T+R S=HPkˉHT+R S m × m S \atop m×m m×mS临时变量

实现

函数定义

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;
}

测试(暂无,之后补充)

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值