-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathParticle.m
103 lines (81 loc) · 3.06 KB
/
Particle.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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
classdef Particle
properties
x; % x position
y; % y position
w; % weight
% landmarks
rgbPos; % landmarks positions, dim:(3,2); ex: [Rx Ry; Gx Gy; Bx By]
rgbCov; % x positions' covariance, dim:(3,3);
singularPoint;
numUpdates; % number of updates
end
methods
function obj = Particle(x_,y_,varargin)
obj.x = x_;
obj.y = y_;
obj.singularPoint = 1e-6;
obj.numUpdates = 0;
if nargin == 3
obj.w = varargin{1};
elseif nargin == 5
obj.w = varargin{1};
obj.rgbPos = varargin{2};
obj.rgbCov = varargin{3};
end
end
function obj = move(obj, dx, dy)
obj.x = obj.x + dx + (rand*0.06-0.03);
obj.y = obj.y + dy + (rand*0.06-0.03);
end
function obj = addNewLm(obj, U, Z, lmY)
% z: distance between the particle and the lm
dX2 = Z.^2 - (lmY-obj.y).^2;
im = dX2 < 0;
dX2(dX2<0) = 0;
if obj.numUpdates == 1
obj.rgbPos(:,1) = sqrt(dX2);
obj.rgbCov = diag((0.2+1.0*im));
end
% lmX = obj.x + sign*sqrt(dX2);
% obj.rgbPos(:,1) = lmX;
% obj.rgbCov = (0.5+1.0*im)*diag([1,1,1]);
end
function obj = updateLandmark(obj, Z, R)
% update by EKF
P = obj.rgbCov; % covariance matrix
[H,dx,dy] = obj.computeJacobian(); % H: jacobian of h(x_k)
Qz = H*P*H' + R; % Qz: measurement covariance; R: measurement noise
if det(Qz) < obj.singularPoint
QzInv = pinv(Qz);
else
QzInv = inv(Qz);
end
K = P*H'*QzInv; % Kalman Gain
Z_hat = sqrt(dx.^2 + dy.^2);
dZ = Z - Z_hat;
% update the states and the covariance
obj.rgbPos(:,1) = obj.rgbPos(:,1) + K*dZ;
obj.rgbCov = (eye(3) - K*H)*P;
end
function [H, dx, dy] = computeJacobian(obj)
% Compute the H matrix in EKF
dx = obj.rgbPos(:,1) - obj.x;
dy = obj.rgbPos(:,2) - obj.y;
H = diag(dx./sqrt(dx.^2+dy.^2)); % H: jacobian of h(x_k)
end
function w = computeWeight(obj, Z, R)
P = obj.rgbCov; % covariance matrix
[H, dx, dy] = obj.computeJacobian(); % H: jacobian of h(x_k)
Qz = H*P*H' + R; % Qz: measurement covariance; R: measurement noise
if det(Qz) < obj.singularPoint
% singular
w = 1.0;
return;
end
Z_hat = sqrt(dx.^2 + dy.^2);
dZ = Z - Z_hat;
w = exp(-0.5*dZ'*(Qz\dZ)) / (2*pi*sqrt(det(Qz)));
return;
end
end
end