-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathlocalize2d_shimshoni02_algebraic.m
74 lines (70 loc) · 2.76 KB
/
localize2d_shimshoni02_algebraic.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
function [pose, valid] = localize2d_shimshoni02_algebraic(data, map)
%LOCALIZE2D_SHIMSHONI02_ALGEBRAIC Estimate 2D position and orientation using bearing
% angles measured from landmarks (N >= 3)
%
% [POSE, VALID] = LOCALIZE2D_SHIMSHONI02_ALGEBRAIC(DATA, MAP)
% (matrix) DATA : The measured bearing angles from landmarks (Nx2 matrix)
% (matrix) MAP : The corresponding landmark map (Nx6 matrix)
% (matrix) POSE : The estimated pose (1x6 matrix)
% (matrix) VALID: A flag to represent validity of the estimated pose (1x6 matrix)
%
% Note: Please refer to the command, OBSERVE_BEARING, for the convention of DATA,
% MAP, and POSE.
%
% Note: A flag for validity, VALID, is 1x6 matrix whose elements correspond to each
% element of POSE. Since this algorithm estimates 2D position and orientation,
% the expected VALID is [true, true, false, false, false, true].
%
% Note: This implementation is based on Shimshoni's basic algebraic approach [1]
% without the proposed improvement.
%
% Reference:
% [1] I. Shimshoni, On Mobile Robot Localization from Landmark Bearings,
% IEEE Transactions on Robotics and Automation, Vol. 18, No. 6, 2002
% URL: http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=1159015
%
% Example:
% N = 3;
% map = [10 * rand(N,2), zeros(N,4)]; % Random 2D landmark map
% data = [2 * pi * rand(N,1) - pi, zeros(N,1)]; % Random measurement
% [pose, valid] = localize2d_shimshoni02_algebraic(data, map)
%
% See also localize2d_shimshoni02_improved, localize2d_betke97.
if size(data,1) < 3
error('DATA has less number of observations!');
end
if size(data,2) ~= 2
error('DATA has wrong size!');
end
% Calculate pose using algebraic method (Section II.C)
if sum(data(:,1) == 0) > 0 % A degenerate case of cotangent
pose = zeros(1,6);
valid = false * ones(1,6);
return;
end
A = ...
[ ...
map(:,1) - map(:,2) .* cot(data(:,1)), ...
map(:,2) + map(:,1) .* cot(data(:,1)), ...
ones(size(data,1),1), ...
-cot(data(:,1)) ...
];
[U,S,V] = svd(A);
W = V(:,end);
W = W ./ norm(W(1:2)); % Scaling
R = [W(1), W(2); -W(2), W(1)];
T = W(3:4);
P = -R' * T; % T = -R * P
% Select one betweetn two solutions using the first landmark (i = 1)
P_i = map(1,1:2)';
l = norm(P - P_i);
signL = sign(l * [cos(data(1,1)); sin(data(1,1))]);
signR = sign(R * P_i + T);
if ~isequal(signL, signR)
W = -W;
R = [W(1), W(2); -W(2), W(1)];
T = W(3:4);
P = -R' * T;
end
pose = [P(1), P(2), 0, 0, 0, atan2(W(2), W(1))];
valid = [true, true, false, false, false, true];