凡科网站怎么修改昨天做的网站/整站优化快速排名
原始 Markdown文档、Visio流程图、XMind思维导图见:https://github.com/LiZhengXiao99/Navigation-Learning
PSINS 中的 Kalman 滤波代码都在百行以内,没调用什么函数,而且通用性很强,拿去让 AI 解释,效果挺好。
文章目录
- 一、RLS
- RLSUD:UD分解RLS
- UDUT
- 二、kalman滤波
- KFUD:UD分解Kalman滤波
- kfc2d:连续时间Kalman滤波离散化
- 三、ekf:扩展卡尔曼滤波
- 四、UKF:无迹卡尔曼滤波
- ukfUT
- utpoint
- 五、ssukf
- SSUT
- 六、CKF:容积卡尔曼滤波
- ckfCT
- 七、PF:粒子滤波
- 八、akfupdate:自适应滤波
- shamn :Sage-Husa自适应滤波
- 九、抗差等价权函数
- igg1
- igg3
- 十、数据融合
- POSFusion
- POSSmooth
- POSProcessing
- POSProcessing_ifk_test
- 十一:模拟
- htwn:产生高斯白噪声
- vfbfx:模拟垂直下落物体的状态方程
- vfbhx:模拟垂直下落的物体的测量方程
- vfbhx:模拟垂直下落的物体的测量方程
一、RLS
RLS(递归最小二乘估计)是一种常用的自适应滤波算法,用于估计线性系统的参数1。
RLS估计的基本思想是通过对输入信号进行迭代最小化误差平方和,来逐步调整估计器的增益系数,从而不断优化估计器的性能。具体来说,RLS估计的步骤包括1:
- 初始化估计器的增益系数和误差方差。
- 对于每个输入信号采样,计算输出信号的预测值和实际值之间的误差。
- 根据误差和当前增益系数,计算出新的误差方差和增益系数。
- 重复执行步骤2和3,进行迭代优化,直到满足收敛条件为止。
function kf = RLS(kf, zk)
% Recursive Least Square filter.
%
% Prototype: kf = RLS(kf, zk)
% Inputs: kf - filter structure array
% zk - measurement vector
% Output: kf - filter structure array after filtering
%
% See also kfupdate, RLSPot, RLSUD.% Copyright(c) 2009-2014, by Gongmin Yan, All rights reserved.
% Northwestern Polytechnical University, Xi An, P.R.China
% 16/09/2013if ~isfield(kf, 'Rk') kf.Rk = eye(size(kf.Hk,1));endkf.Pxzk = kf.Pxk*kf.Hk'; kf.Pzk = kf.Hk*kf.Pxzk + kf.Rk; kf.Kk = kf.Pxzk*kf.Pzk^-1;kf.xk = kf.xk + kf.Kk*(zk-kf.Hk*kf.xk);kf.Pxk = kf.Pxk - kf.Kk*kf.Pxzk';kf.Pxk = (kf.Pxk+kf.Pxk')*0.5;
这是一个递归最小二乘(Recursive Least Square,RLS)滤波器的函数。它用于更新滤波器结构体数组 kf,并根据测量向量 zk 进行滤波操作。
函数的输入参数有 kf 和 zk,其中 kf 是滤波器的结构体数组,zk 是测量向量。函数的输出参数也是 kf,表示经过滤波操作后的滤波器结构体数组。
函数首先判断 kf 结构体数组中是否存在 Rk 字段,如果不存在,则初始化 Rk 为单位矩阵。然后计算 Pxzk = Pxk * Hk’,Pzk = Hk * Pxzk + Rk。接着计算增益矩阵 Kk = Pxzk * Pzk^-1。然后更新状态向量 xk = xk + Kk * (zk - Hk * xk)。再更新 Pxk = Pxk - Kk * Pxzk’。最后对 Pxk 进行对称化处理,使其成为对称矩阵。
这段代码的作用是实现递归最小二乘滤波器的更新过程,用于估计系统状态。
RLSUD:UD分解RLS
function [U, D, K, X] = RLSUD(U, D, H, R, Z, X)
% Recursive Least Square filter using UD decomposition.
%
% Prototype: [U, D, K, X] = RLSUD(U, D, H, R, Z, X)
% Inputs: U,D - factors of UD decomposition
% H,R - 1-row measurement matrix / measurement var
% X,Z - state / measurement
% Outputs: U,D,X - as input after update
% K - gain
%
% See also KFUD, RLS, kfupdate.% Copyright(c) 2009-2023, by Gongmin Yan, All rights reserved.
% Northwestern Polytechnical University, Xi An, P.R.China
% 30/01/2023if isstruct(U) % kf = RLSUD(kf, z);[U.Uk, U.Dk, ~, U.xk] = RLSUD(U.Uk, U.Dk, U.Hk, U.Rk, D, U.xk);return;endif nargin<4, R=1; endn = length(D);f = (H*U)'; g = D.*f; afa = f'*g+R;for j=n:-1:1afa0 = afa - f(j)*g(j); lambda = -f(j)/afa0;D(j) = afa0/afa*D(j); afa = afa0;for i=(j-1):-1:1s = (i+1):(j-1);U(i,j) = U(i,j) + lambda*(g(i)+U(i,s)*g(s));endendif nargout>2K = U*(D.*(H*U)')/R;if nargout>3, X = X + K*(Z-H*X); endend
该代码是一个递归最小二乘滤波器的实现,使用了UD分解技术。以下是其功能的解释:
- 输入参数:
U
:UD分解中的左奇异矩阵。D
:UD分解中的右奇异矩阵。H
:1行测量矩阵。R
:测量噪声的方差。Z
:测量值。X
:状态值。
- 输出参数:
U
:更新后的左奇异矩阵。D
:更新后的右奇异矩阵。X
:更新后的状态值(仅在输出参数中存在)。K
:增益(仅在输出参数中存在)。
- 功能解释:
- 首先,代码检查输入的参数是否为结构体。如果是结构体,则表示调用函数的方式为
kf = RLSUD(kf, z);
,即用当前的状态值kf.xk
和测量值z
更新结构体变量kf
。在这种情况下,函数直接返回更新后的结构体变量kf
,不进行其他计算。 - 如果输入参数不是结构体,则继续执行下面的代码。首先,根据输入的参数计算中间变量
f
、g
和afa
。其中,f = (H*U)'
表示将H
与U
进行矩阵乘积的转置,g = D.*f
表示将D
与f
进行逐元素相乘,afa = f'*g+R
表示将f'
与g
进行逐元素相乘,并将结果加上R
。 - 接下来,通过循环逐个处理矩阵的列,从最后一列开始逆序迭代。在每一列处理过程中,首先计算新的增益系数
lambda
,根据递推公式计算新的对角线元素D(j)
,并更新上三角矩阵U
的相应元素。具体的计算过程如下:- 首先,计算临时变量
afa0 = afa - f(j)*g(j)
,表示将afa
减去与当前列的乘积项。 - 然后,计算增益系数
lambda = -f(j)/afa0
,其中负号表示使用最小二乘法。 - 接下来,根据递推公式计算新的对角线元素
D(j) = afa0/afa*D(j)
。 - 最后,使用增益系数
lambda
和中间变量g(i)
、U(i,s)
更新上三角矩阵U
的相应元素。
- 首先,计算临时变量
- 在完成所有列的处理后,如果输出参数要求计算增益
K
,则根据公式K = U*(D.(H*U)')/R
计算增益,其中.
表示矩阵乘积的转置。 - 如果输出参数要求更新状态值
X
,则根据公式X = X + K*(Z-H*X)
更新状态值。其中,Z-H*X
表示预测误差。
- 首先,代码检查输入的参数是否为结构体。如果是结构体,则表示调用函数的方式为
- 总结:该代码实现了一个递归最小二乘滤波器,利用UD分解技术对矩阵进行更新和计算增益。它通过对矩阵逐列处理的方式,逐步更新滤波器的状态和增益系数,以实现滤波器的滤波功能。
UDUT
function [U, D] = UDUT(P)
% UDUT decomposition, so that P = U*diag(D)*U'.
%
% Prototype: [U, D] = UDUT(P)
% Input: P - nonnegative define symmetic matrix
% Outputs: U - unit upper-triangular matrix
% D - vector representation of diagonal matrix
%
% See also chol1, qrmgs.% Copyright(c) 2009-2016, by Gongmin Yan, All rights reserved.
% Northwestern Polytechnical University, Xi An, P.R.China
% 12/11/2016n = length(P);U = eye(n); D = zeros(n,1); trPn = trace(P)/n*1e-40;for j=n:-1:1k = (j+1):n;D(j) = P(j,j) - (U(j,k).^2)*D(k);if D(j)<=trPn, continue; endfor i=(j-1):-1:1U(i,j) = (P(i,j)-(U(i,k).*U(j,k))*D(k)) / D(j);endend
该代码实现了UDUT分解(Upper-Triangular Decomposition with Diagonal Similarity Transform),将一个非负定对称矩阵P分解为U * diag(D) * U’的形式。 2. 从最后一行开始,依次向上处理每一行。 3. 首先计算当前行j的对角线元素D(j),通过用当前行的上三角元素U(j,k)和D(k)的平方进行插值,减去对角线元素P(j,j)。 4. 如果D(j)小于等于trPn,说明该元素非常小,对分解结果影响不大,因此跳过对该行的处理。 5. 如果D(j)大于trPn,则需要计算当前行j和之前行i的元素U(i,j),通过用当前行的元素P(i,j)和之前的上三角元素U(i,k)和U(j,k)以及D(k)进行插值,除以D(j)。 6. 循环处理完所有行后,输出U和D即为UDUT分解的结果。
这段代码的目的是将一个非负定对称矩阵进行UDUT分解,以便进行后续的计算和分析。UDUT分解可以用于求解线性方程组、计算矩阵的行列式、计算矩阵的特征值和特征向量等应用中。
二、kalman滤波
卡尔曼滤波(Kalman filter)是一种高效率的递归滤波器(自回归滤波器),它能够从一系列的不完全及包含噪声的测量中,估计动态系统的状态1。
卡尔曼滤波的主要思想是利用状态转移矩阵和观测矩阵,结合当前状态和上一时刻的状态,来估计当前的最优状态1。具体来说,卡尔曼滤波的步骤包括1:
- 初始化滤波器的状态向量和协方差矩阵。
- 对于每个时间步长,执行以下步骤:
- 利用状态转移矩阵和当前状态向量,计算出下一时刻的状态向量和协方差矩阵。
- 结合观测矩阵和当前观测向量,计算出当前时刻的状态估计值和协方差矩阵。
- 根据新的状态估计值和协方差矩阵,更新滤波器的状态向量和协方差矩阵。
- 重复执行步骤2,进行迭代优化,直到满足收敛条件为止。
与传统的滤波器相比,卡尔曼滤波具有更好的数值稳定性和计算效率,能够更准确地估计状态变量的值。
function [Xk, Pxk, Xkk_1, Pxkk_1] = kalman(Phikk_1, Gammak, Qk, Xk_1, Pxk_1, Hk, Rk, Zk, s)
% A simple Kalman filter By Yan Gongminif nargin<9, s=1; endXkk_1 = Phikk_1*Xk_1;Pxkk_1 = Phikk_1*s*Pxk_1*Phikk_1' + Gammak*Qk*Gammak';Pxykk_1 = Pxkk_1*Hk';Pykk_1 = Hk*Pxykk_1 + Rk;Kk = Pxykk_1*Pykk_1^-1;Xk = Xkk_1 + Kk*(Zk-Hk*Xkk_1);Pxk = Pxkk_1 - Kk*Pykk_1*Kk';Pxk = (Pxk+Pxk')/2;
这段代码是一个简单的卡尔曼滤波器的实现。卡尔曼滤波器是一种用于估计动态系统状态的方法,通过结合先前的估计和最新的观测数据来更新当前状态的估计。
以下是代码的功能解释:
- 输入参数:
Phikk_1
:状态转移矩阵,描述系统状态的转移方式。Gammak
:过程噪声协方差矩阵,描述系统过程中引入的噪声。Qk
:过程噪声协方差矩阵,描述系统过程中引入的噪声。Xk_1
:先前的状态估计。Zk
:观测数据。s
:可选参数,用于调整卡尔曼增益的平滑因子,默认为1。
- 初始化:
Xkk_1
:根据状态转移矩阵和先前的状态估计计算得到当前状态的预测值。Pxkk_1
:根据状态转移矩阵、过程噪声协方差矩阵和先前的状态估计误差协方差矩阵计算得到当前状态预测值的误差协方差矩阵。
- 预测:
Pxykk_1
:将当前状态预测值的误差协方假矩阵转换为预测的状态和观测之间的协方差矩阵。Pykk_1
:根据观测矩阵、预测的状态和观测之间的协方差矩阵以及观测噪声协方差矩阵计算得到预测的观测噪声协方差矩阵。
- 更新:
Kk
:通过预测的状态和观测之间的协方差矩阵以及预测的观测噪声协方差矩阵的逆计算得到卡尔曼增益。Xk
:根据当前状态预测值和观测数据的卡尔曼增益,对当前状态进行更新。Pxk
:根据当前状态更新后的误差协方差矩阵,通过减去卡尔曼增益与预测的观测噪声协方差矩阵的乘积的转置,得到更新后的误差协方差矩阵。Pxkk_1
:当前状态预测值误差协方差矩阵。
该代码实现了一个简单的卡尔曼滤波器,可以根据输入的参数进行状态估计和预测,并输出当前状态的估计值以及误差协方差矩阵等相关信息。
KFUD:UD分解Kalman滤波
function [U, D, K] = KFUD(U, D, Phi, Tau, Q, H, R)
% UDUT square root Kalman filter.
%
% Prototype: [U, D, K] = KFUD(U, D, Phi, Tau, Q, H, R)
% Inputs: U - unit upper-triangular matrix
% D - vector representation of diagonal matrix
% Phi, Tau, Q - system matrix, processing noise distribusion matrix
% & noise variance (vector representation)
% H, R - measurement matrix, measurement noise variance
% Outputs: U - unit upper-triangular matrix
% D - vector representation of diagonal matrix
% K - Kalman filter gain
%
% See also RLSUD, UDUT, chol1, qrmgs.% Copyright(c) 2009-2016, by Gongmin Yan, All rights reserved.
% Northwestern Polytechnical University, Xi An, P.R.China
% 12/11/2016n = length(U);W = [Phi*U, Tau]; D1 = [D; Q]; % NOTE: D,Q are both vectormeanD = mean(D)/n*1e-40;for j=n:-1:1 % time updatingD(j) = (W(j,:).*W(j,:))*D1;for i=1:(j-1)if D(j)<=meanD, U(i,j) = 0;else U(i,j) = (W(i,:).*W(j,:))*D1/D(j); endW(i,:) = W(i,:) - U(i,j)*W(j,:);endendif ~exist('R', 'var'), return; endf = (H*U)'; g = D.*f; afa = f'*g+R;for j=n:-1:1 % measurement updatingafa0 = afa - f(j)*g(j); lambda = -f(j)/afa0;D(j) = afa0/afa*D(j); afa = afa0;for i=1:(j-1)s = (i+1):(j-1);U(i,j) = U(i,j) + lambda*(g(i)+U(i,s)*g(s));endendK = U*(D.*(H*U)')/R;
这个函数实现了一种称为通用对角线卡尔曼滤波(UDUT square root Kalman filter)算法。UD分解卡尔曼滤波是一种扩展的状态估计算法,适用于处理非线性系统。
函数接受以下输入参数:
U
:单位上三角矩阵,用于表示状态转移矩阵。D
:一个向量,表示对角线矩阵的元素。Phi
:系统矩阵,表示系统的动态模型。Tau
:一个向量,表示处理噪声的分布矩阵(也称为过程噪声)。Q
:一个向量,表示过程噪声的方差(以向量形式表示)。H
:测量矩阵,表示如何从状态中获取测量值。R
:测量噪声的方差。
函数返回以下输出参数:
U
:更新后的单位上三角矩阵。D
:更新后的对角线矩阵的元素向量。K
:卡尔曼滤波增益。
算法的主要步骤如下:
- 初始化:根据输入参数,初始化一些变量,包括计算过程中的临时变量。
- 时间更新:从后向前遍历每一个时间步,根据系统的动态模型和过程噪声计算每个时间步的状态预测和对角线矩阵的元素。如果预测的对角线元素小于一个阈值(
meanD
),则将其设为零,以避免过小的数值引起数值不稳定。 - 测量更新:如果存在测量噪声方差(即
R
不为零),则进行测量更新步骤。首先计算预测的测量残差(f
)和残差的权重(g
)。然后从后向前遍历每个时间步,根据测量残差和权重更新对角线矩阵的元素和对角线元素上的权重。接着根据更新的对角线元素更新卡尔曼滤波增益(K
)。 - 返回输出:返回更新后的单位上三角矩阵、对角线矩阵的元素向量和卡尔曼滤波增益。
这个函数的输出可以用于进一步的状态估计或控制应用中。
kfc2d:连续时间Kalman滤波离散化
function [Phikk_1, Qk] = kfc2d(Ft, Qt, Ts, n)
% For Kalman filter system differential equation, convert continuous-time
% model to discrete-time model: Ft->Phikk_1, Qt->Qk.
%
% Prototype: [Phikk_1, Qk] = kfc2d(Ft, Qt, Ts, n)
% Inputs: Ft - continous-time system transition matrix
% Qt - continous-time system noise variance matrix
% Ts - discretization time interval
% n - the order for Taylor expansion
% Outputs: Phikk_1 - discrete-time transition matrix
% Qk - discrete-time noise variance matrix
% Alogrithm notes:
% Phikk_1 = I + Ts*Ft + Ts^2/2*Ft^2 + Ts^3/6*Ft^3
% + Ts^4/24*Ft^4 + Ts^5/120*Ft^5 + ...
% Qk = M1*Ts + M2*Ts^2/2 + M3*Ts^3/6 + M4*Ts^4/24 + M5*Ts^5/120 + ...
% where M1 = Qt; M2 = Ft*M1+(Ft*M1)'; M3 = Ft*M2+(Ft*M2)';
% M4 = Ft*M3+(Ft*M3)'; M5 = Ft*M4+(Ft*M4)'; ...
%
% See also kfinit, kffk, kfupdate, kffeedback.% Copyright(c) 2009-2014, by Gongmin Yan, All rights reserved.
% Northwestern Polytechnical University, Xi An, P.R.China
% 05/08/2012Phikk_1 = eye(size(Ft)) + Ts*Ft;Qk = Qt*Ts;if nargin<4 % n==1return;endTsi = Ts; facti = 1; Fti = Ft; Mi = Qt;for i=2:1:nTsi = Tsi*Ts; facti = facti*i;Fti = Fti*Ft;Phikk_1 = Phikk_1 + Tsi/facti*Fti; % Phikk_1FtMi = Ft*Mi;Mi = FtMi + FtMi';Qk = Qk + Tsi/facti*Mi; % Qkend
这段代码是一个用于将连续时间Kalman滤波器的系统差分方程转换为离散时间模型的函数。函数名为kfc2d
,其输入参数包括连续时间系统的转移矩阵Ft
、系统噪声方差矩阵Qt
、离散化时间间隔Ts
和泰勒级数展开的阶数n
。函数的输出包括离散时间的转移矩阵Phikk_1
和噪声方差矩阵Qk
。
代码的主要逻辑如下:
- 首先初始化离散时间的转移矩阵
Phikk_1
为单位矩阵加上第一阶近似项Ts*Ft
。 - 初始化噪声方差矩阵
Qk
为第一阶近似项Qt*Ts
。 - 如果输入的
n
小于等于1(默认值),则直接返回。 - 进入循环,从第二阶开始迭代计算更高阶的近似项。
- 在每一次迭代中,更新时间间隔
Tsi
为当前时间间隔的幂次,即Tsi = Tsi*Ts
。 - 更新阶数因子
facti
为当前阶数因子的幂次,即facti = facti*i
。 - 更新连续时间系统的转移矩阵
Fti
为当前转移矩阵的幂次,即Fti = Fti*Ft
。 - 将当前时间间隔和阶数因子的乘积与当前转移矩阵相加,得到离散时间的转移矩阵,即
Phikk_1 = Phikk_1 + Tsi/facti*Fti
。 - 更新噪声方差矩阵的计算,通过当前时间间隔和当前噪声方差矩阵的乘积以及转置运算得到新的噪声方差矩阵,即
Mi = FtMi + FtMi'
。 - 将当前时间间隔和阶数因子的乘积与新的噪声方差矩阵相加,得到离散时间的噪声方差矩阵,即
Qk = Qk + Tsi/facti*Mi
。 - 循环结束后,返回离散时间的转移矩阵
Phikk_1
和噪声方差矩阵Qk
。
该代码主要用于根据连续时间模型的差分方程,通过泰勒级数展开的方式,计算得到离散时间的转移矩阵和噪声方差矩阵,以便在离散时间环境下应用Kalman滤波器进行状态估计和预测。
三、ekf:扩展卡尔曼滤波
EKF(Extended Kalman Filter,简称扩展卡尔曼滤波器)是一种高效率的递归滤波器(自回归滤波器),它能够从一系列的不完全及包含噪声的测量中,估计动态系统的状态1。
EKF滤波的主要思想是利用状态转移矩阵和观测矩阵,结合当前状态和上一时刻的状态,来估计当前的最优状态1。具体来说,EKF滤波的步骤包括1:
- 初始化滤波器的状态向量和协方差矩阵。
- 对于每个时间步长,执行以下步骤:
a. 利用状态转移矩阵和当前状态向量,计算出下一时刻的状态向量和协方差矩阵。
b. 结合观测矩阵和当前观测向量,计算出当前时刻的状态估计值和协方差矩阵。
c. 根据新的状态估计值和协方差矩阵,更新滤波器的状态向量和协方差矩阵。 3. 重复执行步骤2,进行迭代优化,直到满足收敛条件为止。
与传统的滤波器相比,EKF滤波具有更好的数值稳定性和计算效率,能够更准确地估计状态变量的值,并且在高维度和非线性较强的系统中表现更好。
function kf = ekf(kf, yk, TimeMeasBoth)if nargin==1;TimeMeasBoth = 'T';elseif nargin==2TimeMeasBoth = 'B';endif TimeMeasBoth=='T' || TimeMeasBoth=='B'if isfield(kf, 'fx') % nonliear state Jacobian matrix[kf.Phikk_1, kf.xkk_1] = ekfJcb(kf.fx, kf.xk, kf.px);if isempty(kf.xkk_1), kf.xkk_1 = kf.Phikk_1*kf.xk; endelsekf.xkk_1 = kf.Phikk_1*kf.xk;endkf.Pxkk_1 = kf.Phikk_1*kf.Pxk*kf.Phikk_1' + kf.Gammak*kf.Qk*kf.Gammak';if TimeMeasBoth=='T' % time updating onlykf.xk = kf.xkk_1; kf.Pxk = kf.Pxkk_1;return;endendif TimeMeasBoth=='M' || TimeMeasBoth=='B'if TimeMeasBoth=='M' % meas updating onlykf.xkk_1 = kf.xk; kf.Pxkk_1 = kf.Pxk;endif isfield(kf, 'hx') % nonliear measurement Jacobian matrix[kf.Hk, kf.ykk_1] = ekfJcb(kf.hx, kf.xkk_1, kf.py);if isempty(kf.ykk_1), kf.ykk_1 = kf.Hk*kf.xkk_1; endelsekf.ykk_1 = kf.Hk*kf.xkk_1;endkf.Pxykk_1 = kf.Pxkk_1*kf.Hk'; kf.Pykk_1 = kf.Hk*kf.Pxykk_1 + kf.Rk;% filteringkf.Kk = kf.Pxykk_1*kf.Pykk_1^-1;kf.xk = kf.xkk_1 + kf.Kk*(yk-kf.ykk_1);kf.Pxk = kf.Pxkk_1 - kf.Kk*kf.Pykk_1*kf.Kk'; kf.Pxk = (kf.Pxk+kf.Pxk')/2;end
这段代码是一个扩展卡尔曼滤波器(Extended Kalman Filter, EKF)的实现。下面是对代码功能的解释:
-
函数
ekf
接受三个输入参数:kf
(扩展卡尔曼滤波器的状态),yk
(测量值),TimeMeasBoth
(一个字符,表示时间测量的类型)。 -
根据输入参数的数量,确定
TimeMeasBoth
的值。如果输入参数数量为1,则将TimeMeasBoth
设置为字符 ‘T’;如果输入参数数量为2,则将TimeMeasBoth
设置为字符 ‘B’。 -
根据
TimeMeasBoth
的值,执行以下操作:-
如果 TimeMeasBoth 是字符 ‘T’ 或者字符 ‘B’:
-
如果
kf
中存在字段 ‘fx’(非线性状态雅可比矩阵),则调用函数ekfJcb
计算kf
的 ‘Phikk_1’ 和 ‘xkk_1’(分别是状态转移矩阵和下一时刻的状态估计值)。function [Jcb, y] = ekfJcb(hfx, x, tpara)[Jcb, y] = feval(hfx, x, tpara);
-
如果
xkk_1
是空的,则将其设置为Phikk_1
乘以当前状态xk
。 -
如果
fx
不存在,则将xkk_1
设置为 'Phikk_1’乘以当前状态xk
。 -
计算
Pxkk_1
(下一时刻的协方差矩阵估计值),使用Phikk_1
、Pxk
、Gammak
、Qk
和Gammak
的值进行计算。 -
如果
TimeMeasBoth
是字符T
,则只进行时间更新,将下一时刻的状态估计值xkk_1
和协方差矩阵Pxkk_1
赋值给当前状态xk
和协方差矩阵Pxk
,然后返回。
-
-
如果
TimeMeasBoth
是字符B
,则继续执行下面的操作:- 根据下一时刻的状态估计值
xkk_1
和协方差矩阵Pxkk_1
,以及测量值yk
和噪声协方差矩阵Rk
,计算卡尔曼增益(Kalman gain)和更新后的状态估计值xk
和协方差矩阵Pxk
。 - 将更新后的状态估计值
xk
和协方差矩阵Pxk
赋值给当前状态xk
和协方差矩阵Pxk
。
- 根据下一时刻的状态估计值
-
-
函数执行完毕,输出更新后的扩展卡尔曼滤波器状态
kf
。
总体而言,这段代码实现了扩展卡尔曼滤波器的时间更新和测量更新过程,根据输入的状态、测量值和时间测量类型,更新滤波器的状态和协方差矩阵。
四、UKF:无迹卡尔曼滤波
UKF(Unscented Kalman Filter),中文释义是无迹卡尔曼滤波、无迹卡尔曼滤波或者去芳香卡尔曼滤波,是一种用于处理非线性非高斯系统的状态估计的滤波算法1。
UKF滤波的主要思想是利用Unscented变换来将非线性系统方程转化为线性假设下的标准Kalman滤波体系。具体来说,UKF滤波的步骤包括:
- 选择一组Unscented变换的参数,计算Unscented变换中的权重和均值。
- 对系统模型和观测模型进行一阶Taylor展开,得到非线性的残差项。
- 利用这些残差项来更新状态估计值。
- 重复执行步骤2和3,进行迭代优化,直到满足收敛条件为止。
与传统的卡尔曼滤波相比,UKF滤波具有更好的数值稳定性和计算效率,能够更准确地估计状态变量的值,并且在高维度和非线性较强的系统中表现更好。
需要注意的是,在实际应用中,UKF滤波算法的实现和参数设置需要根据具体的系统模型和观测模型进行调整,并进行实验验证和优化。同时,对于大规模或实时性要求高的应用场景,还需要考虑算法的效率和可扩展性。
function kf = ukf(kf, yk, TimeMeasBoth)
% Unscented Kalman filter for nonlinear system.
%
% Prototype: kf = ukf(kf, yk, TimeMeasBoth)
% Inputs: kf - filter structure array
% yk - measurement vector
% TimeMeasBoth - described as follows,
% TimeMeasBoth='T' (or nargin==1) for time updating only,
% TimeMeasBoth='M' for measurement updating only,
% TimeMeasBoth='B' (or nargin==2) for both time and
% measurement updating.
% Output: kf - filter structure array after time/meas updating
%
% See also ukfUT, ckf, ssukf, ekf, kfupdate.% Copyright(c) 2009-2014, by Gongmin Yan, All rights reserved.
% Northwestern Polytechnical University, Xi An, P.R.China
% 27/09/2012if nargin==1;TimeMeasBoth = 'T';elseif nargin==2TimeMeasBoth = 'B';endif ~isfield(kf, 'alpha')kf.alpha = 1e-3; kf.beta = 2; kf.kappa = 0;endif TimeMeasBoth=='T' || TimeMeasBoth=='B'if isfield(kf, 'fx') % nonliear state propagation[kf.xkk_1, kf.Pxkk_1] = ukfUT(kf.xk, kf.Pxk, kf.fx, kf.px, kf.alpha, kf.beta, kf.kappa);kf.Pxkk_1 = kf.Pxkk_1 + kf.Gammak*kf.Qk*kf.Gammak';elsekf.xkk_1 = kf.Phikk_1*kf.xk;kf.Pxkk_1 = kf.Phikk_1*kf.Pxk*kf.Phikk_1' + kf.Gammak*kf.Qk*kf.Gammak';endif TimeMeasBoth=='T' % time updating onlykf.xk = kf.xkk_1; kf.Pxk = kf.Pxkk_1;return;endendif TimeMeasBoth=='M' || TimeMeasBoth=='B'if TimeMeasBoth=='M' % meas updating onlykf.xkk_1 = kf.xk; kf.Pxkk_1 = kf.Pxk;endif isfield(kf, 'hx') % nonliear measurement propagation[kf.ykk_1, kf.Pykk_1, kf.Pxykk_1] = ukfUT(kf.xkk_1, kf.Pxkk_1, kf.hx, kf.py, kf.alpha, kf.beta, kf.kappa);kf.Pykk_1 = kf.Pykk_1 + kf.Rk;elsekf.ykk_1 = kf.Hk*kf.xkk_1;kf.Pxykk_1 = kf.Pxkk_1*kf.Hk'; kf.Pykk_1 = kf.Hk*kf.Pxykk_1 + kf.Rk;end% filteringkf.Kk = kf.Pxykk_1*kf.Pykk_1^-1;kf.xk = kf.xkk_1 + kf.Kk*(yk-kf.ykk_1);kf.Pxk = kf.Pxkk_1 - kf.Kk*kf.Pykk_1*kf.Kk'; kf.Pxk = (kf.Pxk+kf.Pxk')/2;end
这段代码是一个 UKF 的实现。下面是对代码功能的解释:
- 输入参数:
kf
:一个结构体数组,包含卡尔曼滤波器的状态和参数信息,例如状态向量xk
、状态协方差矩阵Pxk
、时间更新系数fx
、测量更新系数hx
等。yk
:测量向量,即系统的观测值。TimeMeasBoth
:一个字符串,用于指定时间更新和测量更新的方式,可选值为'T'
(只进行时间更新)、'M'
(只进行测量更新)和'B'
(同时进行时间和测量更新)。
- 根据输入参数确定更新方式:
- 如果输入参数
TimeMeasBoth
为'T'
或者没有指定,则执行时间更新。 - 如果输入参数
TimeMeasBoth
为'M'
或者没有指定,则执行测量更新。
- 如果输入参数
- 时间更新:
- 如果结构体数组
kf
中没有alpha
、beta
和kappa
字段,则给它们赋默认值。 - 如果结构体数组
kf
中有fx
字段,表示存在非线性状态转移函数,此时需要根据输入的观测值和滤波器参数执行时间更新。- 首先,通过调用函数
ukfUT
(也是该代码文件中的函数)计算状态转移后的状态向量和状态协方差矩阵。 - 然后,根据滤波器参数计算状态协方差矩阵的修正项,并将其加到状态协方差矩阵中。
- 首先,通过调用函数
- 如果结构体数组
kf
中没有fx
字段,表示状态转移是线性的,直接使用预测的状态向量和协方差矩阵。
- 如果结构体数组
- 测量更新:
- 如果执行的是测量更新,首先判断是否只有测量更新。
- 如果只有测量更新,则将预测的状态向量和协方差矩阵分别赋值给当前的状态向量和协方差矩阵。
- 如果同时进行时间和测量更新,则根据滤波器参数执行测量更新。
- 如果结构体数组
kf
中有hx
字段,表示存在非线性测量转移函数,此时需要根据输入的观测值和滤波器参数执行测量更新。- 首先,通过调用函数
ukfUT
计算测量转移后的测量向量、测量协方差矩阵和交叉协方差矩阵。 - 然后,根据滤波器参数计算测量协方差矩阵的修正项,并将其加到测量协方差矩阵中。
- 首先,通过调用函数
- 如果结构体数组
kf
中没有hx
字段,表示测量转移是线性的,直接使用预测的测量向量和协方差矩阵。
- 如果结构体数组
- 返回结果: 更新后的卡尔曼滤波器结构体数组
kf
将作为输出返回。
总体来说,这段代码实现了非线性系统的卡尔曼滤波器的时间更新和测量更新过程。它根据输入的观测值和滤波器参数,对滤波器的状态向量和协方差矩阵进行更新,以实现滤波器的状态估计功能。
ukfUT
function [y, Pyy, Pxy, X, Y] = ukfUT(x, Pxx, hfx, tpara, alpha, beta, kappa)
% Unscented transformation.
%
% Prototype: [y, Pyy, Pxy, X, Y] = ukfUT(x, Pxx, hfx, tpara, alpha, beta, kappa)
% Inputs: x, Pxx - state vector and its variance matrix
% hfx - a handle for nonlinear state equation
% tpara - some time-variant parameter pass to hfx
% alpha, beta, kappa - parameters for UT transformation
% Outputs: y, Pyy - state vector and its variance matrix after UT
% Pxy - covariance matrix between x & y
% X, Y - Sigma-point vectors before & after UT
%
% See also ukf, ckfCT, SSUT.% Copyright(c) 2009-2014, by Gongmin Yan, All rights reserved.
% Northwestern Polytechnical University, Xi An, P.R.China
% 27/09/2012n = length(x);lambda = alpha^2*(n+kappa) - n;gamma = sqrt(n+lambda);Wm = [lambda/gamma^2; repmat(1/(2*gamma^2),2*n,1)]; Wc = [Wm(1)+(1-alpha^2+beta); Wm(2:end)];sPxx = gamma*chol(Pxx)'; % Choleskey decompositionxn = repmat(x,1,n); X = [x, xn+sPxx, xn-sPxx];Y(:,1) = feval(hfx, X(:,1), tpara); m=length(Y); y = Wm(1)*Y(:,1);Y = repmat(Y,1,2*n+1);for k=2:1:2*n+1 % Sigma points nolinear propagationY(:,k) = feval(hfx, X(:,k), tpara);y = y + Wm(k)*Y(:,k);endPyy = zeros(m); Pxy = zeros(n,m);for k=1:1:2*n+1yerr = Y(:,k)-y;Pyy = Pyy + Wc(k)*(yerr*yerr'); % variancexerr = X(:,k)-x;Pxy = Pxy + Wc(k)*xerr*yerr'; % covarianceend
这段代码实现了Unscented变换(Unscented Transformation,UT)的功能。UT是一种用于非线性系统状态估计的方法,它通过对非线性方程进行一系列采样和传播,得到状态变量的估计结果。
该函数的输入参数包括:
x
:状态向量(state vector)。Pxx
:状态向量的方差矩阵(variance matrix)。hfx
:一个处理非线性状态方程的句柄(handle)。tpara
:一些时间变化的参数,用于传递给hfx
。alpha
、beta
、kappa
:UT变换的参数。
该函数的输出参数包括:
y
:经过UT变换后的状态向量。Pyy
:经过UT变换后的状态向量的方差矩阵。Pxy
:状态向量和经过UT变换后的状态向量之间的协方差矩阵。X
、Y
:在UT变换之前和之后的Sigma点向量。
代码的主要步骤如下:
- 根据输入的参数计算一些中间变量,包括
n
(状态向量的长度)、lambda
、gamma
、Wm
和Wc
。 - 进行Cholesky分解,将输入的状态方差矩阵
Pxx
转换为下三角矩阵sPxx
。 - 构造Sigma点向量
X
,包括三个部分的点,分别是状态向量本身、状态向量加上和减去状态方差矩阵的Cholesky分解后的矩阵。 - 对每个Sigma点进行非线性传播,通过调用句柄函数
hfx
计算每个点的输出值,并将结果存储在矩阵Y
中。 - 根据UT变换的公式计算估计的状态向量
y
和方差矩阵Pyy
,以及状态向量和估计状态向量之间的协方差矩阵Pxy
。 - 返回估计的状态向量、方差矩阵、协方差矩阵以及在UT变换之前和之后的Sigma点向量。
需要注意的是,该代码中使用了MATLAB的函数feval来调用句柄函数hfx,并在循环中进行了多次调用。因此,在使用该代码时,需要确保句柄函数hfx的正确实现和可调用性。
utpoint
function [U, wm, wc] = utpoint(n, afa, beta, kappa)
% Calculate 3th or 5th-order cubature points.
%
% Prototype: [U, wm, wc] = utpoint(n, afa, beta, kappa)
% Inputs: n - dimension
% afa,beta,kappa - parameters
% Outputs: U - UT points
% wm,wc - weights
%
% See also cubpoint, ghpoint, ukf.% Copyright(c) 2009-2022, by Gongmin Yan, All rights reserved.
% Northwestern Polytechnical University, Xi An, P.R.China
% 01/08/2022if nargin<4, kappa=0; endif nargin<3, beta=2; endif nargin<2, afa=1e-3; endlambda = afa^2*(n+kappa)-n; gamma = sqrt(n+lambda);U = gamma*[eye(n), -eye(n), zeros(n,1)];wm = [repmat(1/(2*gamma^2),1,2*n), lambda/gamma^2];wc = wm; wc(end) = wc(end)+(1-afa^2+beta);
这段代码是一个MATLAB函数,用于计算3阶或5阶的 cubature 点的权重。下面是代码的功能解释:
- 函数的输入参数为:
n
:维度(整数)afa
、beta
、kappa
:参数(可以是标量、向量或矩阵)
- 函数的输出参数为:
U
:cubature 点的向量(大小为(3*n, 1)
的列向量)wm
:与U
中的每个点对应的权重(大小为(3*n, 1)
的列向量)wc
:与U
中的每个点对应的权重(大小为(3*n, 1)
的列向量)
- 代码逻辑解释:
- 首先,检查输入参数的数量,如果小于4个,将
kappa
设置为0;如果小于3个,将beta
设置为2;如果小于2个,将afa
设置为1e-3。 - 接下来,根据参数计算变量
lambda
和gamma
的值。 - 然后,根据
gamma
和其他参数计算 cubature 点的矩阵U
。 - 最后,根据参数和计算结果计算权重向量
wm
和wc
。其中,wm
的前两个元素是相同的,大小为(2*n, 1)
的矩阵,每个元素都是1/(2*gamma^2)
;第三个元素是lambda/gamma^2
。wc
的前两个元素与wm
相同,最后一个元素是(3*n, 1)
的列向量,值为(1-afa^2+beta)
。
- 首先,检查输入参数的数量,如果小于4个,将
这个函数的作用是通过输入的参数计算 cubature 点的位置和权重。 cubature 点是一种用于数值积分的方法,通过在低维度空间中计算一些点并将它们的权重相加以估计高维度空间的积分值。
五、ssukf
SSUKF是一种非线性滤波算法,全称为Unscented Particle Filtering with Square-Root Unscented Transform。它结合了Unscented变换和粒子滤波的优点,用于处理非线性非高斯系统的状态估计问题。SSUKF的主要步骤包括:
- 选择一组Unscented变换的参数,计算Unscented变换中的权重和均值。
- 对系统模型和观测模型进行一阶Taylor展开,得到非线性的残差项。
- 使用粒子滤波的方法,通过对残差项进行加权和估计,得到新的状态估计值。
- 重复执行步骤2和3,进行迭代优化,直到满足收敛条件为止。同时,对于大规模或实时性要求高的应用场景,还需要考虑算法的效率和可扩展性。
UKF 和 SSUKF 区别:
- Unscented变换的方式不同:UKF使用标准的Unscented变换,而SSUKF使用Square-Root Unscented变换,这种变换可以更快地计算权重和均值,提高了算法的计算效率。
- 粒子滤波的方式不同:在UKF中,使用标准粒子滤波来估计状态变量,而在SSUKF中,使用一种称为序贯 Importance Sampling的粒子滤波方法来估计状态变量。这种滤波方法可以更好地处理非线性较强的系统,并且可以提高算法的数值稳定性。
- 适用场景不同:UKF适用于处理高维度的非线性系统,而SSUKF适用于处理低维度的非线性系统,尤其是对于一些实时性要求较高的应用场景。
需要注意的是,无论是UKF还是SSUKF,它们都是一种相对较新的滤波算法,在实际应用中还需要根据具体的系统模型和观测模型进行调整和优化,同时考虑算法的效率和可扩展性1。
function kf = ssukf(kf, yk, TimeMeasBoth)
% Unscented Kalman filter for nonlinear system.
%
% Prototype: kf = ssukf(kf, yk, TimeMeasBoth)
% Inputs: kf - filter structure array
% yk - measurement vector
% TimeMeasBoth - described as follows,
% TimeMeasBoth='T' (or nargin==1) for time updating only,
% TimeMeasBoth='M' for measurement updating only,
% TimeMeasBoth='B' (or nargin==2) for both time and
% measurement updating.
% Output: kf - filter structure array after time/meas updating
%
% See also ukf, SSUT, ckf, ekf, kfupdate.% Copyright(c) 2009-2022, by Gongmin Yan, All rights reserved.
% Northwestern Polytechnical University, Xi An, P.R.China
% 08/06/2022if nargin==1;TimeMeasBoth = 'T';elseif nargin==2TimeMeasBoth = 'B';endif TimeMeasBoth=='T' || TimeMeasBoth=='B'if isfield(kf, 'fx') % nonliear state propagation[kf.xkk_1, kf.Pxkk_1] = SSUT(kf.xk, kf.Pxk, kf.fx, kf.px, 0);kf.Pxkk_1 = kf.Pxkk_1 + kf.Gammak*kf.Qk*kf.Gammak';elsekf.xkk_1 = kf.Phikk_1*kf.xk;kf.Pxkk_1 = kf.Phikk_1*kf.Pxk*kf.Phikk_1' + kf.Gammak*kf.Qk*kf.Gammak';endif TimeMeasBoth=='T' % time updating onlykf.xk = kf.xkk_1; kf.Pxk = kf.Pxkk_1;return;endendif TimeMeasBoth=='M' || TimeMeasBoth=='B'if TimeMeasBoth=='M' % meas updating onlykf.xkk_1 = kf.xk; kf.Pxkk_1 = kf.Pxk;endif isfield(kf, 'hx') % nonliear measurement propagation[kf.ykk_1, kf.Pykk_1, kf.Pxykk_1] = SSUT(kf.xkk_1, kf.Pxkk_1, kf.hx, kf.py, 0);kf.Pykk_1 = kf.Pykk_1 + kf.Rk;elsekf.ykk_1 = kf.Hk*kf.xkk_1;kf.Pxykk_1 = kf.Pxkk_1*kf.Hk'; kf.Pykk_1 = kf.Hk*kf.Pxykk_1 + kf.Rk;end% filteringkf.Kk = kf.Pxykk_1*kf.Pykk_1^-1;kf.xk = kf.xkk_1 + kf.Kk*(yk-kf.ykk_1);kf.Pxk = kf.Pxkk_1 - kf.Kk*kf.Pykk_1*kf.Kk'; kf.Pxk = (kf.Pxk+kf.Pxk')/2;end
这段代码是一个用于非线性系统的扩展卡尔曼滤波(Unscented Kalman Filter)的函数。它接受一个初始的卡尔曼滤波器结构数组kf
,一个测量向量yk
,以及一个表示时间更新和测量更新的标志TimeMeasBoth
。
代码的主要逻辑如下:
- 根据输入参数的数量,确定
TimeMeasBoth
的值,如果只有一个输入参数,则TimeMeasBoth
被设置为’T’,表示只进行时间更新;如果有两个输入参数,则TimeMeasBoth
被设置为’B’,表示同时进行时间更新和测量更新。 - 如果
TimeMeasBoth
为’T’或’B’,则执行时间更新步骤。如果卡尔曼滤波器结构数组kf
中存在非线性状态转移函数fx
,则使用SSUT函数进行状态预测,并更新状态和状态协方差矩阵。如果只有时间更新,则直接返回更新后的kf
。 - 如果
TimeMeasBoth
为’M’或’B’,则执行测量更新步骤。如果只有测量更新,则将状态和状态协方差矩阵设置为先前的值。如果卡尔曼滤波器结构数组kf
中存在非线性测量转移函数hx
,则使用SSUT函数进行测量预测,并更新测量和测量协方差矩阵。 - 执行滤波步骤。计算卡尔曼增益(Kalman gain),并使用测量和预测的状态和协方差矩阵更新状态估计值和状态协方差矩阵。
最终,函数返回更新后的卡尔曼滤波器结构数组kf
。
需要注意的是,该代码依赖于其他函数SSUT
,这些函数可能需要在其他地方定义或提供。此外,该代码还依赖于一些变量的定义,例如Phikk_1
、Gammak
、Qk
、Hk
等,这些变量应该在输入的卡尔曼滤波器结构数组kf
中提供。
如果您要使用该函数,请确保提供正确的输入参数和正确的函数依赖关系。
SSUT
function [y, Pyy, Pxy, X, Y] = SSUT(x, Pxx, hfx, tpara, w0)
% Spherical Simplex Unscented Transformation.
%
% Prototype: [y, Pyy, Pxy, X, Y] = SSUT(x, Pxx, hfx, tpara, w0)
% Inputs: x, Pxx - state vector and its variance matrix
% hfx - a handle for nonlinear state equation
% tpara - some time-variant parameter pass to hfx
% w0 - weight0
% Outputs: y, Pyy - state vector and its variance matrix after UT
% Pxy - covariance matrix between x & y
% X, Y - Sigma-point vectors before & after UT
%
% See also ssukf, ukfUT, ckfCT.% Copyright(c) 2009-2022, by Gongmin Yan, All rights reserved.
% Northwestern Polytechnical University, Xi An, P.R.China
% 08/06/2022
global SSUT_s SSUT_wif isempty(SSUT_w), SSUT_w(1)=0; endif nargin<5, w0=0; endn = length(x);if n~=size(SSUT_s,1) || SSUT_w(1)~=w0w1 = (1-w0)/(n+1);s = [0, -1/sqrt(2), 1/sqrt(2)];for j=2:ns1 = [s(:,1); 0];for i=1:js1(:,i+1) = [s(:,i+1); -1/sqrt(j*(j+1))];ends1(:,j+2) = [zeros(j-1,1);j/sqrt(j*(j+1))];s = s1;endSSUT_s = s/sqrt(w1); SSUT_w = [w0, repmat(w1,1,n+1)];end%%X = repmat(x,1,n+2) + chol(Pxx)'*SSUT_s;y = SSUT_w(1)*feval(hfx, X(:,1), tpara); m = length(y);Y = repmat(y,1,2*n);for k=2:1:n+2Y(:,k) = feval(hfx, X(:,k), tpara);y = y + SSUT_w(k)*Y(:,k);endPyy = zeros(m); Pxy = zeros(n,m);for k=1:1:n+2yerr = Y(:,k)-y;Pyy = Pyy + SSUT_w(k)*(yerr*yerr'); % variancexerr = X(:,k)-x;Pxy = Pxy + SSUT_w(k)*xerr*yerr'; % covarianceend
这是一个实现了球面简单卡尔曼滤波(Spherical Simplex Unscented Transformation, SSUT)的 MATLAB 函数。SSUT 是一种非线性滤波方法,用于对非线性系统进行状态估计和预测。
函数输入参数包括:
x
:状态向量(一个列向量)。Pxx
:状态向量的方差矩阵。hfx
:一个用于描述非线性状态方程的函数句柄。tpara
:一个时间变参数向量,用于传递给hfx
函数。w0
:权重参数。
函数输出参数包括:
y
:经过 UT 变换后的状态向量(一个列向量)。Pyy
:经过 UT 变换后的状态向量的方差矩阵。Pxy
:状态向量和经过 UT 变换后的状态向量之间的协方差矩阵。X
和Y
:在 UT 变换前后生成的 Sigma 点向量。
函数首先检查是否已经初始化了一些全局变量 SSUT_s
和 SSUT_w
,如果没有则根据默认值进行初始化。然后根据输入的参数 x
和 Pxx
生成相应的 Sigma 点。接着调用非线性状态方程 hfx
来计算这些 Sigma 点对应的输出值,并将这些输出值存储在 Y
中。然后根据球面简单卡尔曼滤波的算法计算经过 UT 变换后的状态向量 y
和其方差矩阵 Pyy
,以及状态向量和经过 UT 变换后的状态向量之间的协方差矩阵 Pxy
。
最后,函数返回经过 UT 变换后的状态向量 y
和其方差矩阵 Pyy
,以及状态向量和经过 UT 变换后的状态向量之间的协方差矩阵 Pxy
,以及在 UT 变换前后生成的 Sigma 点向量 X
和 Y
。
该函数是 SSUT 的实现,可以用于非线性系统的状态估计和预测。
六、CKF:容积卡尔曼滤波
容积卡尔曼滤波(Cube-based Radial Basis Function,简称CKF)是一种用于处理非线性非高斯系统的状态估计的滤波算法。
CKF滤波的核心思想是利用容积准则来近似状态的后验均值和协方差,以保证在理论上以三阶多项式逼近任何非线性高斯状态的后验均值和方差。
与传统的卡尔曼滤波相比,CKF滤波具有更好的数值稳定性和计算效率,能够更准确地估计状态变量的值,并且在高维度和非线性较强的系统中表现更好。
function kf = ckf(kf, yk, TimeMeasBoth)
% Cubature transformation KF.
%
% Prototype: kf = ckf(kf, yk, TimeMeasBoth)
% Inputs: kf - filter structure array
% yk - measurement vector
% TimeMeasBoth - described as follows,
% TimeMeasBoth='T' (or nargin==1) for time updating only,
% TimeMeasBoth='M' for measurement updating only,
% TimeMeasBoth='B' (or nargin==2) for both time and
% measurement updating.
% Output: kf - filter structure array after time/meas updating
%
% See also ckfCT, ukf, ekf, kfupdate.% Copyright(c) 2009-2022, by Gongmin Yan, All rights reserved.
% Northwestern Polytechnical University, Xi An, P.R.China
% 01/03/2022if nargin==1;TimeMeasBoth = 'T';elseif nargin==2TimeMeasBoth = 'B';endif TimeMeasBoth=='T' || TimeMeasBoth=='B'if isfield(kf, 'fx') % nonliear state propagation[kf.xkk_1, kf.Pxkk_1] = ckfCT(kf.xk, kf.Pxk, kf.fx, kf.px);kf.Pxkk_1 = kf.Pxkk_1 + kf.Gammak*kf.Qk*kf.Gammak';elsekf.xkk_1 = kf.Phikk_1*kf.xk;kf.Pxkk_1 = kf.Phikk_1*kf.Pxk*kf.Phikk_1' + kf.Gammak*kf.Qk*kf.Gammak';endif TimeMeasBoth=='T' % time updating onlykf.xk = kf.xkk_1; kf.Pxk = kf.Pxkk_1;return;endendif TimeMeasBoth=='M' || TimeMeasBoth=='B'if TimeMeasBoth=='M' % meas updating onlykf.xkk_1 = kf.xk; kf.Pxkk_1 = kf.Pxk;endif isfield(kf, 'hx') % nonliear measurement propagation[kf.ykk_1, kf.Pykk_1, kf.Pxykk_1] = ckfCT(kf.xkk_1, kf.Pxkk_1, kf.hx, kf.py);kf.Pykk_1 = kf.Pykk_1 + kf.Rk;elsekf.ykk_1 = kf.Hk*kf.xkk_1;kf.Pxykk_1 = kf.Pxkk_1*kf.Hk'; kf.Pykk_1 = kf.Hk*kf.Pxykk_1 + kf.Rk;end% filteringkf.Kk = kf.Pxykk_1*kf.Pykk_1^-1;kf.xk = kf.xkk_1 + kf.Kk*(yk-kf.ykk_1);kf.Pxk = kf.Pxkk_1 - kf.Kk*kf.Pykk_1*kf.Kk'; kf.Pxk = (kf.Pxk+kf.Pxk')/2;end
这段代码是一个实现Cubature Kalman Filter(CKF)的函数。CKF是一种非线性滤波方法,用于估计动态系统的状态。
函数ckf
的作用是根据输入的滤波器结构数组kf
、测量向量yk
和时间/测量更新标志TimeMeasBoth
,对滤波器进行时间更新或测量更新。
代码的主要逻辑如下:
- 根据输入的参数确定时间/测量更新标志
TimeMeasBoth
。如果只有一个输入参数,则默认为时间更新标志为’T’;如果有两个输入参数,则根据第二个参数确定更新标志。 - 如果时间更新标志为’T’或’B’(表示需要进行时间更新或同时进行时间更新和测量更新),执行以下操作:
- 如果滤波器结构数组
kf
中存在非线性状态传播函数fx
,则使用ckfCT
函数进行状态预测和协方差预测。 - 如果时间更新标志为’T’,则更新滤波器的状态和协方差,并返回结果。
- 如果滤波器结构数组
- 如果测量更新标志为’M’或’B’(表示需要进行测量更新或同时进行时间更新和测量更新),执行以下操作:
- 如果测量更新标志为’M’,则将滤波器的状态和协方差设置为当前状态和协方差。
- 如果滤波器结构数组
kf
中存在非线性测量传播函数hx
,则使用ckfCT
函数进行测量预测和协方差预测。 - 进行滤波,计算卡尔曼增益、状态估计和协方差估计。
最后,函数返回更新后的滤波器结构数组kf
。
需要注意的是,这段代码中的一些函数(如ckfCT
、ukf
、ekf
、kfupdate
)并没有在代码中定义,可能是在其他地方定义的辅助函数或子函数。这段代码只展示了实现CKF的主要逻辑,而没有提供完整的实现细节。
ckfCT
function [y, Pyy, Pxy, X, Y] = ckfCT(x, Pxx, hfx, tpara)
% Spherical-Radial Cubature transformation.
%
% Prototype: [y, Pyy, Pxy, X, Y] = ckfCT(x, Pxx, hfx, tpara)
% Inputs: x, Pxx - state vector and its variance matrix
% hfx - a handle for nonlinear state equation
% tpara - some time-variant parameter pass to hfx
% Outputs: y, Pyy - state vector and its variance matrix after UT
% Pxy - covariance matrix between x & y
% X, Y - Sigma-point vectors before & after UT
%
% See also ckf, ukfUT, SSUT.% Copyright(c) 2009-2022, by Gongmin Yan, All rights reserved.
% Northwestern Polytechnical University, Xi An, P.R.China
% 01/03/2022n = length(x);sPxx = sqrt(n)*chol(Pxx)'; % Choleskey decompositionxn = repmat(x,1,n); X = [xn+sPxx, xn-sPxx];y = feval(hfx, X(:,1), tpara);Y = repmat(y,1,2*n);Pyy = Y(:,1)*Y(:,1)'; Pxy = X(:,1)*Y(:,1)';for k=2:1:2*nY(:,k) = feval(hfx, X(:,k), tpara);y = y + Y(:,k);Pyy = Pyy + Y(:,k)*Y(:,k)';Pxy = Pxy + X(:,k)*Y(:,k)';endy = 1/(2*n)*y; % y meanPyy = 1/(2*n)*Pyy - y*y'; Pxy = 1/(2*n)*Pxy - x*y';% Y(:,1) = feval(hfx, X(:,1), tpara); m=length(Y); y = Y(:,1);
% Y = repmat(Y,1,2*n);
% Pyy = zeros(m); Pxy = zeros(n,m);
% for k=2:1:2*n % Sigma points nolinear propagation
% Y(:,k) = feval(hfx, X(:,k), tpara);
% y = y + Y(:,k);
% end
% y = 1/(2*n)*y;
% for k=1:1:2*n
% yerr = Y(:,k)-y;
% Pyy = Pyy + (yerr*yerr'); % variance
% xerr = X(:,k)-x;
% Pxy = Pxy + xerr*yerr'; % covariance
% end
% Pyy = 1/(2*n)*Pyy; Pxy = 1/(2*n)*Pxy;
This code implements the Spherical-Radial Cubature transformation (CKF-CT) for nonlinear state estimation.下面是代码的功能解释:
- 代码输入:
x
:当前状态的向量。Pxx
:当前状态向量的方差矩阵。hfx
:非线性状态方程的句柄。tpara
:传递给hfx
的一些时间变化参数。
- 代码输出:
y
:经过Unscented变换后的状态向量。Pyy
:经过Unscented变换后的状态向量的方差矩阵。Pxy
:经过Unscented变换后的状态向量和初态向量之间的协方差矩阵。X
:在进行Unscented变换之前的Sigma点向量。Y
:在进行Unscented变换之后的Sigma点向量。
- 代码实现:
- 首先,通过Cholesky分解将输入的方差矩阵
Pxx
转换为上三角矩阵sPxx
。 - 然后,根据当前的状态向量
x
和上三角矩阵sPxx
生成两个Sigma点,即X
矩阵。 - 接下来,通过调用非线性状态方程的句柄
hfx
,计算初始的Sigma点对应的输出向量Y
。 - 然后,使用循环计算每个Sigma点的输出,并将它们累加到总输出向量
y
和协方差矩阵Pyy
中。同时,计算初始状态向量和总输出向量之间的协方差矩阵Pxy
。 - 最后,根据总输出向量和协方差矩阵计算最终的状态向量和协方差矩阵。
- 首先,通过Cholesky分解将输入的方差矩阵
- 注意事项:
- 该代码使用了MATLAB中的函数feval,用于调用非线性状态方程的句柄
hfx
进行计算。确保在使用该代码之前,已经定义并正确设置了非线性状态方程的句柄hfx
和相关参数tpara
。 - 代码中的注释提供了一些说明和参考,可以帮助理解代码的功能和实现方法。
- 该代码使用了MATLAB中的函数feval,用于调用非线性状态方程的句柄
总体而言,该代码实现了Spherical-Radial Cubature变换(CKF-CT)用于非线性状态估计,通过Unscented变换(UT)对状态进行估计,并计算估计结果的方差和协方差。
七、PF:粒子滤波
粒子滤波(Particle Filter)是一种非参数化的贝叶斯滤波方法,可以用于对随机过程进行估计和预测。它通过使用一组带有权值的粒子(即样本)来表示随机过程的状态,从而实现对随机过程的估计和预测。
粒子滤波的主要思想是利用已知的先验概率分布和观测数据,通过迭代的方式更新粒子的权值和状态,从而得到后验概率分布。具体来说,粒子滤波包括以下步骤:
- 初始化:根据先验概率分布,生成一组初始粒子,并赋予相应的权值。
- 预测:根据已知的动力学模型,将每个粒子向前推进一个时间步长,得到下一时刻的粒子集合。
- 重采样:根据每个粒子的权值,对粒子进行重新采样,使得权值较大的粒子在采样中出现的概率更大。
- 输出:根据重采样后的粒子集合,可以得到后验概率分布的估计值。
粒子滤波在许多领域都有应用,例如目标跟踪、姿态估计、导航、语音识别、图像处理等。然而,粒子滤波也存在一些问题,例如粒子退化、噪声敏感等,需要进行进一步的研究和改进。
function [pf, Pxk] = pfupdate(pf, Zk, TimeMeasBoth)
% Particle filter updating for additive normal distribution process&measure noise.
%
% Prototype: [pf, Pxk] = pfupdate(pf, Zk, TimeMeasBoth)
% Inputs: pf - particle filter structure array
% Zk - measurement vector
% TimeMeasBoth - described as follows,
% TimeMeasBoth='T' (or nargin==1) for time updating only,
% TimeMeasBoth='M' for measurement updating only,
% TimeMeasBoth='B' (or nargin==2) for both time and
% measurement updating.
% Outputs: pf - particle filter structure array after time/meas updating
% Pxk - for full covariance (not diagnal)
%
% see also pfinit, kfupdate, ckf, ukf.% Copyright(c) 2009-2022, by Gongmin Yan, All rights reserved.
% Northwestern Polytechnical University, Xi An, P.R.China
% 06/04/2022if nargin==1;TimeMeasBoth = 'T';elseif nargin==2TimeMeasBoth = 'B';endif TimeMeasBoth=='T' || TimeMeasBoth=='B'sQ = chol(pf.Qk+eps*eye(pf.n));endif TimeMeasBoth=='M' || TimeMeasBoth=='B'vRv = zeros(pf.Npts, 1); invR = pf.Rk^-1;endfor k=1:pf.Nptsif TimeMeasBoth=='T' || TimeMeasBoth=='B'if isfield(pf,'fx')pf.particles(:,k) = feval(pf.fx, pf.particles(:,k), pf.tpara) + sQ*randn(pf.n,1);elsepf.particles(:,k) = pf.Phikk_1*pf.particles(:,k) + sQ*randn(pf.n,1);endendif TimeMeasBoth=='M' || TimeMeasBoth=='B'if isfield(pf,'hx')v = Zk - feval(pf.hx, pf.particles(:,k), pf.tpara)';elsev = Zk - pf.Hk*pf.particles(:,k);endvRv(k) = v'*invR*v;endendif TimeMeasBoth=='M' || TimeMeasBoth=='B'
% [vRv, idx] = sort(vRv); pf.particles = pf.particles(:,idx);weight = exp(-vRv/2);%/sqrt((2*pi)^pf.m*det(pf.Rk)); % Normal distributioncumw = cumsum(weight+0.01/pf.Npts); cumw = cumw/cumw(end);
% idx = interp1(cumw, (1:pf.Npts)', linspace(cumw(1),cumw(end),pf.Npts+10), 'nearest'); % resampling indexidx = interp1(cumw, (1:pf.Npts)', cumw(1)+(cumw(end)-cumw(1))*rand(pf.Npts+10,1), 'nearest'); % resampling indexpf.particles = pf.particles(:,idx(3:pf.Npts+2)); % myfig,hist(pf.particles(2,:));endpf.xk = mean(pf.particles,2);xk = pf.particles - repmat(pf.xk,1,pf.Npts);pf.Pxk = diag(sum(xk.^2,2)/pf.Npts);
% for k=1:pf.n
% pf.particles(k,:) = pf.xk(k)+sqrt(pf.Pxk(k,k))*randn(1,pf.Npts);
% endif nargout==2 % if using full matrix Pxkpf.Pxk = zeros(pf.n);for k=1:pf.Nptspf.Pxk = pf.Pxk + xk(:,k)*xk(:,k)';endpf.Pxk = pf.Pxk/pf.Npts;Pxk = pf.Pxk;end
function pf = pfinit(x0, P0, Qk, Rk, N)
% Particle filter structure initialization.
%
% Prototype: pf = pfinit(x0, P0, Qk, Rk, N)
% Inputs: x0,P0 - initial state & covariance;
% Qk,Rk - process & measure covariance
% N - particle number
% Output: pf - particle filter structure array
%
% see also pfupdate, kfinit.% Copyright(c) 2009-2022, by Gongmin Yan, All rights reserved.
% Northwestern Polytechnical University, Xi An, P.R.China
% 06/04/2022if size(P0,2)>1, P0 = diag(P0); endpf.n = length(x0); pf.m = length(Rk);for k=1:pf.npf.particles(k,:) = x0(k)+sqrt(P0(k))*randn(1,N);endpf.Npts = N;pf.Pxk = P0; pf.Qk = Qk; pf.Rk = Rk;
八、akfupdate:自适应滤波
这段代码是一个自适应卡尔曼滤波器的实现。下面是代码的功能解释:
- 函数
akfupdate
接受五个输入参数:kf
:一个包含卡尔曼滤波器结构信息的数组。yk
:一个测量向量。TimeMeasBoth
:一个描述时间更新和测量更新的标志字符,可以取以下三个值:'T'
:只进行时间更新。'M'
:只进行测量更新。'B'
:同时进行时间更新和测量更新。
kftype
:自适应卡尔曼滤波器的类型。para
:一些参数。
- 判断输入参数的数量,根据不同的标志字符执行相应的时间更新或测量更新。
- 如果
TimeMeasBoth
是'T'
,则执行时间更新:- 用
kf.Phikk_1
乘以kf.xk
,更新状态估计值kf.xk
。 - 用
kf.Phikk_1
乘以kf.Pxk
,再乘以kf.Phikk_1'
,并加上kf.Gammak * kf.Qk * kf.Gammak'
,更新状态估计误差协方差矩阵kf.Pxk
。
- 用
- 如果
TimeMeasBoth
是'M'
,则执行测量更新:- 保存当前的状态估计值和误差协方差矩阵到
kf.xkk_1
和kf.Pxkk_1
。
- 保存当前的状态估计值和误差协方差矩阵到
- 如果
TimeMeasBoth
是'B'
,则执行时间更新和测量更新:- 保存当前的状态估计值和误差协方差矩阵到
kf.xkk_1
和kf.Pxkk_1
。 - 计算
kf.Pxykk_1
,即当前估计值和测量值之间的协方差矩阵。 - 计算
kf.Py0
,即测量噪声的协方差矩阵乘以Hk
的转置。 - 计算残差
kf.rk
,即实际测量值减去预测的测量值。
- 保存当前的状态估计值和误差协方差矩阵到
- 根据
kftype
的类型执行不同的自适应滤波算法:- 如果
kftype
是字符串'KF'
或'MSHAKF'
,则根据提供的参数计算一些变量,如b
和s
。 - 如果
kftype
是数字2
,则执行 MCKF(Minimum Curvature Filter)算法,其中使用了一个参数sigma
。 - 如果
kftype
是数字3
,则执行 RSTKF(Residual Square Total Least Squares Filter)算法,其中使用了一个参数v
。 - 如果
kftype
是数字4
,则执行 SSMKF(Square Root Split-Operator Matrix Kalman Filter)算法。
- 如果
- 将更新后的状态估计值、状态估计误差协方差矩阵和其他相关信息存储到输入的结构数组
kf
中。 - 输出更新后的卡尔曼滤波器结构数组
kf
。
该代码实现了自适应卡尔曼滤波器的不同算法,并根据输入的标志字符选择相应的时间更新或测量更新操作。
shamn :Sage-Husa自适应滤波
function [Rk, beta, maxflag] = shamn(Rk, r2, Rmin, Rmax, beta, b, s)
% Sage-Husa adaptive measurement noise variance 'Rk'.
%
% Prototype: [Rk, beta] = shamn(Rk, r2, Rmin, Rmax, beta, b, s)
% Inputs: Rk - measurement noise variance
% r2 - =rk^2-Py0;
% Rmin,Rmax - min & max variance bound.
% beta,b - forgettiing factors
% s - if b==0, s is enlarge factor
% Output: Rk, beta - same as above
% maxflag - if r2(k)>Rmax(k) then set the max flag
%
% See also akfupdate.% Copyright(c) 2009-2022, by Gongmin Yan, All rights reserved.
% Northwestern Polytechnical University, Xi An, P.R.China
% 26/03/2022m = length(r2); maxflag = zeros(m,1);beta = beta./(beta+b);for k=1:mif b(k)==0,r2(k) = r2(k) / s(k)^2;if r2(k)<Rmin(k), Rk(k,k)=Rmin(k); else, Rk(k,k)=r2(k); endelseif r2(k)<Rmin(k), r2(k)=Rmin(k);elseif r2(k)>Rmax(k), r2(k)=Rmax(k); beta(k)=1; maxflag(k)=1; endRk(k,k) = (1-beta(k))*Rk(k,k) + beta(k)*r2(k);endend
这段代码是一个Sage-Husa自适应滤波器的实现。下面是代码的功能解释:
- 输入参数:
Rk
:测量噪声方差,一个列向量。r2
:Rk
的平方减去初始残差平方的平均值,也是一个列向量。Rmin
和Rmax
:分别是测量噪声方差的下限和上限,两个列向量。beta
和b
:两个列向量,分别表示遗忘因子和增益因子。s
:当b
等于0时使用的放大因子,一个列向量。
- 输出参数:
Rk
:更新后的测量噪声方差,一个列向量。beta
:更新后的遗忘因子,一个列向量。maxflag
:当r2(k)大于Rmax(k)时的最大标志,一个列向量。
- 代码逻辑:
- 首先,根据输入参数的长度,初始化一个长度为m的maxflag向量,全部元素设为0。
- 然后,将beta除以(beta+b),得到新的beta值。这是根据遗忘因子的公式进行的更新。
- 对于每个k值,进行以下操作:
- 如果b(k)等于0,表示使用增益因子s(k)对r2(k)进行放大。此时,如果r2(k)小于Rmin(k),则将Rk(k,k)设为Rmin(k);否则将Rk(k,k)设为r2(k)。
- 如果b(k)不等于0,表示使用遗忘因子beta(k)对Rk(k,k)进行更新。此时,如果r2(k)小于Rmin(k),则将r2(k)设为Rmin(k);如果r2(k)大于Rmax(k),则将r2(k)设为Rmax(k),并将beta(k)设为1,同时将maxflag(k)设为1。然后根据遗忘因子的公式,更新Rk(k,k)。
- 最后,更新完成后的Rk、beta和maxflag作为输出结果。
总体来说,这段代码实现了Sage-Husa自适应滤波器的核心功能,根据输入的参数和当前状态,自适应地调整测量噪声方差的值,并监控是否超出上限。
九、抗差等价权函数
igg1
function w = igg1(err, k0, k1)
% 'Institute of Geodesy & Geophysics' picewise method to calculate weight.
% Ref. IGG抗差估计在高程拟合中的应用研究_李广来,2021
%
% Prototype: gamma = igg1(err, k0, k1)
% Inputs: err - normalized measurement error
% k0, k1 - picewise points
% Outputs: w - weight
%
% Example:
% figure, err=-100:0.1:100; plot(err,igg1(err,3,10)); grid on
% figure, err=-100:0.1:100; plot(err,igg1(err,3,inf)); grid on
%
% See also igg3.% Copyright(c) 2009-2022, by Gongmin Yan, All rights reserved.
% Northwestern Polytechnical University, Xi An, P.R.China
% 20/06/2022if nargin==1, k0=1.0; k1=3.0; end % w = igg1(err)if nargin==2, k1=k0(2); k0=k0(1); end % w = igg1(err, k0k1)if k1<2*k0, k1=2*k0; enderr = abs(err); w = err;for k=1:length(err)if err(k)<=k0, w(k)=1;elseif err(k)>k1, w(k)=0;else, w(k)=k0/err(k); endend
这段代码是一个用于计算权重的函数,采用了Institute of Geodesy & Geophysics(地球测量与地球物理研究所)提出的一种分段函数方法。该函数接受两个输入参数:误差的归一化测量值(err)和两个分段点(k0和k1)。输出为权重值(w)。
代码首先检查输入参数的数量。如果只有一个输入参数(err),则将k0和k1分别设置为1.0和3.0。如果输入参数有两个(err和k0或k1),则将k1设置为k0的第二个元素,将k0设置为k0的第一个元素。
接下来,代码将误差值abs(err)赋给变量w。然后,通过一个循环遍历err中的每个元素。在循环中,根据误差值的大小,使用条件语句来计算相应的权重值。
如果误差值小于等于k0,权重值设为1.0;如果误差值大于k1,权重值设为0.0。对于介于k0和k1之间的误差值,权重值通过将k0除以误差值来计算。
最后,函数返回计算得到的权重值w。
代码中还提供了一些示例绘图语句,用于展示在不同参数设置下,权重如何随着误差值的变化而变化。
igg3
function w = igg3(err, k0, k1)
% 'Institute of Geodesy & Geophysics' picewise method to calculate weight.
% Ref. IGG抗差估计在高程拟合中的应用研究_李广来,2021
%
% Prototype: gamma = igg3(err, k0, k1)
% Inputs: err - normalized measurement error
% k0, k1 - picewise points
% Outputs: w - weight
%
% Example:
% figure, err=-10:0.1:10; plot(err,igg3(err,3,8)); grid on
%
% See also igg1.% Copyright(c) 2009-2022, by Gongmin Yan, All rights reserved.
% Northwestern Polytechnical University, Xi An, P.R.China
% 20/06/2022if nargin==1, k0=2.0; k1=6.0; end % w = igg3(err)if nargin==2, k1=k0(2); k0=k0(1); end % w = igg3(err, k0k1)if k1<2*k0, k1=2*k0; enderr = abs(err); w = err;for k=1:length(err)if err(k)<=k0, w(k)=1;elseif err(k)>k1, w(k)=0;else, w(k)=k0/err(k) * ((k1-err(k))/(k1-k0))^2; endend
这段代码是一个MATLAB函数,名为igg3
。它用于根据给定的测量误差和两个参数k0
和k1
计算权重。
函数的输入参数为:
err
:归一化测量误差的值。k0
:分段点之一。k1
:分段点之二。
函数的输出为:
w
:计算得到的权重。
该函数使用了’Institute of Geodesy & Geophysics’(大地测量与地球物理学研究所)的picewise方法来计算权重。该方法根据测量误差的大小,在两个分段点之间使用不同的计算方式来得到权重值。
函数首先检查输入参数的数量。如果只有一个输入参数err
,则默认设置k0
为2.0,k1
为6.0。根据不同的误差范围,使用不同的公式计算权重值:
- 如果误差小于等于
k0
,则权重为1。 - 如果误差大于
k1
,则权重为0。 - 否则,使用以下公式计算权重值:
w(k) = k0/err(k) * ((k1-err(k))/(k1-k0))^2
最后,返回计算得到的权重向量作为函数的输出结果。
这个函数主要用于在高程拟合中进行抗差估计,通过根据测量误差的大小调整权重来减小误差对拟合结果的影响。
十、数据融合
POSFusion
function psf = POSFusion(rf, xpf, rr, xpr, ratio)
% POS data fusion for forward and backward results.
%
% Prototype: psf = POSFusion(rf, xpf, rr, xpr, ratio)
% Inputs: rf - forward avp
% xpf - forward state estimation and covariance
% rr - backward avp
% xpr - backward state estimation and covariance
% ratio - the ratio of state estimation used to modify avp.
% Output: the fields in psf are
% rf, pf - avp & coveriance after fusion
% r1, p1 - forward avp & coveriance
% r2, p2 - backward avp & coveriance
%
% See also insupdate, kfupdate, POSSmooth, POSProcessing, posplot.% Copyright(c) 2009-2014, by Gongmin Yan, All rights reserved.
% Northwestern Polytechnical University, Xi An, P.R.China
% 22/01/2014if nargin<5ratio = 1;end[t, i1, i2] = intersect(rf(:,end), rr(:,end));n = size(xpf,2)-1; n2 = n/2;r1 = rf(i1,1:end-1); x1 = xpf(i1,1:n2); p1 = xpf(i1,n2+1:end-1);r2 = rr(i2,1:end-1); x2 = xpr(i2,1:n2); p2 = xpr(i2,n2+1:end-1);x1(:,1:9) = x1(:,1:9)*ratio; x2(:,1:9) = x2(:,1:9)*ratio; % ratio% common fusionr10 = [r1(:,1:9)-x1(:,1:9),r1(:,10:end)+x1(:,10:end)];r20 = [r2(:,1:9)-x2(:,1:9),r2(:,10:end)+x2(:,10:end)];
% r = ( r10.*p2 + r20.*p1 )./(p1+p2);
% p = p1.*p2./(p1+p2);[r, p] = fusion(r10, p1, r20, p2);% attitude fusionfor k=1:length(t)r10(k,1:3) = q2att(qdelphi(a2qua(r1(k,1:3)'),x1(k,1:3)'))';r20(k,1:3) = q2att(qdelphi(a2qua(r2(k,1:3)'),x2(k,1:3)'))';endr(:,1:3) = attfusion(r10(:,1:3), p1(:,1:3), r20(:,1:3), p2(:,1:3));rf = [r,t]; r1 = [r10,t]; r2 = [r20,t];pf = [p,t]; p1 = [p1,t]; p2 = [p2,t];rf(isnan(rf)) = 0;pf(isnan(pf)) = 0;psf = varpack(rf, pf, r1, p1, r2, p2);
这段代码是一个用于进行POS(位置和姿态)数据融合的函数。它接受五个输入参数:rf(正向AVP(伪距))、xpf(正向状态估计和协方差)、rr(反向AVP)、xpr(反向状态估计和协方差)和ratio(用于修改状态估计的比重)。该函数的输出是一个包含以下字段的结构体psf:
- rf和pf:经过融合后的AVP和协方差
- r1和p1:正向AVP和协方差
- r2和p2:反向AVP和协方差
代码的功能如下:
- 检查输入参数的数量,如果小于5个,则将ratio设置为1。
- 通过找到rf和rr在最后一个维度上的交集,确定共同的时刻t、索引i1和i2。
- 提取r1、x1、p1、r2、x2和p2,分别对应于正向和反向的AVP、状态估计和协方差。
- 根据ratio的值,对x1和x2的前9个字段进行比例调整。
- 执行融合操作,生成融合后的AVP和协方差r和p。这里使用了名为fusion的函数,具体的融合方法可能在该函数中实现。
- 将rf和pf中的NaN值替换为0。
- 将psf作为输出返回。
需要注意的是,这段代码中的一些函数(例如insupdate、kfupdate、POSSmooth、POSPlatform、posplot等)并没有在代码中给出实现,因此无法确定这些函数的具体功能。此外,该代码的实现可能依赖于其他未包含在此代码片段中的函数或库。
POSSmooth
function vpOut = POSSmooth(vp, gnss, nSec, isfig)
% POS data smooth via INS-VelPos & GNSS-VelPos.
%
% Prototype: vpOut = POSSmooth(vp, gnss, nSec, isfig)
% Inputs: vp - INS Vel&Pos input array = [vn,pos,t]
% gnss - GNSS Vel&Pos input array = [vn,pos,t]
% nSen - smooth span in second
% isfig - figure flag
% Output: vpOut - INS Vel&Pos output after smooth
%
% See also POSFusion, POSProcessing, smoothol, fusion.% Copyright(c) 2009-2021, by Gongmin Yan, All rights reserved.
% Northwestern Polytechnical University, Xi An, P.R.China
% 18/10/2021if nargin<4, isfig=1; endif nargin<3, nSec=10; enderr = gnss(:,end-1) - interp1(vp(:,end), vp(:,end-1), gnss(:,end));gnss = gnss(~isnan(err),:); err = gnss; errs = err;nSec = fix(nSec/(gnss(end,end)-gnss(1,end))*length(gnss)); % smooth pointsfor k=1:size(gnss,2)-1err(:,end-k) = gnss(:,end-k) - interp1(vp(:,end), vp(:,end-k), gnss(:,end));[~, errs(:,end-k)] = smoothol(err(:,end-k), nSec, 2, 0);endidx = ~isnan(interp1(errs(:,end), errs(:,end-k), vp(:,end)));vpOut = vp;for k=1:size(gnss,2)-1vpOut(idx,end-k) = vp(idx,end-k) + interp1(errs(:,end), errs(:,end-k), vp(idx,end), 'spline');endif isfig==1eth = earth(gnss(1,end-3:end-1)');myfigif size(gnss,2)==7, subplot(211); endplot(err(:,end), [err(:,end-3)*eth.RMh, err(:,end-2)*eth.clRNh, err(:,end-1)]); xygo('dP');plot(errs(:,end), [errs(:,end-3)*eth.RMh, errs(:,end-2)*eth.clRNh, errs(:,end-1)],'-.','linewidth',2);if size(gnss,2)==7subplot(212); plot(err(:,end), err(:,end-6:end-4)); xygo('V'); plot(errs(:,end), errs(:,end-6:end-4), '-.','linewidth',2)avpcmpplot(gnss, vpOut(:,end-6:end), 'vp');elseavpcmpplot(gnss, vpOut(:,end-3:end), 'p');endend
该函数是一个用于通过INS-VelPos和GNSS-VelPos数据进行位置平滑的函数。它的输入包括INS Vel&Pos数据数组vp、GNSS Vel&Pos数据数组gnss、平滑时间跨度nSec和一个图形标志isfig。它的输出是经过平滑处理后的INS Vel&Pos数据数组vpOut。
以下是该函数的具体实现步骤:
- 首先,根据输入参数判断是否指定了图形标志isfig和平滑时间跨度nSec。如果没有指定,则默认isfig为1,nSec为10。
- 接下来,计算GNSS数据和INS数据之间的误差err。这个误差是通过在INS数据的最后一个点和GNSS数据的最后一个点之间进行线性插值来计算的。然后将gnss数组中的NaN值替换为err数组,并将errs数组初始化为err数组。
- 根据平滑时间跨度nSec,计算要平滑的点的数量。这是通过将nSec转换为gnss数组中点的数量来完成的。
- 对于每个要平滑的点k,计算err(:,end-k)的值。这是通过在INS数据的最后一个点和gnss数据的前一个点之间进行线性插值来计算的。然后使用smoothol函数对err(:,end-k)进行平滑处理,得到errs(:,end-k)。
- 根据interp1函数计算出一个指示索引idx,它用于确定哪些点的位置需要进行平滑。
- 初始化vpOut数组为原始的vp数组。
- 对于每个要平滑的点k,根据errs(:,end-k)和vp(idx,end)的值,使用interp1函数进行插值计算,并将结果加到vpOut(idx,end-k)中,以得到平滑后的位置数据。
- 如果isfig等于1,则绘制平滑结果的图形。其中包括误差曲线和平滑后的位置数据曲线。
需要注意的是,该函数使用了外部库中的一些函数,例如interp1、smoothol和eth。这些函数可能需要在系统上进行相应的设置和配置才能正常运行。
POSProcessing
function [ps, psf] = POSProcessing(kf, ins, imu, vpGPS, fbstr, ifbstr)
% POS forward and backward data processing.
% States: phi(3), dvn(3), dpos(3), eb(3), db(3), lever(3), dT(1),
% dKg(9), dKa(6). (total states 6*3+1+9+6=34)
%
% Prototype: ps = POSProcessing(kf, ins, imu, posGPS, fbstr, ifbstr)
% Inputs: kf - Kalman filter structure array from 'kfinit'
% ins - SINS structure array from 'insinit'
% imu - SIMU data including [wm, vm, t]
% vpGPS - GPS velocity & position [lat, lon, heigth, tag, tSecond]
% or [vE, vN, vU, lat, lon, heigth, tag, tSecond], where
% 'tag' may be omitted.
% fbstr,ifbstr - Kalman filter feedback string indicator for
% forward and backward processing. if ifbstr=0 then stop
% backward processing
% Output: ps - a structure array, its fields are
% avp,xkpk - forward processing avp, state estimation and
% variance
% iavp,ixkpk - backward processing avp, state estimation and
% variance
%
% Example:
% psinstypedef(346);
% davp0 = avperrset([30;-30;30], [0.01;0.01;0.03], [0.01;0.01;0.03]);
% lever = [0.; 0; 0]; dT = 0.0; r0 = davp0(4:9)';
% imuerr = imuerrset(0.01,100,0.001,1, 0,0,0,0, [0;0;1000],0,[0;0;0;0;10;10],0);
% ins = insinit([att; pos], ts);
% kf = kfinit(ins, davp0, imuerr, lever, dT, r0);
% ps = POSProcessing(kf, ins, imu, vpGPS, 'avped', 'avp');
% psf = POSFusion(ps.avp, ps.xkpk, ps.iavp, ps.ixkpk);
% POSplot(psf);
%
% See also sinsgps, insupdate, kfupdate, POSFusion, posplot.% Copyright(c) 2009-2014, by Gongmin Yan, All rights reserved.
% Northwestern Polytechnical University, Xi An, P.R.China
% 22/01/2014, 08/02/2015if ~exist('fbstr','var'), fbstr = 'avp'; endif ~exist('ifbstr','var'), ifbstr = fbstr; endlen = length(imu); [lenGPS,col] = size(vpGPS);if col==4||col==7, vpGPS = [vpGPS(:,1:end-1),ones(lenGPS,1),vpGPS(:,end)]; end % add tagimugpssyn(imu(:,7), vpGPS(:,end));ts = ins.ts; nts = kf.nts; nn = round(nts/ts);dKga = zeros(15,1);%% forward navigation[avp, xkpk, zkrk] = prealloc(ceil(len/nn), kf.n+1, 2*kf.n+1, 2*kf.m+1); ki = 1;Qk = zeros(length(vpGPS), kf.n+1); Rk = zeros(length(vpGPS), 8); kki = 1; zk = zeros(size(kf.Hk,1),1);timebar(nn, len, 'SINS/GPS POS forward processing.');for k=1:nn:(len-nn+1)k1 = k+nn-1; wvm = imu(k:k1,1:6); t = imu(k1,7);ins = insupdate(ins, wvm); ins = inslever(ins);kf.Phikk_1 = kffk(ins);kf = kfupdate(kf);[kgps, dt] = imugpssyn(k, k1, 'F');if kgps>0 if vpGPS(kgps,end-1)>=1 % tag OKkf.Hk = kfhk(ins);if size(kf.Hk,1)==6zk = [ins.vnL-ins.an*dt; ins.posL-ins.Mpvvn*dt]-vpGPS(kgps,1:6)';elsezk = ins.posL-ins.Mpvvn*dt-vpGPS(kgps,1:3)';endkf = kfupdate(kf, zk, 'M');endQk(kki,:) = [diag(kf.Qk); t]';Rk(kki,:) = [diag(kf.Rk); kf.beta; t]'; kki = kki+1;end[kf, ins] = kffeedback(kf, ins, nts, fbstr);dKg = ins.Kg-eye(3); dKa = ins.Ka-eye(3);dKga = [dKg(:,1);dKg(:,2);dKg(:,3); dKa(:,1);dKa(2:3,2);dKa(3,3)];avp(ki,:) = [ins.avpL; ins.eb; ins.db; ins.lever; ins.tDelay; dKga; t]';xkpk(ki,:) = [kf.xk; diag(kf.Pxk); t]';zkrk(ki,:) = [zk; diag(kf.Rk); t]'; ki = ki+1;timebar;endavp(ki:end,:)=[]; xkpk(ki:end,:)=[]; zkrk(ki:end,:)=[]; Qk(kki:end,:)=[]; Rk(kki:end,:)=[];ps.avp = avp; ps.xkpk = xkpk; ps.zkrk = zkrk; ps.Qk = [sqrt(Qk(:,1:end-1)),Qk(:,end)]; ps.Rk = [sqrt(Rk(:,1:6)),Rk(:,7:8)];if ~ischar(ifbstr), return; end%% reverse navigation[ikf, iins, idx] = POSReverse(kf, ins);[iavp, ixkpk, izkrk] = prealloc(ceil(len/nn), kf.n+1, 2*kf.n+1, 2*kf.m+1); ki = 1;timebar(nn, len, 'SINS/GPS POS reverse processing.');for k=k1:-nn:(1+nn)ik1 = k-nn+1; wvm = imu(k:-1:ik1,1:6); wvm(:,1:3) = -wvm(:,1:3); t = imu(ik1-1,7);iins = insupdate(iins, wvm); iins = inslever(iins);ikf.Phikk_1 = kffk(iins);ikf = kfupdate(ikf);[kgps, dt] = imugpssyn(ik1, k, 'B');if kgps>0 if vpGPS(kgps,end-1)>=1 % tag OKikf.Hk = kfhk(iins);if size(ikf.Hk,1)==6zk = [iins.vnL-iins.an*dt; iins.posL-iins.Mpvvn*dt]-[-vpGPS(kgps,1:3),vpGPS(kgps,4:6)]';elsezk = iins.posL-iins.Mpvvn*dt-vpGPS(kgps,1:3)';endikf = kfupdate(ikf, zk, 'M');endend[ikf, iins] = kffeedback(ikf, iins, nts, ifbstr);dKg = iins.Kg-eye(3); dKa = iins.Ka-eye(3);dKga = [dKg(:,1);dKg(:,2);dKg(:,3); dKa(:,1);dKa(2:3,2);dKa(3,3)];iavp(ki,:) = [iins.avpL; iins.eb; iins.db; iins.lever; iins.tDelay; dKga; t]';ixkpk(ki,:) = [ikf.xk; diag(ikf.Pxk); t]';izkrk(ki,:) = [zk; diag(ikf.Rk); t]'; ki = ki+1;timebar;endiavp(ki:end,:)=[]; ixkpk(ki:end,:)=[]; izkrk(ki:end,:)=[]; iavp = flipud(iavp); ixkpk = flipud(ixkpk); izkrk = flipud(izkrk); % reverse inverse sequenceiavp(:,idx) = -iavp(:,idx); ixkpk(:,idx) = -ixkpk(:,idx);ps.iavp = iavp; ps.ixkpk = ixkpk; ps.izkrk = izkrk;if nargout==2psf = POSFusion(ps.avp, ps.xkpk, ps.iavp, ps.ixkpk);endfunction [ikf, iins, idx] = POSReverse(kf, ins)
% Copyright(c) 2009-2014, by Gongmin Yan, All rights reserved.
% Northwestern Polytechnical University, Xi An, P.R.China
% 22/01/2014iins = ins;iins.eth.wie = -iins.eth.wie;iins.vn = -iins.vn; iins.eb = -iins.eb; iins.tDelay = -iins.tDelay;ikf = kf;Pd=diag(ikf.Pxk); ikf.Pxk = diag([10*Pd(1:19);Pd(20:end)]);idx = [4:6,10:12,19]; % vn,eb,dT (dKg no reverse!)ikf.xk(idx) = -ikf.xk(idx); % !!!
POSProcessing_ifk_test
function POSProcessing_ifk_test()
% Copyright(c) 2009-2014, by Gongmin Yan, All rights reserved.
% Northwestern Polytechnical University, Xi An, P.R.China
% 27/12/2019
global glvts = 1; nts = 1; nn = 1; T = 5000; len = T/ts;psinstypedef(186);%% forward navigationts = 0.01;avp0 = avpset([1;10;30]*glv.deg, [100;200;10], [34;106;100]);davp0 = avperrset([60;-60;300], [0.1;0.1;0.3], [1;1;3]);ins = insinit(avpadderr(avp0,[[30;-30;30]; [1;1;3]; [1;1;3]]), ts); ins.nts = nts;Ft = etm(ins);iins = ins;iins.eth.wie = -iins.eth.wie;iins.vn = -iins.vn;iins.eth = ethupdate(iins.eth, iins.pos, iins.vn);iFt = etm(iins);xk = [davp0; [1;1;1]*glv.dph; [100;100;100]*glv.ug];xk1 = (eye(15)+Ft*ts)*xk;ixk = xk1; ixk([4:6,10:12]) = -ixk([4:6,10:12]);ixk1 = (eye(15)+iFt*ts)*ixk;ixk2 = (eye(15)-Ft*ts)*ixk;[ixk1,ixk2,xk]avp0 = avpset([1;10;30]*glv.deg, [0;0;0], [34;106;100]);davp0 = avperrset([1;-1;30], [0.1;0.1;0.3], [0.01;0.01;0.03]);imuerr = imuerrset(0, 0, 0, 0);imu = imustatic(avp0, ts, len, imuerr);ins = insinit(avpadderr(avp0,[[30;-30;30]; [0.1;0.1;0.3]; [0.01;0.01;0.03]]), ts); ins.nts = nts;kf = kfinit(ins, davp0, imuerr, [0;0;0], 0, [0;0;0]);kf.xk(1:9) = davp0;err = prealloc(ceil(len/nn), 19); ki = 1;timebar(nn, len, 'SINS/GPS POS forward processing.');for k=1:nn:(len-nn+1)k1 = k+nn-1; wvm = imu(k:k1,1:6); t = imu(k1,7);ins = insupdate(ins, wvm); ins.vn(3) = 0; kf.xk(6) = 0;kf.Phikk_1 = kffk(ins);kf = kfupdate(kf);err(ki,:) = [aa2phi(ins.att,avp0(1:3));(ins.avp(4:9)-avp0(4:9)); kf.xk(1:9); t]; ki = ki+1;timebar;enderr(ki:end,:)=[];%% reverse navigation[ikf, iins, idx] = POSReverse(kf, ins);ierr = prealloc(ceil(len/nn), 19); ki = 1;timebar(nn, len, 'SINS/GPS POS reverse processing.');for k=k1:-nn:(1+nn)ik1 = k-nn+1; wvm = imu(k:-1:ik1,1:6); wvm(:,1:3) = -wvm(:,1:3); t = imu(ik1-1,7);iins = insupdate(iins, wvm); iins.vn(3) = 0; ikf.xk(6) = 0;ikf.Phikk_1 = kffk(iins);ikf = kfupdate(ikf);ierr(ki,:) = [aa2phi(iins.att,avp0(1:3));(iins.avp(4:9)-avp0(4:9)); ikf.xk(1:9); t-0.5]; ki = ki+1;timebar;endierr(ki:end,:)=[];
% ierr = flipud(ierr); ierr(:,[4:6]) = -ierr(:,[4:6]); ierr(:,9+[4:6]) = -ierr(:,9+[4:6]);err = [err;ierr];errr = avpcmpplot(err(:,[1:9,end]), err(:,10:end));
% avpcmpplot(ierr(:,[1:9,end]), ierr(:,10:end));function [ikf, iins, idx] = POSReverse(kf, ins)
% Copyright(c) 2009-2014, by Gongmin Yan, All rights reserved.
% Northwestern Polytechnical University, Xi An, P.R.China
% 22/01/2014iins = ins;iins.eth.wie = -iins.eth.wie;iins.vn = -iins.vn; iins.eb = -iins.eb; iins.tDelay = -iins.tDelay;ikf = kf;ikf.Pxk = 10*diag(diag(ikf.Pxk));idx = [4:6,10:12]; % vn,eb,dT,dvn (dKg no reverse!)ikf.xk(idx) = -ikf.xk(idx); % !!!
十一:模拟
htwn:产生高斯白噪声
function [wn, s] = htwn(wp, s, len)
% Generate Heavy-tailed white noise.
%
% Prototype: wn = htwn(wp, enlarge, len)
% Inputs: wp - with probability
% s - std enlarge with probability 'wp'
% len - element number
% Outputs: wn - noise output
% s - enlarge number for each wn
%
% Example1:
% figure, plot(htwn(0.01, 100, 1000)); grid on
%
% Example2:
% x=-30:0.1:30; n=1000; figure, plot(x,histc([randn(10000,1),htwn(0.3,10,10000)],x)/n); grid on
%
% See also rstd.% Copyright(c) 2009-2022, by Gongmin Yan, All rights reserved.
% Northwestern Polytechnical University, Xi An, P.R.China
% 01/03/2022if length(wp)>1 % [wn, s] = htwn([wp1;wp2;...], [s1;s2;...], [len1;len2;...]);s1 = s;wn = []; s = [];for k=1:length(wp)[wnk,sk] = htwn(wp(k), s1(k), len(k));wn = [wn; wnk]; s = [s; sk];endreturn;endif nargin<3, len=1; endif nargin<2, s=100; endif nargin<1, wp=0.01; endif wp>1, len=wp; wp=0.01; end % wn = htwn(len)wn = randn(len,1);r01 = rand(len,1);idx = r01 < wp;wn(idx) = wn(idx)*s;s(idx,1) = s; s(~idx,1) = 1;
这段代码是一个用于生成heavy-tailed白噪声的函数。下面是代码的功能解释:
- 函数的输入参数包括:
wp
:一个表示概率的向量或标量,用于确定是否对生成的噪声进行放大。s
:一个表示放大数量的向量或标量,用于对生成的噪声进行放大。len
:一个表示生成噪声的元素数量的向量或标量。
- 函数的输出包括:
wn
:生成的噪声的向量或矩阵,其中包含了heavy-tailed分布的随机值。s
:每个噪声元素的放大数量。
- 代码中的主要逻辑如下:
- 首先,通过判断输入参数的长度,支持同时生成多个噪声序列。如果
wp
或s
或len
的长度大于1,则进入循环,逐个生成噪声序列并返回结果。 - 然后,根据输入参数检查是否给出了足够的参数。如果没有给出
len
参数,默认为1;如果没有给出s
参数,默认为100;如果没有给出wp
参数,默认为0.01。 - 接下来,生成一个长度为
len
的随机噪声向量wn
,其中包含了符合标准正态分布的随机值。 - 然后,生成一个长度与
wn
相同的随机向量r01
,其中的值在0和1之间。 - 使用生成的随机向量
r01
和一个阈值wp
,确定哪些噪声元素需要进行放大。将满足概率小于wp
的元素乘以放大数量s
,并更新相应的放大数量s
。
- 首先,通过判断输入参数的长度,支持同时生成多个噪声序列。如果
- 最后,将生成的噪声向量和放大数量返回作为函数的输出。
总体而言,这段代码通过使用随机生成和放大的方法来生成具有heavy-tailed分布特征的噪声数据。
vfbfx:模拟垂直下落物体的状态方程
function [X1, Phik, D] = vfbfx(X0, tpara)
% Vertically falling body state equation f(x).
% Ref: Athans, M. 'Suboptimal state estimation for continuous-time nonlinear systems
% from discrete noisy measurements'. IEEE Transactions on Automatic Control,1968.
% [x1,x2,x3]: altitude,velocity,ballistic-parameter, state equations:
% dx1/dt = -x2
% dx2/dt = g-exp(-gamma*x1)*x2^2*x3
% dx3/dt = 0
%
% See also vfbhx.% Copyright(c) 2009-2022, by Gongmin Yan, All rights reserved.
% Northwestern Polytechnical University, Xi An, P.R.China
% 08/08/2022% Phik = eye(3) + [0,1,0; 0,0,1; 0,0,0]*tpara.ts; D{1}=zeros(3); D{2}=zeros(3); D{3}=zeros(3); % linear model test% X1 = Phik*X0;% return; % for linear testgamma = tpara.gamma; g = tpara.g; Ts = tpara.Ts;x1 = X0(1); x2 = X0(2); x3 = X0(3);%% X0->X1egx1 = exp(-gamma*x1);X1 = [ x1 - x2*Ts; % Euler1 discretizationx2 + (g-egx1*x2^2*x3)*Ts;x3 ];
% k1 = [-X0(2); g-exp(-gamma*X0(1))*X0(2)^2*X0(3); 0]; X01 = X0+k1*Ts/2; % RK4
% k2 = [-X01(2); g-exp(-gamma*X01(1))*X01(2)^2*X01(3); 0]; X02 = X0+k2*Ts/2;
% k3 = [-X02(2); g-exp(-gamma*X02(1))*X02(2)^2*X02(3); 0]; X03 = X0+k3*Ts;
% k4 = [-X03(2); g-exp(-gamma*X03(1))*X03(2)^2*X03(3); 0];
% X1 = X0 + Ts/6*(k1+2*(k2+k3)+k4);%% Jacobian Phikif nargout>1Phik = [ 0, -1, 0;[gamma*x2*x3, -2*x3, -x2]*egx1*x2;0, 0, 0 ];Phik = eye(size(Phik)) + Phik*Ts; % Phi = expm(Phi*ts);end%% Hessian Dif nargout>2D{1} = zeros(3);D{2} = [ [-gamma*x2*x3, 2*x3, x2]*gamma*egx1*x2;0, -2*egx1*x3, -2*egx1*x20, 0, 0 ]*Ts;D{2}(2,1)=D{2}(1,2); D{2}(3,1)=D{2}(1,3); D{2}(3,2)=D{2}(2,3); % symmetricD{3} = zeros(3);end
这段代码是一个用于模拟垂直下落物体的状态方程的函数。它接受一个初始状态向量X0和一个包含参数的向量tparana作为输入,并返回预测的状态向量X1、雅可比矩阵Phik和海森矩阵D。
下面是代码的功能解释:
- 定义参数:
gamma
:阻力系数g
:重力加速度Ts
:离散时间步长
- 初始化变量: 从X0中提取x1、x2和x3的值,分别存储在这些变量中。
- 预测状态向量X1: 使用Euler离散化方法对状态方程进行预测,得到下一个时刻的状态向量X1。
- 计算雅可比矩阵Phik: 如果函数有超过一个输出参数,则计算雅可比矩阵Phik。Phik用于线性化状态方程,其在数值上近似于状态方程的导数。
- 计算海森矩阵D: 如果函数有超过两个输出参数,则计算海森矩阵D。D是用于线性化状态方程的雅可比矩阵的导数,即D是对状态方程的二阶导数。
在这段代码中,使用了Euler离散化方法对状态方程进行预测,并计算了状态方程的雅可比矩阵和海森矩阵。这些矩阵对于进行状态估计和参数辨识等任务非常重要。
vfbhx:模拟垂直下落的物体的测量方程
function [Z, Hk, D] = vfbhx(X, tpara, rk)
% Vertically falling body measurement equation h(x).
% Ref: Athans, M. 'Suboptimal state estimation for continuous-time nonlinear systems
% from discrete noisy measurements'. IEEE Transactions on Automatic Control,1968.
% [x1,x2,x3]: altitude,velocity,ballistic-parameter, measurement equation:
% Z = sqrt(M^2+(x3-H)^2) + V
%
% See also vfbfx.% Copyright(c) 2009-2022, by Gongmin Yan, All rights reserved.
% Northwestern Polytechnical University, Xi An, P.R.China
% 08/08/2022% Z = X(1); Hk = [1, 0, 0]; D{1} = zeros(3); % linear model test% if nargin==3, Z=Z+V*randn(1); end% return; % for linear testM = tpara.M; H = tpara.H;%% ZZ = sqrt(M^2+(X(1)-H)^2);%% Jacobian Hkif nargout>1, Hk = [(X(1)-H)/Z, 0, 0]; end%% Hessian Dif nargout>2, D{1} = [M^2/Z^3, 0, 0; 0, 0, 0; 0, 0, 0]; end%% Measurement noiseif nargin==3, Z=Z+rk*randn(1); end
这段代码是一个MATLAB函数,用于计算垂直下落的物体的测量方程。下面是代码的功能解释:
- 函数名:
vfbhx
,它接受三个输入参数:X
,tpara
和rk
。 X
是一个列向量,包含了三个元素:高度、速度和弹道参数。tpara
是一个包含两个元素的向量,第一个元素是质量参数M
,第二个元素是参考高度H
。rk
是测量噪声的倍数,用于模拟真实测量中的噪声。- 代码开头的注释提供了一些参考信息,包括参考文献和版权声明。
- 代码的第一个注释行是一个测试用的线性模型,如果函数有四个输入参数(即
nargin==3
),则在计算结果之前向Z
中添加一个乘以V
的随机噪声。 Z
的计算是根据测量方程进行的,使用了高度和弹道参数,并考虑了距离的影响。- 如果函数需要输出雅可比矩阵
Hk
(nargout==2
),则根据测量方程计算出雅可比矩阵的值。 - 如果函数需要输出海森矩阵
D
(nargout==3
),则根据测量方程计算出海森矩阵的元素值。 - 最后,如果输入参数中包含第三个元素
rk
,则在计算结果之前向Z
中添加一个乘以rk
的随机噪声,以模拟测量中的噪声。 - 函数的最后一行是可选的,它用于在命令行中显示函数的输出结果。
总结来说,这段代码实现了一个用于计算垂直下落的物体的测量方程的函数。它根据输入的高度、速度、弹道参数和测量噪声,计算出测量结果,并可以输出雅可比矩阵和海森矩阵(如果需要)。
方法对状态方程进行预测,并计算了状态方程的雅可比矩阵和海森矩阵。这些矩阵对于进行状态估计和参数辨识等任务非常重要。
vfbhx:模拟垂直下落的物体的测量方程
function [Z, Hk, D] = vfbhx(X, tpara, rk)
% Vertically falling body measurement equation h(x).
% Ref: Athans, M. 'Suboptimal state estimation for continuous-time nonlinear systems
% from discrete noisy measurements'. IEEE Transactions on Automatic Control,1968.
% [x1,x2,x3]: altitude,velocity,ballistic-parameter, measurement equation:
% Z = sqrt(M^2+(x3-H)^2) + V
%
% See also vfbfx.% Copyright(c) 2009-2022, by Gongmin Yan, All rights reserved.
% Northwestern Polytechnical University, Xi An, P.R.China
% 08/08/2022% Z = X(1); Hk = [1, 0, 0]; D{1} = zeros(3); % linear model test% if nargin==3, Z=Z+V*randn(1); end% return; % for linear testM = tpara.M; H = tpara.H;%% ZZ = sqrt(M^2+(X(1)-H)^2);%% Jacobian Hkif nargout>1, Hk = [(X(1)-H)/Z, 0, 0]; end%% Hessian Dif nargout>2, D{1} = [M^2/Z^3, 0, 0; 0, 0, 0; 0, 0, 0]; end%% Measurement noiseif nargin==3, Z=Z+rk*randn(1); end
这段代码是一个MATLAB函数,用于计算垂直下落的物体的测量方程。下面是代码的功能解释:
- 函数名:
vfbhx
,它接受三个输入参数:X
,tpara
和rk
。 X
是一个列向量,包含了三个元素:高度、速度和弹道参数。tpara
是一个包含两个元素的向量,第一个元素是质量参数M
,第二个元素是参考高度H
。rk
是测量噪声的倍数,用于模拟真实测量中的噪声。- 代码开头的注释提供了一些参考信息,包括参考文献和版权声明。
- 代码的第一个注释行是一个测试用的线性模型,如果函数有四个输入参数(即
nargin==3
),则在计算结果之前向Z
中添加一个乘以V
的随机噪声。 Z
的计算是根据测量方程进行的,使用了高度和弹道参数,并考虑了距离的影响。- 如果函数需要输出雅可比矩阵
Hk
(nargout==2
),则根据测量方程计算出雅可比矩阵的值。 - 如果函数需要输出海森矩阵
D
(nargout==3
),则根据测量方程计算出海森矩阵的元素值。 - 最后,如果输入参数中包含第三个元素
rk
,则在计算结果之前向Z
中添加一个乘以rk
的随机噪声,以模拟测量中的噪声。 - 函数的最后一行是可选的,它用于在命令行中显示函数的输出结果。
总结来说,这段代码实现了一个用于计算垂直下落的物体的测量方程的函数。它根据输入的高度、速度、弹道参数和测量噪声,计算出测量结果,并可以输出雅可比矩阵和海森矩阵(如果需要)。
相关文章:

PSINS工具箱学习(三)让AI解释PSINS中的各种卡尔曼滤波函数
原始 Markdown文档、Visio流程图、XMind思维导图见:https://github.com/LiZhengXiao99/Navigation-Learning PSINS 中的 Kalman 滤波代码都在百行以内,没调用什么函数,而且通用性很强,拿去让 AI 解释,效果挺好。 文章目…...

多边形碰撞检测算法
1、AABB碰撞检测算法 AABB碰撞检测指轴对齐碰撞箱(Axis-aligned Bounding Box),是分别从x轴向和y轴向进行碰撞检测的算法。即对于需要检测的物体A和物体B我们需要将其用A盒和B盒套起来,判断A盒和B盒在x轴向和y轴向是否发生碰撞,只有在x轴向和…...

【C/C++笔试练习】——printf在使用%的注意事项、for循环语句的三个条件、运算符优先级、删除公共字符
文章目录 C/C笔试练习1.%符号在printf用作格式说明符的注意事项(1)输出%5.3s(2)判断%中小数点含义 2.for循环语句的三个条件(3)判断循环次数(4)判断循环次数 3.运算符优先级…...

Linux部署elk日志监控系统
目录 一、简介 二、部署elasticsearch 2.1 安装jdk11(jdk版本>11) 2.2 下载安装包 2.3 授权elk用户 2.4 配置elasticsearch.yml 2.5 启动elasticsearch 三、部署logstash 3.1 启动测试 3.2 可能出现的报错 3.3 指定配置文件启动logstash 3.4 安装El…...

LINUX -SQL笔记(自学用)
1.安装 sudo apt-get install mysql-server sudo mysql -u root -p2.关系模型 在关系数据库中,一张表中的每一行数据被称为一条记录。一条记录就是由多个字段组成的。 每一条记录都包含若干定义好的字段。同一个表的所有记录都有相同的字段定义。 对于关系表&#…...

【Spark】win10配置IDEA、saprk、hadoop和scala
终于,要对并行计算下手了哈哈哈。 一直讲大数据大数据,我单次数据处理量大概在1t上下,是过亿级的轨迹数据。 用python调用multiprogress编写的代码,用多线程也要一个多月跑完。 我对这个效率不太满意,希望能快一点再快…...

MQTT 协议概要
01 MQTT协议 MQTT(消息队列遥测传输) 是基于 TCP/IP 协议栈而构建的支持在各方之间异步通信的消息协议。MQTT在空间和时间上将消息发送者与接收者分离,因此可以在不可靠的网络环境中进行扩展。虽然叫做消息队列遥测传输,但它与消息…...

向量数据库X云计算驱动大模型落地电商行业,Zilliz联合AWS探索并贡献成熟解决方案
近日,由Zilliz 联合亚马逊云科技举办的【向量数据库 X 云计算 驱动大模型落地电商行业】活动在上海落幕,获得业内专业人士的广泛好评。 众所周知,大模型技术的发展正加速对千行万业的改革和重塑,向量数据库作为大模型的海量记忆体、云计算作为大模型的大算力平台,是大模型…...

【vue2】解决Vuex刷新页面数据丢失的问题
最近写vue2 项目需要用到vuex, 但遇到一个问题,存进store里的数据刷新就丢失了,于是乎百度解决。将自己的感受与解决方法记录下来。 数据丢失的原因 vuex存储的数据只是在页面中,相当于全局变量,页面刷新的时候vuex里的数据会重…...

小皮面板配置Xdebug,调试单个php文件
小皮面板配置Xdebug 首先下载phpstrom,和小皮面板 打开小皮面板,选中好要使用的php版本 然后点击【管理】> 【php扩展】> 【xdebug】 然后打开选中好版本的php位置 D:\Program_Files\phpstudy_pro\Extensions\php\php7.4.3nts打开php.ini文件…...

版本控制系统:Perforce Helix Core -2023
Perforce Helix Core是领先的版本控制系统,适用于需要加速大规模创新的团队。存储并跟踪您所有数字资产的更改,从源代码到二进制再到IP。连接您的团队,让他们更快地行动,更好地构建。 通过 Perforce 版本控制加速创新 Perforce H…...

回归预测 | Matlab实现基于MIC-BP最大互信息系数数据特征选择算法结合BP神经网络的数据回归预测
回归预测 | Matlab实现基于MIC-BP最大互信息系数数据特征选择算法结合BP神经网络的数据回归预测 目录 回归预测 | Matlab实现基于MIC-BP最大互信息系数数据特征选择算法结合BP神经网络的数据回归预测效果一览基本介绍研究内容程序设计参考资料 效果一览 基本介绍 Matlab实现基于…...

Hive-命令行CDH访问开启kerberos的hive
1.通过hive用户访问 切换用户为hive [rootslave conf]# su - hive 上一次登录:五 4月 12 13:59:19 CST 2019pts/1 上 [hiveslave ~]$命令行直接输入hive就可以进入hive [hiveslave ~]$ hive log4j:WARN No such property [maxFileSize] in org.apache.log4j.Dail…...

手机能搜到某个wifi,电脑搜不到解决方法(也许有用)
方法一:更新驱动 下载驱动大师、驱动精灵等等驱动软件,更新网卡驱动 方法二 按 win 键,打开菜单 搜索 查看网络连接(win11版本是搜这个名字) 点击打开是这样式的 然后对 WLAN右击->属性->配置->高级 这…...

Java-day18(网络编程)
网络编程 1.概述 Java提供跨平台的网络类库,可以实现无痛的网络连接,程序员面对的是一个统一的网络编程环境 网络编程的目的:直接或间接地通过网络协议与其他计算机进行通信 网络编程的两个主要问题: 1.如何准确定位网络上一台…...

Java多线程编程-栅栏CyclicBarrier实例
前言 本文是基于《Java多线程编程实战指南-核心篇》第五章个人理解,源码是摘抄作者的源码,源码会加上自己的理解。读书笔记目前笔者正在更新如下, 《Java多线程编程实战指南-核心篇》,《How Tomcat Works》,再到《spr…...

【100天精通Python】Day67:Python可视化_Matplotlib 绘制动画,2D、3D 动画 示例+代码
1 绘制2D动画(animation) Matplotlib是一个Python绘图库,它提供了丰富的绘图功能,包括绘制动画。要绘制动画,Matplotlib提供了FuncAnimation类,允许您创建基于函数的动画。下面是一个详细的Matplotlib动画示…...

变量、常量以及与其他语言的差异 - Go语言从入门到实战
知识点 源码文件以_test结尾:xxx_test.go测试方法名以Test开头:func TestXXX(t *testing.T){…} 利用单元测试来写代码段,保存之后会自动运行程序返回结果,可以快速实践得到反馈。 编写测试程序 接下来练习一下,怎…...

Android 编译插桩操纵字节码
本文讲解如何编译插桩操纵字节码。 就使用 ASM 来实现简单的编译插桩效果,通过插桩实现在每一个 Activity 打开时输出相应的 log 日志。实现思路 过程主要包含两步: 1、遍历项目中所有的 .class 文件 如何找到项目中编译生成的所有 .class 文件&#…...

云原生的简单理解
一、何谓云原生? 一种构建和运行应用软件的方法 应用程序从设计之初即考虑到云的环境,原生为云而设计,在云上以最佳姿势运行,充分利用和发挥云平台的弹性分布式优势。 二、包括以下四个要素 采用容器化部署:实现云平…...

AVL Cruise 2020.1 安装教程
文章目录 安装包安装破解 安装包 链接:https://pan.baidu.com/s/1GxbeDj_SyvKFyPeTsstvTQ?pwd6666 提取码:6666 安装 安装文件: 双击setup.exe: 一直netx,中间要修改两次路径,第一次是安装位置…...

数组07-滑动窗口、HashMap
LeetCode——904. 水果成篮 你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示,其中 fruits[i] 是第 i 棵树上的水果 种类 。 你想要尽可能多地收集水果。然而,农场的主人设定了一些严格的规矩,…...

【C++杂货店】类和对象(上)
【C杂货店】类和对象(上) 一、面向过程和面向对象初步认识二、类的引入三、类的定义四、类的访问限定符及封装4.1 访问限定符4.2 封装 五、类的作用域六、类的实例化七、类对象模型7.1 类对象的存储规则7.2 例题7.3结构体内存对齐规则 八、this指针8.2 t…...

K8S笔记
...

MySQL关于日期函数的使用-笔记
韩老师笔记 select current_time select CURRENT_DATE create table mes ( id int, content VARCHAR(255), send_time DATETIME ) select * from mes; insert into mes values(1,北京,CURRENT_DATE) insert into mes (id,send_time) values(2,CURRENT_TIME) insert into mes v…...

【postgresql 】 ERROR: “name“ is not supported as an alias
org.postgresql.util.PSQLException: ERROR: "name" is not supported as an alias 错误:不支持将“name”作为别名 SELECT real_name name FROM doc_user 加上 在关键词上加上 “” 示例: SELECT real_name "name" FROM do…...

都用HTTPS了,还能被查出浏览记录?
最近,群里一个刚入职的小伙因为用公司电脑访问奇怪的网站,被约谈了。他很困惑 —— 访问的都是HTTPS的网站,公司咋知道他访问了啥? 实际上,由于网络通信有很多层,即使加密通信,仍有很多途径暴露…...

vi配置文件.vimrc内容示例
1、.vimrc配置文件介绍 (1).vimrc是vi编辑器的配置文件,里面可以对vi编译器做个性化配置; (2).vimrc在用户目录下,每个用户有一个,类似于.bashrc文件,将下面的配置文件内…...

MacOS上的Pip和Python升级指南
在MacOS系统上,保持Pip和Python版本的最新状态对于顺利进行Python开发至关重要。通过升级Pip和Python,你可以享受到最新的功能、修复的bug以及提升的开发效率。本文将为你提供在MacOS上升级Pip和Python的详细指南,助你打造更强大的开发环境。…...

VB6.0实现修改EXE程序的图标
当你给一家公司做技术支持的时候,需求各种各样的,其中今天遇到就是要修改某个程序的图标,代码实现如下。 // q1016058890 群 214016721 //注 意:这个方法貌似只对有些EXE文件有效,这不是万能的方法,此…...