![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
1
kalmanfilter/kalmanfilter.cpp
- Committer:
- shaorui
- Date:
- 2020-02-07
- Revision:
- 0:c55310328157
File content as of revision 0:c55310328157:
#include"kalmanfilter.h" #include "math.h" /*========================= Mat3Init ====================================*/ Mat3 kalmanfilter::Mat3Init(Mat3 C, double dNum){ /*初始化3维方阵所有分量为指定值 参数:[in]C: 待初始化的3维方阵 [in]dNum: 指定值 返回:C */ /*需求: 类型: Mat3 */ /*创建时间: 20070530 最近更改时间:20070530 Copyright 2006-2010 SSTC,HLW Email: nostalgica@163.com */ int i,j; for (i=0;i<3;i++){ for(j=0;i<3;j++){ C[i][j]=dNum; } } return C; } /*========================= MatInit ====================================*/ Mat kalmanfilter:: MatInit(Mat C, int nM,int nN, double dNum){ /*初始化矩阵所有分量为指定值 参数:[in]C: 待初始化矩阵 [in]nM: 矩阵行数 [in]nN: 矩阵列数 [in]dNum: 指定值 返回:C */ /*需求: 类型: Mat 宏: MGet */ /*创建时间: 20070530 最近更改时间:20091103 Copyright 2006-2010 SSTC,HLW Email: nostalgica@163.com */ int i,j; for (i=0;i<nM;i++){ for(j=0;j<nN;j++){ MGet(C,i,j,nN)=dNum; } } return C; } /*========================= Mat3InitI ====================================*/ Mat3 kalmanfilter::Mat3InitI(Mat3 C){ /*初始化3维方阵为单位对角阵 参数:[in]C: 待初始化的3维方阵 返回:C */ /*需求: 类型: Mat3 */ /*创建时间: 20070530 最近更改时间:20070530 Copyright 2006-2010 SSTC,HLW Email: nostalgica@163.com */ int i,j; for (i=0;i<3;i++){ for(j=0;i<3;j++){ if (i==j){ C[i][j]=1.0; }else{ C[i][j]=0.0; } } } return C; } /*========================= MatInitI ====================================*/ Mat kalmanfilter::MatInitI(Mat C, int nOrder){ /*方阵初始化为单位对角阵 参数:[in]C: 待初始化的方阵 [in]nOrder: 方阵维数 返回:C */ /*需求: 类型: Mat 宏: MGet */ /*创建时间: 20070530 最近更改时间:20070530 Copyright 2006-2010 SSTC,HLW Email: nostalgica@163.com */ int i,j; for (i=0;i<nOrder;i++){ for(j=0;j<nOrder;j++){ if (i==j){ MGet(C,i,j,nOrder)=1.0; }else{ MGet(C,i,j,nOrder)=0.0; } } } return C; } /*========================= Diag ====================================*/ Mat kalmanfilter::Diag(cVec V, Mat Mout, int nOrder){ /* 通过向量初始化对角方阵 参数:[in]V: 向量V [out]Mout: 待初始化方阵 [in]nOrder: 向量维数 返回:Mout */ /*需求: 类型: Mat, cVec 宏: MGet */ /*创建时间: 20080509 最近更改时间:20080509 Copyright 2006-2010 SSTC,HLW Email: nostalgica@163.com */ int i,j; for (i=0;i<nOrder;i++){ for(j=0;j<nOrder;j++){ if (i==j){ MGet(Mout,i,j,nOrder)=V[i]; }else{ MGet(Mout,i,j,nOrder)=0.0; } } } return Mout; } /******************************************************************************************************************/ /*============================ Mat3Sum=================================*/ Mat3 kalmanfilter::Mat3Sum(cMat3 C1, cMat3 C2, Mat3 C){ /*3*3矩阵加法 参数:[in]C1:3*3 C1矩阵 [in]C2:3*3 C2矩阵 [out]C: C1+C2 返回:C */ /*需求: 类型: Mat3,cMat3 */ /* 创建时间: 20070528 最近更改时间:20070528 Copyright 2005-2010 SSTC */ int i,j; for (i=0;i<3;i++) { for(j=0;j<3;j++) C[i][j] = C1[i][j] + C2[i][j]; } return C; } /*============================ Mat3Sum3=================================*/ Mat3 kalmanfilter::Mat3Sum3(cMat3 C1, cMat3 C2, cMat3 C3, Mat3 C){ /*3*3矩阵加法(三个矩阵) 参数:[in]C1:3*3 C1矩阵 [in]C2:3*3 C2矩阵 [in]C3:3*3 C3矩阵 [out]C: C1+C2+C3 返回:C */ /*需求: 类型: Mat3,cMat3 */ /* 创建时间: 20080410 最近更改时间:20080410 Copyright 2005-2010 SSTC */ int i,j; for (i=0;i<3;i++) { for(j=0;j<3;j++) C[i][j] = C1[i][j] + C2[i][j]+ C3[i][j]; } return C; } /*============================ MatSum=================================*/ Mat kalmanfilter::MatSum(cMat C1, cMat C2, Mat C, int nM, int nN){ /*矩阵加法 参数:[in]C1: C1矩阵 [in]C2: C2矩阵 [out]C: C1+C2 [in]nM: 矩阵行数 [in]nN: 矩阵列数 返回:C */ /*需求: 类型: Mat,cMat 宏: MGet */ /* 创建时间: 20080402 最近更改时间:20080402 Copyright 2005-2010 SSTC */ int i,j; for (i=0;i<nM;i++){ for(j=0;j<nN;j++){ MGet(C,i,j,nN)=MGet(C1,i,j,nN)+MGet(C2,i,j,nN); } } return C; } /*============================ MatSum3=================================*/ Mat kalmanfilter::MatSum3(cMat C1, cMat C2, cMat C3, Mat C, int nM, int nN){ /*矩阵加法(三个矩阵) 参数:[in]C1: C1矩阵 [in]C2: C2矩阵 [in]C3: C3矩阵 [out]C: C1+C2+C3 [in]nM: 矩阵行数 [in]nN: 矩阵列数 返回:C */ /*需求: 类型: Mat,cMat 宏: MGet */ /* 创建时间: 20080402 最近更改时间:20080402 Copyright 2005-2010 SSTC */ int i,j; for (i=0;i<nM;i++){ for(j=0;j<nN;j++){ MGet(C,i,j,nN)=MGet(C1,i,j,nN)+MGet(C2,i,j,nN)+MGet(C3,i,j,nN); } } return C; } /*************************************************************************************************/ /*============================ Mat3Minus =================================*/ Mat3 kalmanfilter::Mat3Minus(cMat3 C1, cMat3 C2, Mat3 C){ /*3*3矩阵减法 参数:[in]C1:3*3 C1矩阵 [in]C2:3*3 C2矩阵 [out]C: C1-C2 返回:C */ /*需求: 类型: Mat3,cMat3 */ /* 创建时间: 20070528 最近更改时间:20070528 Copyright 2005-2010 SSTC */ int i,j; for (i=0;i<3;i++){ for(j=0;j<3;j++) C[i][j] = C1[i][j] - C2[i][j]; } return C; } /*============================ MatMinus =================================*/ Mat kalmanfilter::MatMinus(cMat C1, cMat C2, Mat C, int nM, int nN){ /*矩阵减法 参数:[in]C1: C1矩阵 [in]C2: C2矩阵 [out]C: C1-C2 [in]nM: 矩阵行数 [in]nN: 矩阵列数 返回:C */ /*需求: 类型: Mat,cMat */ /* 创建时间: 20080402 最近更改时间:20080402 Copyright 2005-2010 SSTC */ int i; for (i=0;i<nM*nN;i++){ C[i]=C1[i]-C2[i]; } return C; } /*********************************************************************************************************/ /*========================= Mat3Cpy ====================================*/ Mat3 kalmanfilter::Mat3Cpy(Mat3 dest,cMat3 source){ /*3*3矩阵拷贝 参数:[out]dest:3*3目标矩阵 [in]source:3*3源矩阵 返回:dest */ /*需求: 类型: Mat3,cMat3 */ /*创建时间: 20070527 最近更改时间:20070527 Copyright 2006-2010 SSTC,HLW Email: nostalgica@163.com */ dest[0][0]=source[0][0]; dest[0][1]=source[0][1]; dest[0][2]=source[0][2]; dest[1][0]=source[1][0]; dest[1][1]=source[1][1]; dest[1][2]=source[1][2]; dest[2][0]=source[2][0]; dest[2][1]=source[2][1]; dest[2][2]=source[2][2]; return dest; } /*========================= MatCpy ====================================*/ Mat kalmanfilter::MatCpy(Mat dest, cMat source, int nM, int nN){ /*矩阵拷贝 参数:[out]dest: 目标矩阵 [in]source: 源矩阵 [in]nM: 矩阵行数 [in]nN: 矩阵列数 返回:dest */ /*需求: 类型: Mat,cMat */ /*创建时间: 20080402 最近更改时间:20080402 Copyright 2006-2010 SSTC,HLW Email: nostalgica@163.com */ int i; for(i=0;i<nM*nN;i++){ dest[i]=source[i]; } return dest; } /***************************************************************************************************/ /*============================ Mat3Prod =================================*/ Mat3 kalmanfilter::Mat3Prod(cMat3 C1, cMat3 C2, Mat3 C){ /*3*3矩阵乘法 参数:[in]C1:3*3 C1矩阵 [in]C2:3*3 C2矩阵 [out]C: C1*C2 返回:C */ /*需求: 类型:Mat3,cMat3 */ /* 创建时间: 20070528 最近更改时间:20070528 Copyright 2005-2010 HLW */ int i,j,k; double Ctemp[3][3]; for (i=0;i<3;i++){ for(j=0;j<3;j++){ Ctemp[i][j] = 0.0; for (k=0;k<3;k++){ Ctemp[i][j] = Ctemp[i][j] + C1[i][k]*C2[k][j]; } } } for (i=0;i<3;i++){ for(j=0;j<3;j++){ C[i][j]=Ctemp[i][j]; } } return C; } /*============================ Mat3Prod3 =================================*/ Mat3 kalmanfilter::Mat3Prod3(cMat3 C1, cMat3 C2, cMat3 C3, Mat3 C){ /*3*3矩阵乘法(三个矩阵) 参数:[in]C1:3*3 C1矩阵 [in]C2:3*3 C2矩阵 [in]C3:3*3 C3矩阵 [out]C: C1*C2*C3 返回:C */ /*需求: 类型:Mat3,cMat3 */ /* 创建时间: 20080410 最近更改时间: 20080410 Copyright 2005-2010 SSTC */ int i,j,k; double Ctemp[3][3],Ctemp2[3][3]; for (i=0;i<3;i++){ for(j=0;j<3;j++){ Ctemp[i][j] = 0.0; for (k=0;k<3;k++){ Ctemp[i][j] = Ctemp[i][j] + C1[i][k]*C2[k][j]; } } } for (i=0;i<3;i++){ for(j=0;j<3;j++){ Ctemp2[i][j] = 0.0; for (k=0;k<3;k++){ Ctemp2[i][j] = Ctemp2[i][j] + Ctemp[i][k]*C3[k][j]; } } } for (i=0;i<3;i++){ for(j=0;j<3;j++){ C[i][j]=Ctemp2[i][j]; } } return C; } /*============================ MatProd =================================*/ Mat kalmanfilter::MatProd(cMat C1, cMat C2, Mat C, int nM, int nN, int nP){ /*矩阵乘法 参数:[in]C1: C1矩阵(nM*nN) [in]C2: C2矩阵(nN*nP) [out]C: C1*C2 [in]nM: C1行数 [in]nN: C1列数(C2行数) [in]nP: C2列数 返回:C */ /*需求: 类型: Mat,cMat 头文件: stdlib.h 宏: MGet */ /* 创建时间: 20080403 最近更改时间:20080403 Copyright 2005-2010 SSTC */ int i,j,k; Mat Ctemp=(Mat)malloc(sizeof(double)*nM*nP); for (i=0;i<nM;i++){ for(j=0;j<nP;j++){ MGet(Ctemp,i,j,nP) = 0.0; for (k=0;k<nN;k++){ MGet(Ctemp,i,j,nP) = MGet(Ctemp,i,j,nP) + MGet(C1,i,k,nN)*MGet(C2,k,j,nP); } } } for (i=0;i<nM;i++){ for(j=0;j<nP;j++){ MGet(C,i,j,nP)=MGet(Ctemp,i,j,nP); } } free(Ctemp); return C; } /*============================ MatProd3 =================================*/ Mat kalmanfilter::MatProd3(cMat C1, cMat C2, cMat C3, Mat C, int nM, int nN, int nP, int nQ){ /*矩阵乘法(三个矩阵) 参数:[in]C1: C1矩阵(nM*nN) [in]C2: C2矩阵(nN*nP) [in]C3: C3矩阵(nP*nQ) [out]C: C1*C2*C3 [in]nM: C1行数 [in]nN: C1列数(C2行数) [in]nP: C2列数(C3行数) [in]nQ: C3列数 返回:C */ /*需求: 类型: Mat,cMat 头文件: stdlib.h 宏: MGet */ /* 创建时间: 20080410 最近更改时间:20080410 Copyright 2005-2010 SSTC */ int i,j,k; Mat Ctemp=(Mat)malloc(sizeof(double)*nM*nP); Mat Ctemp2=(Mat)malloc(sizeof(double)*nM*nQ); for (i=0;i<nM;i++){ for(j=0;j<nP;j++){ MGet(Ctemp,i,j,nP) = 0.0; for (k=0;k<nN;k++){ MGet(Ctemp,i,j,nP) = MGet(Ctemp,i,j,nP) + MGet(C1,i,k,nN)*MGet(C2,k,j,nP); } } } for (i=0;i<nM;i++){ for(j=0;j<nQ;j++){ MGet(Ctemp2,i,j,nQ) = 0.0; for (k=0;k<nP;k++){ MGet(Ctemp2,i,j,nQ) = MGet(Ctemp2,i,j,nQ) + MGet(Ctemp,i,k,nP)*MGet(C3,k,j,nQ); } } } for (i=0;i<nM;i++){ for(j=0;j<nQ;j++){ MGet(C,i,j,nQ)=MGet(Ctemp2,i,j,nQ); } } free(Ctemp); free(Ctemp2); return C; } /***************************************************************************************************/ /*============================ Mat3Trans =================================*/ Mat3 kalmanfilter::Mat3Trans(cMat3 C,Mat3 CT){ /*3*3矩阵转置 参数:[in]C: 3*3 C矩阵 [out]CT: C的转置 返回:CT */ /*需求: 类型:Mat3,cMat3 */ /* 创建时间: 20070528 最近更改时间:20070528 Copyright 2005-2010 SSTC */ int i,j; double Ctemp[3][3]; for(i=0;i<3;i++){ for(j=0;j<3;j++){ Ctemp[i][j] = C[j][i]; } } for(i=0;i<3;i++){ for(j=0;j<3;j++){ CT[i][j] = Ctemp[i][j]; } } return CT; } /*============================ MatTrans =================================*/ Mat kalmanfilter::MatTrans(cMat C,Mat CT,int nM,int nN){ /*矩阵转置 参数:[in]C: C矩阵 [out]CT: C的转置 [in]nM: C矩阵行数 [in]nN: C矩阵列数 返回:CT */ /*需求: 类型:Mat,cMat 头文件:stdlib.h 宏:MGet */ /* 创建时间: 20080402 最近更改时间:20080402 Copyright 2005-2010 SSTC */ int i,j; Mat Ctemp=(Mat)malloc(sizeof(double)*nM*nN); for(i=0;i<nN;i++){ for(j=0;j<nM;j++){ MGet(Ctemp,i,j,nM)=MGet(C,j,i,nN); } } for(i=0;i<nM*nN;i++){ CT[i] = Ctemp[i]; } free(Ctemp); return CT; } /**************************************************************************************************/ /*============================ MatInv =================================*/ Mat kalmanfilter::MatInv(cMat C,Mat IC,int n){ /*方阵的逆 参数:[in]C:方阵C [out]IC:方阵C的逆 [in]n:方阵C的维数 返回:IC,若不可逆或失败则返回NULL */ /*需求: 头文件:math.h,stdlib.h 类型:Mat,cMat 宏:NULL */ /* 创建时间: 20070615 最近更改时间: 20070615 Copyright 2005-2010 SSTC */ int i,j,k,l; double *cpyC; cpyC=(double*)malloc(n*n*sizeof(double)); if (cpyC==NULL){ return NULL; } for (i=0;i<n*n;i++){ cpyC[i]=C[i]; } /* 单位阵*/ for (i=0; i<n; i++){ for (j=0; j<n; j++){ *(IC+i*n+j) = 0.0; } *(IC+i*n+i) = 1.0; } /* 化上三角阵*/ for (j=0; j<n; j++) { if(fabs(*(cpyC+j*n+j))>1.0e-25){/* C[j][j]不等于0*/ /* IC阵的第j行除以C[j][j]*/ for(k=0; k<n; k++){ *(IC+j*n+k) /= *(cpyC+j*n+j); } /* C阵的第j行除以C[j][j]*/ for(k=n-1; k>=j; k--){ *(cpyC+j*n+k) /= *(cpyC+j*n+j); } for(i=j+1; i<n; i++){ /* IC阵的第i行 - C[i][j]*IC阵的第j行*/ for(k=0; k<n; k++){ *(IC+i*n+k) -= *(cpyC+i*n+j) * *(IC+j*n+k); } /* C阵的第i行 - C[i][j]*C阵的第j行*/ for (k=n-1; k>=j; k--){ *(cpyC+i*n+k) -= *(cpyC+i*n+j) * *(cpyC+j*n+k); } } }else if (j<n-1){ for(l=j+1; l<n; l++){ /* 若C阵第j行后的C[l][j]不等于0,第j行加上第l行*/ if (fabs(*(cpyC+l*n+j)) > 1.0e-25) { for (k=0; k<n; k++){ *(IC+j*n+k) += *(IC+l*n+k); } for (k=n-1; k>=j; k--){ *(cpyC+j*n+k) += *(cpyC+l*n+k); } /* IC阵的第j行除以C[j][j]*/ for (k=0; k<n; k++){ *(IC+j*n+k) /= *(cpyC+j*n+j); } /* C阵的第j行除以C[j][j]*/ for (k=n-1; k>=j; k--){ *(cpyC+j*n+k) /= *(cpyC+j*n+j); } /* 第i行 - C[i][j]*第j行*/ for (i=j+1; i<n; i++){ for (k=0; k<n; k++){ *(IC+i*n+k) -= *(cpyC+i*n+j) * *(IC+j*n+k); } for (k=n-1; k>=j; k--){ *(cpyC+i*n+k) -= *(cpyC+i*n+j) * *(cpyC+j*n+k); } } break; } } if (l == n){ /* C[l][j] 全等于0*/ free(cpyC); return NULL; /* 矩阵的行列式为零,不可求逆*/ } }else{ /* C[n][n]等于0*/ free(cpyC); return NULL; /* 矩阵的行列式为零,不可求逆*/ } } /* 化成单位阵*/ for(j=n-1; j>=1; j--){ for(i=j-1; i>=0; i--){ for(k=0; k<n; k++){ *(IC+i*n+k) -= *(cpyC+i*n+j) * *(IC+j*n+k); } *(cpyC+i*n+j) = 0; } } free(cpyC); return IC; } /*============================ Mat3Inv =================================*/ Mat3 kalmanfilter::Mat3Inv(cMat3 CM,Mat3 ICM){ /*3*3矩阵的逆 参数:[in]CM:3*3 CM矩阵 [out]ICM:3*3 ICM矩阵 返回:ICM,若不可逆则返回NULL */ /*需求: 类型:Mat3,cMat3 宏:NULL, EPS 头文件: math.h */ /* 创建时间: 20070528 最近更改时间:20070528 Copyright 2005-2010 SSTC */ double det; double Ctemp[3][3]; int i,j; det=CM[0][0]*CM[1][1]*CM[2][2]+CM[0][1]*CM[1][2]*CM[2][0]+CM[1][0]*CM[2][1]*CM[0][2]-CM[0][2]*CM[1][1]*CM[2][0]-CM[0][1]*CM[1][0]*CM[2][2]-CM[2][1]*CM[1][2]*CM[0][0]; if (fabs(det)<1.0e-16){ return NULL; } Ctemp[0][0] = (CM[1][1]*CM[2][2] - CM[2][1]*CM[1][2])/det; Ctemp[0][1] = -(CM[0][1]*CM[2][2] - CM[2][1]*CM[0][2])/det; Ctemp[0][2] = (CM[0][1]*CM[1][2] - CM[1][1]*CM[0][2])/det; Ctemp[1][0] = -(CM[1][0]*CM[2][2] - CM[2][0]*CM[1][2])/det; Ctemp[1][1] = (CM[0][0]*CM[2][2] - CM[2][0]*CM[0][2])/det; Ctemp[1][2] = -(CM[0][0]*CM[1][2] - CM[1][0]*CM[0][2])/det; Ctemp[2][0] = (CM[1][0]*CM[2][1] - CM[2][0]*CM[1][1])/det; Ctemp[2][1] = -(CM[0][0]*CM[2][1] - CM[2][0]*CM[0][1])/det; Ctemp[2][2] = (CM[0][0]*CM[1][1] - CM[0][1]*CM[1][0])/det; for (i=0;i<3;i++){ for(j=0;j<3;j++){ ICM[i][j]=Ctemp[i][j]; } } return ICM; } /*============================ MatInvDiag =================================*/ Mat kalmanfilter::MatInvDiag(cMat C,Mat IC,int n){ /*方阵的对角逆 参数:[in]C:方阵C [out]IC:方阵C的对角逆 [in]n:方阵C的维数 返回:IC,对角元素取倒数,其他元素置0,对角元素若为0则仍保持0 */ /*需求: 头文件:math.h,stdlib.h 类型:Mat,cMat 宏:MGet */ /* 创建时间: 20091104 最近更改时间: 20091104 Copyright 2005-2010 SSTC */ int i,j; for (i=0;i<n;i++){ for (j=0;j<n;j++){ if(i!=j){ MGet(IC,i,j,n)=0; }else{ if (MGet(C,i,j,n)!=0){ MGet(IC,i,j,n)=1.0/MGet(C,i,j,n); }else{ MGet(IC,i,j,n)=0; } } } } return IC; } /*****************************************************************************************************************************/ /*============================ MV3Prod =================================*/ Vec3 kalmanfilter::MV3Prod(cMat3 C, cVec3 V, Vec3 Vout){ /*3*3矩阵与3维向量乘法 参数:[in]C:3*3 C矩阵 [in]V:3维向量V [out]Vout: C*V(V视为列向量) 返回:Vout */ /*需求: 类型: Mat3,Vec3,cMat3,cVec3 */ /* 创建时间: 20070528 最近更改时间:20070528 Copyright 2005-2010 SSTC */ double Vtemp[3]; int i; for (i=0;i<3;i++){ Vtemp[i] = C[i][0]*V[0] + C[i][1]*V[1] + C[i][2]*V[2]; } Vout[0]=Vtemp[0]; Vout[1]=Vtemp[1]; Vout[2]=Vtemp[2]; return Vout; } /*============================ VM3Prod =================================*/ Vec3 kalmanfilter::VM3Prod(cVec3 V, cMat3 C, Vec3 Vout){ /*3维向量与3*3矩阵乘法 参数:[in]V:3维向量V [in]C:3*3 C矩阵 [out]Vout: V*C(V视为行向量) 返回:Vout */ /*需求: 类型: Mat3,Vec3,cMat3,cVec3 */ /* 创建时间: 20080402 最近更改时间:20080402 Copyright 2005-2010 SSTC */ double Vtemp[3]; int i; for (i=0;i<3;i++){ Vtemp[i] = C[0][i]*V[0] + C[1][i]*V[1] + C[2][i]*V[2]; } Vout[0]=Vtemp[0]; Vout[1]=Vtemp[1]; Vout[2]=Vtemp[2]; return Vout; } /*============================ MVProd =================================*/ Vec kalmanfilter::MVProd(cMat C, cVec V, Vec Vout, int nM, int nN){ /*矩阵与向量乘法 参数:[in]C: C矩阵 [in]V: 向量V [out]Vout: C*V(V视为列向量) [in]nM: C行数 [in]nN: C列数,即V的维数 返回:Vout */ /*需求: 类型: Mat,Vec,cMat,cVec 宏: MGet 头文件: stdlib.h */ /* 创建时间: 20080402 最近更改时间:20080402 Copyright 2005-2010 SSTC */ Vec Vtemp=(Vec)malloc(sizeof(double)*nM); int i,j; for (i=0;i<nM;i++){ Vtemp[i]=0.0; for(j=0;j<nN;j++){ Vtemp[i] = Vtemp[i]+MGet(C,i,j,nN)*V[j]; } } for (i=0;i<nM;i++){ Vout[i]=Vtemp[i]; } free(Vtemp); return Vout; } /*============================ VMProd =================================*/ Vec kalmanfilter::VMProd(cVec V, cMat C, Vec Vout, int nM, int nN){ /*向量与矩阵乘法 参数:[in]V: 向量V [in]C: 矩阵C [out]Vout: V*C(V视为行向量) [in]nM: C行数,即V的维数 [in]nN: C列数 返回:Vout */ /*需求: 类型: Mat,Vec,cMat,cVec 宏: MGet 头文件: stdlib.h */ /* 创建时间: 20080402 最近更改时间:20080402 Copyright 2005-2010 SSTC */ Vec Vtemp=(Vec)malloc(sizeof(double)*nN); int i,j; for (i=0;i<nN;i++){ Vtemp[i]=0.0; for(j=0;j<nM;j++){ Vtemp[i] = Vtemp[i]+MGet(C,j,i,nN)*V[j]; } } for (i=0;i<nN;i++){ Vout[i]=Vtemp[i]; } free(Vtemp); return Vout; } /**************************************************************************************************************/ /*========================= VecCpy =================================*/ Vec kalmanfilter::VecCpy(Vec dest, cVec source, int nOrder){ /*向量拷贝 参数:[out]dest: 目标向量 [in]source: 源向量 [in]nOrder: 向量维数 返回:dest */ /*需求: 类型: Vec,cVec */ /*创建时间: 20070530 最近更改时间:20070530 Copyright 2006-2010 SSTC,HLW Email: nostalgica@163.com */ int i; for (i=0;i<nOrder;i++){ dest[i]=source[i]; } return dest; } /*========================= nVecCpy =================================*/ nVec kalmanfilter::nVecCpy(nVec dest, cnVec source, int nOrder){ /*整型向量拷贝 参数:[out]dest: 目标向量 [in]source: 源向量 [in]nOrder: 向量维数 返回:dest */ /*需求: 类型: nVec,cnVec */ /*创建时间: 20080512 最近更改时间:20080512 Copyright 2006-2010 SSTC,HLW Email: nostalgica@163.com */ int i; for (i=0;i<nOrder;i++){ dest[i]=source[i]; } return dest; } /*********************************************************************************************************/ /*========================= VecSum ====================================*/ Vec kalmanfilter::VecSum(cVec V1, cVec V2, int nOrder, Vec Vout){ /*向量加法 参数:[in]V1: 向量1 [in]V2: 向量2 [in]nOrder: 向量1与向量2的维数 [out]Vout: 向量1与向量2的和 返回:Vout */ /*需求: 类型: Vec,cVec */ /*创建时间: 20070530 最近更改时间:20070530 Copyright 2006-2010 SSTC,HLW Email: nostalgica@163.com */ int i; for (i=0;i<nOrder;i++){ Vout[i]=V1[i]+V2[i]; } return Vout; } /*========================= nVecSum ====================================*/ nVec kalmanfilter::nVecSum(cnVec V1, cnVec V2, int nOrder, nVec Vout){ /*整型向量加法 参数:[in]V1: 整型向量1 [in]V2: 整型向量2 [in]nOrder: 向量1与向量2的维数 [out]Vout: 向量1与向量2的和 返回:Vout */ /*需求: 类型: nVec,cnVec */ /*创建时间: 20080512 最近更改时间:20080512 Copyright 2006-2010 SSTC,HLW Email: nostalgica@163.com */ int i; for (i=0;i<nOrder;i++){ Vout[i]=V1[i]+V2[i]; } return Vout; } /*******************************************************************************************************************/ /*========================= VecMinus =================================*/ Vec kalmanfilter::VecMinus(cVec V1, cVec V2, int nOrder, Vec Vout){ /*向量减法 参数:[in]V1: 向量1 [in]V2: 向量2 [in]nOrder: 向量1与向量2的维数 [out]Vout: 向量1与向量2的差 返回:Vout */ /*需求: 类型: Vec,cVec */ /*创建时间: 20070530 最近更改时间:20070530 Copyright 2006-2010 SSTC,HLW Email: nostalgica@163.com */ int i; for (i=0;i<nOrder;i++){ Vout[i]=V1[i]-V2[i]; } return Vout; } /*========================= nVecMinus =================================*/ nVec kalmanfilter::nVecMinus(cnVec V1, cnVec V2, int nOrder, nVec Vout){ /*整型向量减法 参数:[in]V1: 整型向量1 [in]V2: 整型向量2 [in]nOrder: 向量1与向量2的维数 [out]Vout: 向量1与向量2的差 返回:Vout */ /*需求: 类型: nVec,cnVec */ /*创建时间: 20080512 最近更改时间:20080512 Copyright 2006-2010 SSTC,HLW Email: nostalgica@163.com */ int i; for (i=0;i<nOrder;i++){ Vout[i]=V1[i]-V2[i]; } return Vout; } /*******************************************************************************************************************/ /*========================= Kalman1 ====================================*/ Vec kalmanfilter::Kalman1(cMat Phik_, cMat Gamak_1, cMat Hk, cMat Qk_1, cMat Rk, cMat Pk_1, cVec Xk_1, cVec Zk, cMat Bk_1, cVec Uk_1, int n, int m, int q, int p, Vec Xk, Mat Pk, Mat Kk, Mat Pk_, Vec Xk_){ /*离散卡尔曼滤波的一步递推,系统方程:X(k+1)=Φ(k+1,k)X(k)+B(k)U(k)+Γ(k)W(k),Z(k+1)=H(k+1)X(k+1)+V(k+1) 参数:[in]Phik_: Φ(k+1,k);n*n,n为阶数 [in]Gamak_1: Γ(k);n*q,q为驱动噪声W(k)维数 [in]Hk: H(k+1);m*n,m为观测维数 [in]Qk_1: Q(k);q*q,驱动噪声W(k)协方差阵 [in]Rk: R(k+1);m*m,观测噪声V(k+1)协方差阵 [in]Pk_1: P(k,k);n*n [in]Xk_1: X(k,k);n维向量 [in]Zk: Z(k+1);m维向量 [in]Bk_1: B(k);n*p,p为输入维数 [in]Uk_1: U(k);p维向量 [in]n: 系统阶数 [in]m: 观测维数 [in]p: 输入维数 [in]q: 驱动噪声维数 [out]Xk: X(k+1,k+1);n维向量,若不需输出设为NULL [out]Pk: P(k+1,k+1);n*n,若不需输出设为NULL [out]Kk: K(k+1);n*m,若不需输出设为NULL [out]Pk_: P(k+1,k);n*n,若不需输出设为NULL [out]Xk_: X(k+1,k);n维向量,若不需输出设为NULL 返回:Xk,若不成功,返回NULL */ /*需求: 函数: MatTrans, MatProd, MatSum, MatInv, MatInitI, MatMinus, MVProd, VecSum, VecMinus, VecCpy, MatCpy 头文件: stdlib.h 宏: NULL */ /* 创建时间: 20080402 最近更改时间:20080403 Copyright 2005-2010 SSTC,HLW Email: nostalgica@163.com */ int nmax=max(max(max(n,m),p),q); Mat tCn=(Mat)malloc(sizeof(double)*nmax*nmax); Mat tCn2=(Mat)malloc(sizeof(double)*nmax*nmax); Mat tCn3=(Mat)malloc(sizeof(double)*nmax*nmax); Mat tCn4=(Mat)malloc(sizeof(double)*nmax*nmax); Mat tCn5=(Mat)malloc(sizeof(double)*nmax*nmax); Vec tV=(Vec)malloc(sizeof(double)*nmax); Vec tV2=(Vec)malloc(sizeof(double)*nmax); /*Pk_=Phik_*Pk_1*Phik_'+Gamak_1*Qk_1*Gamak_1'; Kk=Pk_*Hk'*(Hk*Pk_*Hk'+Rk)^(-1); I=eye(order); Pk=(I-Kk*Hk)*Pk_*(I-Kk*Hk)'+Kk*Rk*Kk'; Xk_=Phik_*Xk_1+Bk_1*Uk_1; Xk=Xk_+Kk*(Zk-Hk*Xk_); */ MatTrans(Phik_,tCn,n,n); MatProd(Pk_1,tCn,tCn2,n,n,n); MatProd(Phik_,tCn2,tCn,n,n,n); MatTrans(Gamak_1,tCn2,n,q); MatProd(Qk_1,tCn2,tCn3,q,q,n); MatProd(Gamak_1,tCn3,tCn2,n,q,n); MatSum(tCn,tCn2,tCn,n,n);/*tCn:Pk_*/ MatTrans(Hk,tCn2,m,n); MatProd(Hk,MatProd(tCn,tCn2,tCn3,n,n,m),tCn4,m,n,m); MatSum(tCn4,Rk,tCn3,m,m); if (MatInv(tCn3,tCn3,m)==NULL){ return NULL; } MatProd(tCn,MatProd(tCn2,tCn3,tCn4,n,m,m),tCn2,n,n,m);/*tCn2:Kk*/ MatInitI(tCn5,n); MatMinus(tCn5,MatProd(tCn2,Hk,tCn3,n,m,n),tCn3,n,n); MatTrans(tCn3,tCn4,n,n); MatProd(tCn3,MatProd(tCn,tCn4,tCn4,n,n,n),tCn3,n,n,n); MatProd(tCn2,MatProd(Rk,MatTrans(tCn2,tCn4,n,m),tCn4,m,m,n),tCn4,n,m,n); MatSum(tCn3,tCn4,tCn3,n,n);/*tCn3:Pk*/ MVProd(Phik_,Xk_1,tV,n,n); MVProd(Bk_1,Uk_1,tV2,n,p); VecSum(tV,tV2,n,tV);/*tV:Xk_*/ VecMinus(Zk,MVProd(Hk,tV,tV2,m,n),m,tV2); VecSum(tV,MVProd(tCn2,tV2,tV2,n,m),n,tV2);/*tV2:Xk*/ if (Xk!=NULL){ VecCpy(Xk,tV2,n); } if (Pk!=NULL){ MatCpy(Pk,tCn3,n,n); } if (Kk!=NULL){ MatCpy(Kk,tCn2,n,m); } if (Pk_!=NULL){ MatCpy(Pk_,tCn,n,n); } if (Xk_!=NULL){ VecCpy(Xk_,tV,n); } free(tCn); free(tCn2); free(tCn3); free(tCn4); free(tCn5); free(tV); free(tV2); return Xk; }