Repository navigation
Expand file tree
/
Copy pathpostProcessPath.m
More file actions
92 lines (72 loc) · 2.32 KB
/
Copy pathpostProcessPath.m
File metadata and controls
92 lines (72 loc) · 2.32 KB
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
function processedPath = postProcessPath( ...
rawPath,occupancyGrid,cfg)
%POSTPROCESSPATH Simplify and uniformly resample an A* path.
%
% Greedy line-of-sight simplification removes unnecessary grid turns.
% Uniform resampling then gives the look-ahead follower continuous,
% closely spaced target points. No spline is used, so obstacle clearance
% remains consistent with the occupancy grid.
if size(rawPath,1) <= 2
simplifiedPath = rawPath;
else
simplifiedPath = rawPath(1,:);
anchorIndex = 1;
while anchorIndex < size(rawPath,1)
candidateIndex = size(rawPath,1);
while candidateIndex > anchorIndex+1
if lineIsFreeLocal( ...
rawPath(anchorIndex,:), ...
rawPath(candidateIndex,:), ...
occupancyGrid)
break;
end
candidateIndex = candidateIndex-1;
end
simplifiedPath(end+1,:) = ...
rawPath(candidateIndex,:); %#ok<AGROW>
anchorIndex = candidateIndex;
end
end
segmentLengths = sqrt(sum( ...
diff(simplifiedPath,1,1).^2,2));
arcLength = [0;cumsum(segmentLengths)];
if arcLength(end) <= cfg.path.resampleSpacing
processedPath = simplifiedPath;
return;
end
queryArcLength = ...
(0:cfg.path.resampleSpacing:arcLength(end))';
if queryArcLength(end) < arcLength(end)
queryArcLength(end+1,1) = arcLength(end);
end
processedPath = [ ...
interp1(arcLength,simplifiedPath(:,1), ...
queryArcLength,'linear'), ...
interp1(arcLength,simplifiedPath(:,2), ...
queryArcLength,'linear')];
processedPath(1,:) = rawPath(1,:);
processedPath(end,:) = rawPath(end,:);
end
function free = lineIsFreeLocal( ...
pointA,pointB,occupancyGrid)
distance = norm(pointB-pointA);
sampleCount = max(2,ceil( ...
distance*occupancyGrid.resolution*3));
free = true;
for sampleIndex = 0:sampleCount
ratio = sampleIndex/sampleCount;
point = pointA+ratio*(pointB-pointA);
column = round( ...
point(1)*occupancyGrid.resolution+0.5);
row = round( ...
point(2)*occupancyGrid.resolution+0.5);
column = min(max(column,1), ...
occupancyGrid.numberOfColumns);
row = min(max(row,1), ...
occupancyGrid.numberOfRows);
if occupancyGrid.occupied(row,column)
free = false;
return;
end
end
end