-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathekf_update.m
57 lines (44 loc) · 2.07 KB
/
ekf_update.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
function [X, Cx, a, Ca] = ekf_update(X, Z, Cx, D, a, Ca, Q, F, H)
% Prediction for state vector and covariance:
X = F*X;
Cx = F * Cx * F.' + Q;
avec = [a, (D(1,1))^(1/2), (D(2,2))^(1/2)].';
Ca = eye(3) * Ca * eye(3)';
if sum(sum(~isnan(Z))) > 0
for j = 1:sum(~isnan(Z(1,:)),2)
%R = calcrotmat(X);
R = [cos(avec(1)), -sin(avec(1)); sin(avec(1)), cos(avec(1))];
Drot = R * D * R.';
Ex = H*X;
% Compute conventional Kalman covariance matrices:
Cxz = Cx*H.';
Czz = H*Cx*H.' + Drot;
% Correction based on observation:
X = X + Cxz*(Czz)^(-1)*(Z(:,j)-Ex);
Cx = Cx - Cxz*(Czz)^(-1)*Cxz.';
Cx = (Cx + Cx.')/2;
% Compute pseudo-measurement and expectation:
%Ztilde = kron((Z - X(1:2)).',(Z - X(1:2)).');
Zshift = Z(:,j) - Ex;
Ztilde = [eye(2), zeros(2,2); 0 0 0 1]*kron(Zshift,Zshift);
%Ztilde = [(Z(1,:) - X(1)).^2; (Z(2,:) - X(2)).^2; (Z(1,:) - X(1)) .* (Z(2,:) - X(2))];
%expect_Ztilde = [Czz(1,1), Czz(2,2), Czz(1,2)].';
expect_Ztilde = [Czz(1,1); Czz(1,2); Czz(2,2)];
% Compute extended covariance matrices:
elem1 = 3*(Czz(1,1))^2; elem2 = 3*(Czz(2,2))^2;
elem3 = Czz(1,1) * Czz(2,2) + 2*(Czz(1,2))^2; elem4 = 3*Czz(1,1)*Czz(1,2);
elem5 = 3*Czz(2,2)*Czz(1,2);
Czztilde = [elem1, elem4, elem3; elem4, elem3, elem5; elem3, elem5, elem2];
expect_Ja = [-sin(2*avec(1)), (cos(avec(1)))^2, (sin(avec(1)))^2; cos(2*avec(1)), sin(2*avec(1)), -sin(2*avec(1)); sin(2*avec(1)), (sin(avec(1)))^2, (cos(avec(1)))^2];
expect_Ja = expect_Ja * diag([D(1,1)/100 - D(2,2)/100, 2*(D(1,1))^(1/2)/100, 2*(D(2,2))^(1/2)/100]);
Caztilde = Ca * expect_Ja.';
% Correction based on observation:
avec = avec + Caztilde*(Czztilde)^(-1)*(Ztilde-expect_Ztilde);
avec(1) = mod(avec(1), 2*pi);
Ca = Ca - Caztilde * (Czztilde)^(-1) * Caztilde.';
Ca = (Ca + Ca')/2;
end
a = avec(1);
%a = mod(avec(1), 2*pi);
end
end