卡尔曼滤波算法及C语言代码
卡尔曼滤波c语言实现
卡尔曼滤波c语言实现
卡尔曼滤波(Kalman filter)是一种著名的非线性估计方法,它由美国工程师R.E.KALMAN于1960年提出。
卡尔曼滤波基本思想是将系统状态采用隐马尔可夫模型来描述,将系统状态的不确定性表示为有限的概率分布,由此建立一个状态估计问题。
c语言实现卡尔曼滤波的步骤如下:
1、初始化:设置初始条件,包括状态变量x的初始值和协方差矩阵P的初始值。
2、预测:根据当前的状态变量x估计下一时刻的状态变量x_prediction。
3、更新:根据观测值z和预测状态变量
x_prediction更新当前状态变量x_update。
4、循环:重复以上步骤,直到达到目标精度或者停止条件。
ekf卡尔曼滤波 c语言
ekf卡尔曼滤波 c语言卡尔曼滤波(Kalman Filter)是一种用于估计动态系统状态的算法,它在信号处理、控制工程和计算机视觉等领域有广泛的应用。
以下是一个简单的 EKF(Extended Kalman Filter,扩展卡尔曼滤波)卡尔曼滤波的 C 语言示例代码:```c#include <stdio.h>#include <math.h>// 定义状态向量结构体typedef struct {double x;double y;} StateVector;// 定义观测向量结构体typedef struct {double z;} ObservationVector;// 初始化卡尔曼滤波器void kalmanFilterInit(StateVector *state, double x0, double y0, double S0, double R0) {state->x = x0;state->y = y0;state->S = S0;state->R = R0;}// 预测状态void kalmanFilterPredict(StateVector *state, double u, double S) {state->x = state->x + u;state->y = state->y + u;state->S = S + S;}// 观测更新void kalmanFilterCorrect(StateVector *state, ObservationVector *observation, double H, double R) {double S = state->S + H * H;double K = state->S / S;state->x = state->x + K * (observation->z - H * state->x);state->y = state->y + K * (observation->z - H * state->y);state->S = S - K * H;}int main() {// 状态向量StateVector state;// 观测向量ObservationVector observation;// 初始状态double x0 = 0.0, y0 = 0.0, S0 = 1.0, R0 = 0.1;// 过程噪声double u = 0.1, S = 0.2;// 观测噪声double H = 1.0, R = 0.2;kalmanFilterInit(&state, x0, y0, S0, R0);for (int i = 0; i < 10; i++) {kalmanFilterPredict(&state, u, S);observation.z = H * state.x + R * (double)rand() / RAND_MAX;kalmanFilterCorrect(&state, &observation, H, R);printf("x = %f, y = %f\n", state.x, state.y);}return 0;}```这个示例代码实现了一个简单的 EKF 卡尔曼滤波。
自适应卡尔曼滤波c语言实现
自适应卡尔曼滤波C语言实现1. 什么是卡尔曼滤波?卡尔曼滤波是一种用于估计系统状态的算法,它基于线性动态系统模型和高斯噪声假设。
卡尔曼滤波器通过不断地更新状态估计值,将测量结果和系统动态进行融合,提供更准确的状态估计。
在实际应用中,传感器测量值常常包含噪声或者不完全准确。
卡尔曼滤波通过对测量值进行加权平均,同时考虑系统的动态模型和测量噪声的特性,可以有效地抑制噪声并提高状态估计的精度。
2. 卡尔曼滤波的基本原理卡尔曼滤波器由两个步骤组成:预测步骤和更新步骤。
预测步骤预测步骤用于根据当前时刻的状态估计值和系统动态模型,预测下一时刻的状态估计值。
假设我们有一个状态向量x表示系统的状态,在每个时刻t,我们可以使用状态转移矩阵A将当前时刻的状态向量x(t)预测到下一时刻的状态向量x(t+1):x(t+1) = A * x(t)同时,我们还需要考虑过程噪声的影响。
假设过程噪声服从均值为0、协方差矩阵为Q的高斯分布,我们可以使用协方差矩阵Q来描述过程噪声的特性。
预测步骤可以表示为:P(t+1|t) = A * P(t|t) * A' + Q其中,P(t|t)表示当前时刻的状态估计误差协方差矩阵,P(t+1|t)表示预测步骤中的状态估计误差协方差矩阵。
更新步骤更新步骤用于根据当前时刻的测量值和预测步骤得到的状态估计值,更新系统状态的估计。
假设我们有一个观测向量z表示系统的观测值,在每个时刻t,我们可以使用观测模型C将当前时刻的状态向量x(t)映射到观测空间中:z(t) = C * x(t)同时,我们还需要考虑观测噪声的影响。
假设观测噪声服从均值为0、协方差矩阵为R的高斯分布,我们可以使用协方差矩阵R来描述观测噪声的特性。
更新步骤可以表示为:K(t+1) = P(t+1|t) * C' * (C * P(t+1|t) * C' + R)^(-1)x(t+1|t+1) = x(t+1|t) + K(t+1) * (z(t+1) - C * x(t+1|t))P(t+1|t+1) = (I - K(t+1) * C) * P(t+1|t)其中,K(t+1)表示卡尔曼增益,x(t+1|t+1)表示更新步骤中的状态估计值,P(t+1|t+1)表示更新步骤中的状态估计误差协方差矩阵。
卡尔曼滤波简介及其实现(附C代码)
卡尔曼滤波简介及其算法实现代码(C++/C/MATLAB)卡尔曼滤波器简介近来发现有些问题很多人都很感兴趣。
所以在这里希望能尽自己能力跟大家讨论一些力所能及的算法。
现在先讨论一下卡尔曼滤波器,如果时间和能力允许,我还希望能够写写其他的算法,例如遗传算法,傅立叶变换,数字滤波,神经网络,图像处理等等。
因为这里不能写复杂的数学公式,所以也只能形象的描述。
希望如果哪位是这方面的专家,欢迎讨论更正。
卡尔曼滤波器– Kalman Filter1.什么是卡尔曼滤波器(What is the Kalman Filter?)在学习卡尔曼滤波器之前,首先看看为什么叫“卡尔曼”。
跟其他著名的理论(例如傅立叶变换,泰勒级数等等)一样,卡尔曼也是一个人的名字,而跟他们不同的是,他是个现代人!卡尔曼全名Rudolf Emil Kalman,匈牙利数学家,1930年出生于匈牙利首都布达佩斯。
1953,1954年于麻省理工学院分别获得电机工程学士及硕士学位。
1957年于哥伦比亚大学获得博士学位。
我们现在要学习的卡尔曼滤波器,正是源于他的博士论文和1960年发表的论文《A New Approach to Linear Filtering and Prediction Problems》(线性滤波与预测问题的新方法)。
如果对这编论文有兴趣,可以到这里的地址下载:/~welch/media/pdf/Kalman1960.pdf。
简单来说,卡尔曼滤波器是一个“optimal recursive data processing algorithm(最优化自回归数据处理算法)”。
对于解决很大部分的问题,他是最优,效率最高甚至是最有用的。
他的广泛应用已经超过30年,包括机器人导航,控制,传感器数据融合甚至在军事方面的雷达系统以及导弹追踪等等。
近年来更被应用于计算机图像处理,例如头脸识别,图像分割,图像边缘检测等等。
2.卡尔曼滤波器的介绍(Introduction to the Kalman Filter)为了可以更加容易的理解卡尔曼滤波器,这里会应用形象的描述方法来讲解,而不是像大多数参考书那样罗列一大堆的数学公式和数学符号。
卡尔曼滤波算法C语言实现
卡尔曼滤波算法及C 语言实现摘要:本文着重讨论了卡尔曼滤波器的原理,典型算法以及应用领域。
清晰地阐述了kalman filter 在信息估计方面的最优性能。
着重介绍简单kalman filter algorithm 的编程,使用kalman filter 的经典5个体现最优化递归公式来编程。
通过c 语言编写程序实现kalman filter 的最优估计能力。
关键词:kalman filter ;最优估计;C 语言1 引言Kalman Filter 是一个高效的递归滤波器,它可以实现从一系列的噪声测量中,估计动态系统的状态。
起源于Rudolf Emil Kalman 在1960年的博士论文和发表的论文《A New Approach to Linear Eiltering and Prediction Problems 》(《线性滤波与预测问题的新方法》)。
并且最先在阿波罗登月计划轨迹预测上应用成功,此后kalman filter 取得重大发展和完善。
它的广泛应用已经超过30年,包括机器人导航,控制。
传感器数据融合甚至在军事方面的雷达系统以及导弹追踪等等,近年来更被广泛应用于计算机图像处理,例如头脸识别,图像分割,图像边缘检测等等。
2 kalman filter 最优化递归估计Kalman filter 是一个“optimal recursive data processing algorithm (最优化递归数据处理方法)”。
对于解决很大部分的问题,他是最优,效率最高甚至是最有用的方法。
而kalman filter 最为核心的内容是体现它最优化估计和递归特点的5条公式。
举一个例子来详细说明5条公式的物理意义。
假设我们要研究的对象是某一个房间的温度信号。
对于室温来说,一分钟内或一小段时间内的值是基本上不变的或者变化范围很小。
也就是说时刻的温度和时刻的温度1t 1T 2t 基本不变,即。
在这个过程中,因为毕竟温度还是有所改变的,设有几度的偏差。
(完整word版)卡尔曼滤波算法(C--C++两种实现代码)
卡尔曼滤波算法实现代码C++实现代码如下: ============================kalman.h================= =============== // kalman.h: interface for the kalman class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_KALMAN_H__ED3D740F_01D2_4616_8B74_8BF57636F2C0__IN CLUDED_) #define AFX_KALMAN_H__ED3D740F_01D2_4616_8B74_8BF57636F2C0__INCLU DED_#if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000#include <math.h> #include "cv.h"class kalman { public: void init_kalman(int x,int xv,int y,int yv); CvKalman* cvkalman; CvMat* state; CvMat* process_noise; CvMat* measurement; const CvMat* prediction; CvPoint2D32f get_predict(float x, float y);kalman(int x=0,int xv=0,int y=0,int yv=0); //virtual ~kalman();};#endif // !defined(AFX_KALMAN_H__ED3D740F_01D2_4616_8B74_8BF57636F2C 0__INCLUDED_)============================kalman.cpp=============== =================#include "kalman.h" #include <stdio.h>/* tester de printer toutes les valeurs des vecteurs */ /* tester de changer les matrices du noises */ /* replace state by cvkalman->state_post ??? */CvRandState rng; const double T = 0.1; kalman::kalman(int x,int xv,int y,int yv) {cvkalman = cvCreateKalman( 4, 4, 0 ); state = cvCreateMat( 4, 1, CV_32FC1 ); process_noise = cvCreateMat( 4, 1, CV_32FC1 ); measurement = cvCreateMat( 4, 1, CV_32FC1 ); int code = -1;/* create matrix data */ const float A[] = { 1, T, 0, 0, 0, 1, 0, 0, 0, 0, 1, T, 0, 0, 0, 1 };const float H[] = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 };const float P[] = { pow(320,2), pow(320,2)/T, 0, 0, pow(320,2)/T, pow(320,2)/pow(T,2), 0, 0, 0, 0, pow(240,2), pow(240,2)/T, 0, 0, pow(240,2)/T, pow(240,2)/pow(T,2) };const float Q[] = { pow(T,3)/3, pow(T,2)/2, 0, 0, pow(T,2)/2, T, 0, 0, 0, 0, pow(T,3)/3, pow(T,2)/2, 0, 0, pow(T,2)/2, T };const float R[] = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }; cvRandInit( &rng, 0, 1, -1, CV_RAND_UNI );cvZero( measurement );cvRandSetRange( &rng, 0, 0.1, 0 ); rng.disttype = CV_RAND_NORMAL;cvRand( &rng, state );memcpy( cvkalman->transition_matrix->data.fl, A, sizeof(A)); memcpy( cvkalman->measurement_matrix->data.fl, H, sizeof(H)); memcpy( cvkalman->process_noise_cov->data.fl, Q, sizeof(Q)); memcpy( cvkalman->error_cov_post->data.fl, P, sizeof(P)); memcpy( cvkalman->measurement_noise_cov->data.fl, R, sizeof(R)); //cvSetIdentity( cvkalman->process_noise_cov, cvRealScalar(1e-5) ); //cvSetIdentity( cvkalman->error_cov_post, cvRealScalar(1)); //cvSetIdentity( cvkalman->measurement_noise_cov, cvRealScalar(1e-1) );/* choose initial state */state->data.fl[0]=x; state->data.fl[1]=xv; state->data.fl[2]=y;state->data.fl[3]=yv; cvkalman->state_post->data.fl[0]=x; cvkalman->state_post->data.fl[1]=xv; cvkalman->state_post->data.fl[2]=y; cvkalman->state_post->data.fl[3]=yv;cvRandSetRange( &rng, 0, sqrt(cvkalman->process_noise_cov->data.fl[0]), 0 ); cvRand( &rng, process_noise ); }CvPoint2D32f kalman::get_predict(float x, float y) {/* update state with current position */ state->data.fl[0]=x; state->data.fl[2]=y;/* predict point position */ /* x'k=A 鈥 k+B 鈥 kP'k=A 鈥 k-1*AT + Q */ cvRandSetRange( &rng, 0, sqrt(cvkalman->measurement_noise_cov->data.fl [0]), 0 ); cvRand( &rng, measurement );/* xk=A?xk-1+B?uk+wk */ cvMatMulAdd( cvkalman->transition_matrix, state, process_noise, cvkalman-> state_post );/* zk=H?xk+vk */cvMatMulAdd( cvkalman->measurement_matrix, cvkalman->state_post, meas urement, measurement );cvKalmanCorrect( cvkalman, measurement ); float measured_value_x = measurement->data.fl[0]; float measured_value_y = measurement->data.fl[2];const CvMat* prediction = cvKalmanPredict( cvkalman, 0 ); float predict_value_x = prediction->data.fl[0]; float predict_value_y = prediction->data.fl[2];return(cvPoint2D32f(predict_value_x,predict_value_y)); }void kalman::init_kalman(int x,int xv,int y,int yv) { state->data.fl[0]=x;state->data.fl[1]=xv; state->data.fl[2]=y; state->data.fl[3]=yv; cvkalman->state_post->data.fl[0]=x; cvkalman->state_post->data.fl[1]=xv; cvkalman->state_post->data.fl[2]=y; cvkalman->state_post->data.fl[3]=yv; }c 语言实现代码如下:#include "stdlib.h" #include "rinv.c" int lman(n,m,k,f,q,r,h,y,x,p,g) int n,m,k; double f[],q[],r[],h[],y[],x[],p[],g[]; { int i,j,kk,ii,l,jj,js; double *e,*a,*b; e=malloc(m*m*sizeof(double)); l=m; if (l<n) l=n; a=malloc(l*l*sizeof(double)); b=malloc(l*l*sizeof(double)); for (i=0; i<=n-1; i++) for (j=0; j<=n-1; j++) { ii=i*l+j; a[ii]=0.0; for (kk=0; kk<=n-1; kk++) a[ii]=a[ii]+p[i*n+kk]*f[j*n+kk]; } for (i=0; i<=n-1; i++) for (j=0; j<=n-1; j++) { ii=i*n+j; p[ii]=q[ii]; for (kk=0; kk<=n-1; kk++) p[ii]=p[ii]+f[i*n+kk]*a[kk*l+j]; } for (ii=2; ii<=k; ii++) { for (i=0; i<=n-1; i++) for (j=0; j<=m-1; j++) { jj=i*l+j; a[jj]=0.0;for (kk=0; kk<=n-1; kk++) a[jj]=a[jj]+p[i*n+kk]*h[j*n+kk];} for (i=0; i<=m-1; i++) for (j=0; j<=m-1; j++){ jj=i*m+j; e[jj]=r[jj]; for (kk=0; kk<=n-1; kk++)e[jj]=e[jj]+h[i*n+kk]*a[kk*l+j]; } js=rinv(e,m); if (js==0){ free(e); free(a); free(b); return(js);} for (i=0; i<=n-1; i++) for (j=0; j<=m-1; j++){ jj=i*m+j; g[jj]=0.0; for (kk=0; kk<=m-1; kk++)g[jj]=g[jj]+a[i*l+kk]*e[j*m+kk]; } for (i=0; i<=n-1; i++){ jj=(ii-1)*n+i; x[jj]=0.0; for (j=0; j<=n-1; j++)x[jj]=x[jj]+f[i*n+j]*x[(ii-2)*n+j]; } for (i=0; i<=m-1; i++){ jj=i*l; b[jj]=y[(ii-1)*m+i]; for (j=0; j<=n-1; j++) b[jj]=b[jj]-h[i*n+j]*x[(ii-1)*n+j]; } for (i=0; i<=n-1; i++) { jj=(ii-1)*n+i;for (j=0; j<=m-1; j++) x[jj]=x[jj]+g[i*m+j]*b[j*l];} if (ii<k){ for (i=0; i<=n-1; i++) for (j=0; j<=n-1; j++){ jj=i*l+j; a[jj]=0.0; for (kk=0; kk<=m-1; kk++)a[jj]=a[jj]-g[i*m+kk]*h[kk*n+j]; if (i==j) a[jj]=1.0+a[jj]; } for (i=0; i<=n-1; i++) for (j=0; j<=n-1; j++) { jj=i*l+j; b[jj]=0.0; for (kk=0; kk<=n-1; kk++) b[jj]=b[jj]+a[i*l+kk]*p[kk*n+j]; } for (i=0; i<=n-1; i++) for (j=0; j<=n-1; j++) { jj=i*l+j; a[jj]=0.0; for (kk=0; kk<=n-1; kk++) a[jj]=a[jj]+b[i*l+kk]*f[j*n+kk]; } for (i=0; i<=n-1; i++) for (j=0; j<=n-1; j++) { jj=i*n+j; p[jj]=q[jj]; for (kk=0; kk<=n-1; kk++) p[jj]=p[jj]+f[i*n+kk]*a[j*l+kk]; } }} free(e); free(a); free(b); return(js);}。
卡尔曼滤波c语言
卡尔曼滤波c语言卡尔曼滤波是一种用于估计系统状态的算法,它可以通过将系统测量值和先验估计值进行加权平均,得到一个更准确的状态估计值。
以下是一个简单的卡尔曼滤波的C语言实现示例:c#include <stdio.h>#define SENSOR_NOISE 0.1 测量噪声方差#define PROCESS_NOISE 0.001 过程噪声方差float kalman_filter(float measurement, float previous_estimate, float previous_covariance) {预测步骤float predicted_estimate = previous_estimate;float predicted_covariance = previous_covariance +PROCESS_NOISE;更新步骤float kalman_gain = predicted_covariance / (predicted_covariance + SENSOR_NOISE);float current_estimate = predicted_estimate + kalman_gain *(measurement - predicted_estimate);float current_covariance = (1 - kalman_gain) * predicted_covariance;return current_estimate;}int main() {float measurement1 = 10.5;float measurement2 = 12.3;float estimate = 0; 初始估计值float covariance = 1; 初始估计方差estimate = kalman_filter(measurement1, estimate, covariance);printf("Estimate after measurement1: %f\n", estimate);estimate = kalman_filter(measurement2, estimate, covariance);printf("Estimate after measurement2: %f\n", estimate);return 0;}在上述示例中,传感器测量值和初始估计值分别通过`kalman_filter`函数进行卡尔曼滤波处理。
卡尔曼滤波算法及C语言代码
卡尔曼滤波简介及其算法实现代码卡尔曼滤波算法实现代码(C,C++分别实现)卡尔曼滤波器简介近来发现有些问题很多人都很感兴趣。
所以在这里希望能尽自己能力跟大家讨论一些力所能及的算法。
现在先讨论一下卡尔曼滤波器,如果时间和能力允许,我还希望能够写写其他的算法,例如遗传算法,傅立叶变换,数字滤波,神经网络,图像处理等等。
因为这里不能写复杂的数学公式,所以也只能形象的描述。
希望如果哪位是这方面的专家,欢迎讨论更正。
卡尔曼滤波器– Kalman Filter1.什么是卡尔曼滤波器(What is the Kalman Filter?)在学习卡尔曼滤波器之前,首先看看为什么叫“卡尔曼”。
跟其他著名的理论(例如傅立叶变换,泰勒级数等等)一样,卡尔曼也是一个人的名字,而跟他们不同的是,他是个现代人!卡尔曼全名Rudolf Emil Kalman,匈牙利数学家,1930年出生于匈牙利首都布达佩斯。
1953,1954年于麻省理工学院分别获得电机工程学士及硕士学位。
1957年于哥伦比亚大学获得博士学位。
我们现在要学习的卡尔曼滤波器,正是源于他的博士论文和1960年发表的论文《A New Approach to Linear Filtering and Prediction Problems》(线性滤波与预测问题的新方法)。
如果对这编论文有兴趣,可以到这里的地址下载:/~welch/media/pdf/Kalman1960.pdf。
简单来说,卡尔曼滤波器是一个“optimal recursive data processing algorithm(最优化自回归数据处理算法)”。
对于解决很大部分的问题,他是最优,效率最高甚至是最有用的。
他的广泛应用已经超过30年,包括机器人导航,控制,传感器数据融合甚至在军事方面的雷达系统以及导弹追踪等等。
近年来更被应用于计算机图像处理,例如头脸识别,图像分割,图像边缘检测等等。
2.卡尔曼滤波器的介绍(Introduction to the Kalman Filter)为了可以更加容易的理解卡尔曼滤波器,这里会应用形象的描述方法来讲解,而不是像大多数参考书那样罗列一大堆的数学公式和数学符号。
卡尔曼滤波代码c
卡尔曼滤波代码c卡尔曼滤波是一种用于估计系统状态的滤波算法。
以下是一个简单的卡尔曼滤波的 C 代码实现:```c#include <stdio.h>#define Q 0.1 // 过程噪声的方差#define R 1.0 // 测量噪声的方差void kalman_filter(float* x, float* P, float z, float* K) {// 预测步骤float x_pred = *x;float P_pred = *P + Q;// 更新步骤float y = z - x_pred;float S = P_pred + R;float K_gain = P_pred / S;*x = x_pred + K_gain * y;*P = (1 - K_gain) * P_pred;*K = K_gain;}int main() {float x = 0; // 初始状态float P = 1; // 初始协方差float K; // 卡尔曼增益float measurements[] = {1, 2, 3, 4, 5}; // 测量值for (int i = 0; i < 5; i++) {kalman_filter(&x, &P, measurements[i], &K);printf("Measurement: %.2f, Estimated: %.2f\n", measurements[i], x);}return 0;}```在这个例子中,我们使用卡尔曼滤波来估计一个连续的测量值序列。
在每次测量后,我们调用`kalman_filter` 函数来更新状态估计值`x` 和协方差 `P`。
然后,我们打印出当前测量值和估计值。
这只是一个简单的卡尔曼滤波实现,更复杂的应用可能需要更多的参数和计算。
如果你有特定的应用需求,可以根据卡尔曼滤波的原理进行相应的调整和扩展。
自适应卡尔曼滤波c语言实现
自适应卡尔曼滤波c语言实现自适应卡尔曼滤波(Adaptive Kalman Filtering)是一种改进的卡尔曼滤波算法,它能够在系统噪声和测量噪声方差未知或变化的情况下,自动调整卡尔曼滤波器的参数,以提高滤波效果。
以下是一个简单的C语言实现自适应卡尔曼滤波的示例代码:```c#include <stdio.h>#define STATE_DIMENSION 2 // 状态维度#define MEASUREMENT_DIMENSION 1 // 测量维度typedef struct {double x[STATE_DIMENSION]; // 状态向量double P[STATE_DIMENSION][STATE_DIMENSION]; // 状态协方差矩阵double Q[STATE_DIMENSION][STATE_DIMENSION]; //过程噪声协方差矩阵doubleR[MEASUREMENT_DIMENSION][MEASUREMENT_DIMEN SION]; // 测量噪声协方差矩阵} KalmanFilter;void kalman_filter_init(KalmanFilter* kf) {// 初始化状态向量kf->x[0] = 0.0;kf->x[1] = 0.0;// 初始化状态协方差矩阵kf->P[0][0] = 0.0;kf->P[0][1] = 0.0;kf->P[1][0] = 0.0;kf->P[1][1] = 0.0;// 初始化过程噪声协方差矩阵kf->Q[0][0] = 0.1;kf->Q[0][1] = 0.0;kf->Q[1][0] = 0.0;kf->Q[1][1] = 0.1;// 初始化测量噪声协方差矩阵kf->R[0][0] = 1.0;}void kalman_filter_update(KalmanFilter* kf, double z) {// 预测步骤double x_hat[STATE_DIMENSION];double P_hat[STATE_DIMENSION][STATE_DIMENSION]; doubleK[STATE_DIMENSION][MEASUREMENT_DIMENSION]; for (int i = 0; i < STATE_DIMENSION; i++) {x_hat[i] = kf->x[i];for (int j = 0; j < STATE_DIMENSION; j++) {x_hat[i] += kf->Q[i][j] * kf->x[j];}}for (int i = 0; i < STATE_DIMENSION; i++) {for (int j = 0; j < STATE_DIMENSION; j++) {P_hat[i][j] = kf->P[i][j] + kf->Q[i][j];}}// 更新步骤double y = z - x_hat[0];double S = P_hat[0][0] + kf->R[0][0];double K0 = P_hat[0][0] / S;kf->x[0] = x_hat[0] + K0 * y;kf->P[0][0] = (1 - K0) * P_hat[0][0];}int main() {KalmanFilter kf;double measurements[] = {0.1, 0.2, 0.3, 0.4, 0.5}; // 测量值序列kalman_filter_init(&kf);for (int i = 0; i < sizeof(measurements) / sizeof(double); i++) { kalman_filter_update(&kf, measurements[i]);printf("x[%d] = %f\n", i, kf.x[0]);}return 0;}这个示例代码实现了一个一维自适应卡尔曼滤波器,用于对一个测量值序列进行滤波。
卡尔曼滤波c语言姿态解算
卡尔曼滤波c语言姿态解算
摘要:
一、卡尔曼滤波简介
1.卡尔曼滤波的定义
2.卡尔曼滤波的应用领域
二、卡尔曼滤波的原理
1.卡尔曼滤波的基本思想
2.卡尔曼滤波的基本步骤
三、卡尔曼滤波在姿态解算中的应用
1.姿态解算的定义
2.姿态解算在导航系统中的重要性
3.卡尔曼滤波在姿态解算中的应用实例
四、卡尔曼滤波的C 语言实现
1.C 语言实现的基本步骤
2.C 语言实现的注意事项
3.C 语言实现的示例代码
正文:
一、卡尔曼滤波简介
卡尔曼滤波是一种线性滤波方法,主要用于估计动态系统的状态。
该方法是由俄国数学家卡尔曼提出的,被广泛应用于航空航天、自动化控制、通信、计算机等领域。
二、卡尔曼滤波的原理
卡尔曼滤波的基本思想是在系统的观测数据中,通过加权最小二乘法来估计系统的状态。
其基本步骤包括:
1.建立系统状态的数学模型
2.计算系统的观测值
3.构造卡尔曼增益公式
4.更新系统状态的估计值
三、卡尔曼滤波在姿态解算中的应用
姿态解算是指通过测量和计算,确定飞行器或其他运动物体的姿态参数,如位置、速度、加速度等。
在导航系统中,姿态解算是非常重要的一个环节。
一维卡尔曼滤波c语言
一维卡尔曼滤波c语言以下是一个简单的用C语言实现的一维卡尔曼滤波的示例:```cinclude <>// 定义状态变量和观测变量typedef struct {double x;} State;typedef struct {double z;} Measurement;// 定义卡尔曼滤波器结构体typedef struct {State x_est; // 估计状态变量State x_pred; // 预测状态变量double P; // 估计误差协方差double K; // 卡尔曼增益} KalmanFilter;// 初始化卡尔曼滤波器void kalman_filter_init(KalmanFilter kf, double Q, double R, double P0, double x0) {kf->x_ = x0;kf->P = P0;kf->K = 0;}// 更新状态变量和观测变量void kalman_filter_update(KalmanFilter kf, Measurement z) {// 预测状态变量和误差协方差kf->x_ = kf->x_;kf->P = kf->P + kf->Q;// 计算卡尔曼增益kf->K = kf->P / (kf->P + kf->R);// 更新估计状态变量和误差协方差kf->x_ = kf->x_ + kf->K (z->z - kf->x_);kf->P = (1 - kf->K) kf->P;}int main() {// 定义卡尔曼滤波器参数和观测数据KalmanFilter kf;Measurement z[10] = {, , , , , , , , , };double Q = ; // 过程噪声协方差double R = ; // 观测噪声协方差double P0 = 1; // 初始估计误差协方差double x0 = 0; // 初始状态变量值kalman_filter_init(&kf, Q, R, P0, x0);// 进行卡尔曼滤波处理for (int i = 0; i < 10; i++) {kalman_filter_update(&kf, &z[i]);printf("Time step %d: x = %f, P = %f\n", i+1, _, ); }return 0;} ```。
卡尔曼滤波(C语言,二维)
state->q[0] = 10e-7; //
state->q[1] = 10e-7; //
state->r = 10e-7; /* estimated error convariance */
float temp1;
float temp;
/* Step1: Predict */
state->x[0] = state->A[0][0] * state->x[0] + state->A[0][1] * state->x[1]; //预测当前角速度状态值 自变化+互变化 由于state->A[0][1]为0.1,所以角度的变化是由角速度的测量*0.1得到角度,现有的角度,此式子即是角速度积分累加成角度
state->p[0][0] = state->A[0][0] * state->p[0][0] + state->A[0][1] * state->p[1][0] + state->q[0]; //计算角度方差P,实际上是P(k|k-1)=A*P(k-1|k-1) +Q
state->p[0][1] = state->A[0][0] * state->p[0][1] + state->A[1][1] * state->p[1][1]; //
//矩阵的维数与卡尔曼的维数相同
/********************************************************************************************************/
卡尔曼滤波算法(C--C++两种实现代码)
卡尔曼滤波算法实现代码C++实现代码如下:============================kalman.h================= ===============// kalman.h: interface for the kalman class.////////////////////////////////////////////////////////////////////////#if !defined(AFX_KALMAN_H__ED3D740F_01D2_4616_8B74_8BF57636F2C0__IN CLUDED_)#define AFX_KALMAN_H__ED3D740F_01D2_4616_8B74_8BF57636F2C0__INCLU DED_#if _MSC_VER > 1000#pragma once#endif// _MSC_VER > 1000#include <math.h>#include "cv.h"class kalman{public:void init_kalman(int x,int xv,int y,int yv);CvKalman* cvkalman;CvMat* state;CvMat* process_noise;CvMat* measurement;const CvMat* prediction;CvPoint2D32f get_predict(float x, float y);kalman(int x=0,int xv=0,int y=0,int yv=0);//virtual ~kalman();};#endif// !defined(AFX_KALMAN_H__ED3D740F_01D2_4616_8B74_8BF57636F2C 0__INCLUDED_)============================kalman.cpp=============== =================#include "kalman.h"#include <stdio.h>/* tester de printer toutes les valeurs des vecteurs*//* tester de changer les matrices du noises *//* replace state by cvkalman->state_post ??? */CvRandState rng;const double T = 0.1;kalman::kalman(int x,int xv,int y,int yv){cvkalman = cvCreateKalman( 4, 4, 0 );state = cvCreateMat( 4, 1, CV_32FC1 );process_noise = cvCreateMat( 4, 1, CV_32FC1 );measurement = cvCreateMat( 4, 1, CV_32FC1 );int code = -1;/* create matrix data */const float A[] = {1, T, 0, 0,0, 1, 0, 0,0, 0, 1, T,0, 0, 0, 1};const float H[] = {1, 0, 0, 0,0, 0, 0, 0,0, 0, 1, 0,0, 0, 0, 0};const float P[] = {pow(320,2), pow(320,2)/T, 0, 0,pow(320,2)/T, pow(320,2)/pow(T,2), 0, 0, 0, 0, pow(240,2), pow(240,2)/T,0, 0, pow(240,2)/T, pow(240,2)/pow(T,2) };const float Q[] = {pow(T,3)/3, pow(T,2)/2, 0, 0,pow(T,2)/2, T, 0, 0,0, 0, pow(T,3)/3, pow(T,2)/2,0, 0, pow(T,2)/2, T};const float R[] = {1, 0, 0, 0,0, 0, 0, 0,0, 0, 1, 0,0, 0, 0, 0};cvRandInit( &rng, 0, 1, -1, CV_RAND_UNI );cvZero( measurement );cvRandSetRange( &rng, 0, 0.1, 0 );rng.disttype = CV_RAND_NORMAL;cvRand( &rng, state );memcpy( cvkalman->transition_matrix->data.fl, A, sizeof(A));memcpy( cvkalman->measurement_matrix->data.fl, H, sizeof(H));memcpy( cvkalman->process_noise_cov->data.fl, Q, sizeof(Q));memcpy( cvkalman->error_cov_post->data.fl, P, sizeof(P));memcpy( cvkalman->measurement_noise_cov->data.fl, R, sizeof(R));//cvSetIdentity( cvkalman->process_noise_cov, cvRealScalar(1e-5) ); //cvSetIdentity( cvkalman->error_cov_post, cvRealScalar(1));//cvSetIdentity( cvkalman->measurement_noise_cov, cvRealScalar(1e-1) );/* choose initial state */state->data.fl[0]=x;state->data.fl[1]=xv;state->data.fl[2]=y;state->data.fl[3]=yv;cvkalman->state_post->data.fl[0]=x;cvkalman->state_post->data.fl[1]=xv;cvkalman->state_post->data.fl[2]=y;cvkalman->state_post->data.fl[3]=yv;cvRandSetRange( &rng, 0, sqrt(cvkalman->process_noise_cov->data.fl[0]), 0 ); cvRand( &rng, process_noise );}CvPoint2D32f kalman::get_predict(float x, float y){/* update state with current position */state->data.fl[0]=x;state->data.fl[2]=y;/* predict point position *//* x'k=A鈥鈥P'k=A鈥-1*AT + Q */cvRandSetRange( &rng, 0, sqrt(cvkalman->measurement_noise_cov->data.fl [0]), 0 );cvRand( &rng, measurement );/* xk=A?xk-1+B?uk+wk */cvMatMulAdd( cvkalman->transition_matrix, state, process_noise, cvkalman-> state_post );/* zk=H?xk+vk */cvMatMulAdd( cvkalman->measurement_matrix, cvkalman->state_post, meas urement, measurement );cvKalmanCorrect( cvkalman, measurement );float measured_value_x = measurement->data.fl[0];float measured_value_y = measurement->data.fl[2];const CvMat* prediction = cvKalmanPredict( cvkalman, 0 );float predict_value_x = prediction->data.fl[0];float predict_value_y = prediction->data.fl[2];return(cvPoint2D32f(predict_value_x,predict_value_y));}void kalman::init_kalman(int x,int xv,int y,int yv){state->data.fl[0]=x;state->data.fl[1]=xv;state->data.fl[2]=y;state->data.fl[3]=yv;cvkalman->state_post->data.fl[0]=x;cvkalman->state_post->data.fl[1]=xv;cvkalman->state_post->data.fl[2]=y;cvkalman->state_post->data.fl[3]=yv;}c语言实现代码如下:#include "stdlib.h"#include "rinv.c"int lman(n,m,k,f,q,r,h,y,x,p,g)int n,m,k;double f[],q[],r[],h[],y[],x[],p[],g[];{ int i,j,kk,ii,l,jj,js;double *e,*a,*b;e=malloc(m*m*sizeof(double));l=m;if (l<n) l=n;a=malloc(l*l*sizeof(double));b=malloc(l*l*sizeof(double));for (i=0; i<=n-1; i++)for (j=0; j<=n-1; j++){ ii=i*l+j; a[ii]=0.0;for (kk=0; kk<=n-1; kk++)a[ii]=a[ii]+p[i*n+kk]*f[j*n+kk];}for (i=0; i<=n-1; i++)for (j=0; j<=n-1; j++){ ii=i*n+j; p[ii]=q[ii];for (kk=0; kk<=n-1; kk++)p[ii]=p[ii]+f[i*n+kk]*a[kk*l+j];}for (ii=2; ii<=k; ii++){ for (i=0; i<=n-1; i++)for (j=0; j<=m-1; j++){ jj=i*l+j; a[jj]=0.0;for (kk=0; kk<=n-1; kk++)a[jj]=a[jj]+p[i*n+kk]*h[j*n+kk];}for (i=0; i<=m-1; i++)for (j=0; j<=m-1; j++){ jj=i*m+j; e[jj]=r[jj];for (kk=0; kk<=n-1; kk++)e[jj]=e[jj]+h[i*n+kk]*a[kk*l+j];}js=rinv(e,m);if (js==0){ free(e); free(a); free(b); return(js);}for (i=0; i<=n-1; i++)for (j=0; j<=m-1; j++){ jj=i*m+j; g[jj]=0.0;for (kk=0; kk<=m-1; kk++)g[jj]=g[jj]+a[i*l+kk]*e[j*m+kk];}for (i=0; i<=n-1; i++){ jj=(ii-1)*n+i; x[jj]=0.0;for (j=0; j<=n-1; j++)x[jj]=x[jj]+f[i*n+j]*x[(ii-2)*n+j];}for (i=0; i<=m-1; i++){ jj=i*l; b[jj]=y[(ii-1)*m+i];for (j=0; j<=n-1; j++)b[jj]=b[jj]-h[i*n+j]*x[(ii-1)*n+j];}for (i=0; i<=n-1; i++){ jj=(ii-1)*n+i;for (j=0; j<=m-1; j++)x[jj]=x[jj]+g[i*m+j]*b[j*l];}if (ii<k){ for (i=0; i<=n-1; i++)for (j=0; j<=n-1; j++){ jj=i*l+j; a[jj]=0.0;for (kk=0; kk<=m-1; kk++)a[jj]=a[jj]-g[i*m+kk]*h[kk*n+j];if (i==j) a[jj]=1.0+a[jj];}for (i=0; i<=n-1; i++)for (j=0; j<=n-1; j++){ jj=i*l+j; b[jj]=0.0;for (kk=0; kk<=n-1; kk++)b[jj]=b[jj]+a[i*l+kk]*p[kk*n+j];}for (i=0; i<=n-1; i++)for (j=0; j<=n-1; j++){ jj=i*l+j; a[jj]=0.0;for (kk=0; kk<=n-1; kk++)a[jj]=a[jj]+b[i*l+kk]*f[j*n+kk];}for (i=0; i<=n-1; i++)for (j=0; j<=n-1; j++){ jj=i*n+j; p[jj]=q[jj];for (kk=0; kk<=n-1; kk++)p[jj]=p[jj]+f[i*n+kk]*a[j*l+kk];}}}free(e); free(a); free(b);return(js);}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
卡尔曼滤波简介及其算法实现代码卡尔曼滤波算法实现代码(C,C++分别实现)卡尔曼滤波器简介近来发现有些问题很多人都很感兴趣。
所以在这里希望能尽自己能力跟大家讨论一些力所能及的算法。
现在先讨论一下卡尔曼滤波器,如果时间和能力允许,我还希望能够写写其他的算法,例如遗传算法,傅立叶变换,数字滤波,神经网络,图像处理等等。
因为这里不能写复杂的数学公式,所以也只能形象的描述。
希望如果哪位是这方面的专家,欢迎讨论更正。
卡尔曼滤波器– Kalman Filter1.什么是卡尔曼滤波器(What is the Kalman Filter?)在学习卡尔曼滤波器之前,首先看看为什么叫“卡尔曼”。
跟其他著名的理论(例如傅立叶变换,泰勒级数等等)一样,卡尔曼也是一个人的名字,而跟他们不同的是,他是个现代人!卡尔曼全名Rudolf Emil Kalman,匈牙利数学家,1930年出生于匈牙利首都布达佩斯。
1953,1954年于麻省理工学院分别获得电机工程学士及硕士学位。
1957年于哥伦比亚大学获得博士学位。
我们现在要学习的卡尔曼滤波器,正是源于他的博士论文和1960年发表的论文《A New Approach to Linear Filtering and Prediction Problems》(线性滤波与预测问题的新方法)。
如果对这编论文有兴趣,可以到这里的地址下载:/~welch/media/pdf/Kalman1960.pdf。
简单来说,卡尔曼滤波器是一个“optimal recursive data processing algorithm(最优化自回归数据处理算法)”。
对于解决很大部分的问题,他是最优,效率最高甚至是最有用的。
他的广泛应用已经超过30年,包括机器人导航,控制,传感器数据融合甚至在军事方面的雷达系统以及导弹追踪等等。
近年来更被应用于计算机图像处理,例如头脸识别,图像分割,图像边缘检测等等。
2.卡尔曼滤波器的介绍(Introduction to the Kalman Filter)为了可以更加容易的理解卡尔曼滤波器,这里会应用形象的描述方法来讲解,而不是像大多数参考书那样罗列一大堆的数学公式和数学符号。
但是,他的5条公式是其核心内容。
结合现代的计算机,其实卡尔曼的程序相当的简单,只要你理解了他的那5条公式。
在介绍他的5条公式之前,先让我们来根据下面的例子一步一步的探索。
假设我们要研究的对象是一个房间的温度。
根据你的经验判断,这个房间的温度是恒定的,也就是下一分钟的温度等于现在这一分钟的温度(假设我们用一分钟来做时间单位)。
假设你对你的经验不是100%的相信,可能会有上下偏差几度。
我们把这些偏差看成是高斯白噪声(White Gaussian Noise),也就是这些偏差跟前后时间是没有关系的而且符合高斯分配(Gaussian Distribution)。
另外,我们在房间里放一个温度计,但是这个温度计也不准确的,测量值会比实际值偏差。
我们也把这些偏差看成是高斯白噪声。
好了,现在对于某一分钟我们有两个有关于该房间的温度值:你根据经验的预测值(系统的预测值)和温度计的值(测量值)。
下面我们要用这两个值结合他们各自的噪声来估算出房间的实际温度值。
假如我们要估算k时刻的是实际温度值。
首先你要根据k-1时刻的温度值,来预测k时刻的温度。
因为你相信温度是恒定的,所以你会得到k时刻的温度预测值是跟 k-1时刻一样的,假设是23度,同时该值的高斯噪声的偏差是5度(5是这样得到的:如果k-1时刻估算出的最优温度值的偏差是3,你对自己预测的不确定度是4度,他们平方相加再开方,就是5)。
然后,你从温度计那里得到了k时刻的温度值,假设是25度,同时该值的偏差是4度。
由于我们用于估算k时刻的实际温度有两个温度值,分别是23度和25度。
究竟实际温度是多少呢?相信自己还是相信温度计呢?究竟相信谁多一点,我们可以用他们的 covariance来判断。
因为Kg^2=5^2/(5^2+4^2),所以Kg=0.78,我们可以估算出k时刻的实际温度值是:23+0.78* (25-23)=24.56度。
可以看出,因为温度计的covariance比较小(比较相信温度计),所以估算出的最优温度值偏向温度计的值。
现在我们已经得到k时刻的最优温度值了,下一步就是要进入k+1时刻,进行新的最优估算。
到现在为止,好像还没看到什么自回归的东西出现。
对了,在进入 k+1时刻之前,我们还要算出k 时刻那个最优值(24.56度)的偏差。
算法如下:((1-Kg)*5^2)^0.5=2.35。
这里的5就是上面的k时刻你预测的那个23度温度值的偏差,得出的2.35就是进入k+1时刻以后k时刻估算出的最优温度值的偏差(对应于上面的3)。
就是这样,卡尔曼滤波器就不断的把covariance递归,从而估算出最优的温度值。
他运行的很快,而且它只保留了上一时刻的covariance。
上面的Kg,就是卡尔曼增益(Kalman Gain)。
他可以随不同的时刻而改变他自己的值,是不是很神奇!下面就要言归正传,讨论真正工程系统上的卡尔曼。
3.卡尔曼滤波器算法(The Kalman Filter Algorithm)在这一部分,我们就来描述源于Dr Kalman 的卡尔曼滤波器。
下面的描述,会涉及一些基本的概念知识,包括概率(Probability),随即变量(Random Variable),高斯或正态分配(Gaussian Distribution)还有State-space Model等等。
但对于卡尔曼滤波器的详细证明,这里不能一一描述。
首先,我们先要引入一个离散控制过程的系统。
该系统可用一个线性随机微分方程(Linear Stochastic Difference equation)来描述:X(k)=A X(k-1)+B U(k)+W(k)再加上系统的测量值:Z(k)=H X(k)+V(k)上两式子中,X(k)是k时刻的系统状态,U(k)是k时刻对系统的控制量。
A和B是系统参数,对于多模型系统,他们为矩阵。
Z(k)是k时刻的测量值,H 是测量系统的参数,对于多测量系统,H为矩阵。
W(k)和V(k)分别表示过程和测量的噪声。
他们被假设成高斯白噪声(White Gaussian Noise),他们的covariance 分别是Q,R(这里我们假设他们不随系统状态变化而变化)。
对于满足上面的条件(线性随机微分系统,过程和测量都是高斯白噪声),卡尔曼滤波器是最优的信息处理器。
下面我们来用他们结合他们的covariances 来估算系统的最优化输出(类似上一节那个温度的例子)。
首先我们要利用系统的过程模型,来预测下一状态的系统。
假设现在的系统状态是k,根据系统的模型,可以基于系统的上一状态而预测出现在状态:X(k|k-1)=A X(k-1|k-1)+B U(k) (1)式(1)中,X(k|k-1)是利用上一状态预测的结果,X(k-1|k-1)是上一状态最优的结果,U(k)为现在状态的控制量,如果没有控制量,它可以为0。
到现在为止,我们的系统结果已经更新了,可是,对应于X(k|k-1)的covariance还没更新。
我们用P表示covariance:P(k|k-1)=A P(k-1|k-1) A’+Q (2)式 (2)中,P(k|k-1)是X(k|k-1)对应的covariance,P(k-1|k-1)是X(k-1|k-1)对应的covariance,A’表示A的转置矩阵,Q是系统过程的covariance。
式子1,2就是卡尔曼滤波器5个公式当中的前两个,也就是对系统的预测。
现在我们有了现在状态的预测结果,然后我们再收集现在状态的测量值。
结合预测值和测量值,我们可以得到现在状态(k)的最优化估算值X(k|k):X(k|k)= X(k|k-1)+Kg(k) (Z(k)-H X(k|k-1)) (3)其中Kg为卡尔曼增益(Kalman Gain):Kg(k)= P(k|k-1) H’ / (H P(k|k-1) H’ + R) (4)到现在为止,我们已经得到了k状态下最优的估算值X(k|k)。
但是为了要另卡尔曼滤波器不断的运行下去直到系统过程结束,我们还要更新k状态下X(k|k)的covariance:P(k|k)=(I-Kg(k) H)P(k|k-1) (5)其中I 为1的矩阵,对于单模型单测量,I=1。
当系统进入k+1状态时,P(k|k)就是式子(2)的P(k-1|k-1)。
这样,算法就可以自回归的运算下去。
卡尔曼滤波器的原理基本描述了,式子1,2,3,4和5就是他的5 个基本公式。
根据这5个公式,可以很容易的实现计算机的程序。
下面,我会用程序举一个实际运行的例子。
4.简单例子(A Simple Example)这里我们结合第二第三节,举一个非常简单的例子来说明卡尔曼滤波器的工作过程。
所举的例子是进一步描述第二节的例子,而且还会配以程序模拟结果。
根据第二节的描述,把房间看成一个系统,然后对这个系统建模。
当然,我们见的模型不需要非常地精确。
我们所知道的这个房间的温度是跟前一时刻的温度相同的,所以A=1。
没有控制量,所以U(k)=0。
因此得出:X(k|k-1)=X(k-1|k-1) (6)式子(2)可以改成:P(k|k-1)=P(k-1|k-1) +Q (7)因为测量的值是温度计的,跟温度直接对应,所以H=1。
式子3,4,5可以改成以下:X(k|k)= X(k|k-1)+Kg(k) (Z(k)-X(k|k-1)) (8)Kg(k)= P(k|k-1) / (P(k|k-1) + R) (9)P(k|k)=(1-Kg(k))P(k|k-1) (10)现在我们模拟一组测量值作为输入。
假设房间的真实温度为25度,我模拟了200个测量值,这些测量值的平均值为25度,但是加入了标准偏差为几度的高斯白噪声(在图中为蓝线)。
为了令卡尔曼滤波器开始工作,我们需要告诉卡尔曼两个零时刻的初始值,是X(0|0)和P(0|0)。
他们的值不用太在意,随便给一个就可以了,因为随着卡尔曼的工作,X会逐渐的收敛。
但是对于P,一般不要取0,因为这样可能会令卡尔曼完全相信你给定的X(0|0)是系统最优的,从而使算法不能收敛。
我选了 X(0|0)=1度,P(0|0)=10。
该系统的真实温度为25度,图中用黑线表示。
图中红线是卡尔曼滤波器输出的最优化结果(该结果在算法中设置了Q=1e-6,R=1e-1)。
最佳线性滤波理论起源于40年代美国科学家Wiener和前苏联科学家Kолмогоров等人的研究工作,后人统称为维纳滤波理论。
从理论上说,维纳滤波的最大缺点是必须用到无限过去的数据,不适用于实时处理。