Skip to content

Commit 019a049

Browse files
committed
Ensure start and end points are in the path
Fix bug in plot if not distance map yet set Check only (x,y) part of configuration for collision Change isoccupied() to accept a set of points, can check path in a single call
1 parent 0066945 commit 019a049

File tree

1 file changed

+33
-23
lines changed

1 file changed

+33
-23
lines changed

Navigation.m

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,9 @@
136136
% - allow for an arbitrary transform from world coordinates to the grid
137137
% - it needs to affect plot scaling, start and goal
138138

139-
if nargin >= 1
139+
if nargin >= 1 && ( isnumeric(varargin{1}) || islogical(varargin{1}))
140140
% first argument is the map
141-
map = varargin{1};
141+
map = double( varargin{1} );
142142
varargin = varargin(2:end);
143143
if isnumeric(map) && ~isscalar(map)
144144
nav.occgrid = map;
@@ -243,7 +243,7 @@
243243

244244
% iterate using the next() method until we reach the goal
245245
robot = nav.start;
246-
path = [];
246+
path = nav.start(:);
247247
while true
248248
if opt.animate
249249
plot(robot(1), robot(2), 'g.', 'MarkerSize', 12);
@@ -255,13 +255,12 @@
255255

256256
% are we there yet?
257257
if isempty(robot)
258+
path = [path nav.goal(:)];
258259
% yes, exit the loop
259260
break
260261
else
261-
% no, append it to the path
262-
path = [path robot(:)];
262+
path = [path robot(:)]; % append it to the path
263263
end
264-
265264
end
266265

267266
% return the path
@@ -335,7 +334,7 @@ function plot_bg(nav, varargin)
335334
end
336335

337336
clf
338-
if isempty(opt.distance)
337+
if isempty(opt.distance) || all(all(~isfinite(opt.distance)))
339338
% create color map for free space + obstacle:
340339
% free space, color index = 1, white,
341340
% obstacle, color index = 2, red
@@ -354,7 +353,7 @@ function plot_bg(nav, varargin)
354353
d = opt.distance(isfinite(opt.distance));
355354
d = d + 2; % minimum distance is cmap=2 or black
356355
maxdist = max(d(:));
357-
356+
358357
% create the color map
359358
% 1 = red (obstacle)
360359
% 2 = black (zero distance)
@@ -538,47 +537,58 @@ function checkquery(nav, start, goal)
538537
end
539538

540539
% check if reachable
541-
assert(~nav.isoccupied(nav.start), 'Navigation:checkquery:badarg', 'start location inside obstacle');
540+
assert(~nav.isoccupied(nav.start(1:2)), 'Navigation:checkquery:badarg', 'start location inside obstacle');
542541

543542
if nargin == 3
544543
% make upright
545544
nav.goal = goal(:);
546545

547546
% check if reachable
548-
assert(~nav.isoccupied(nav.goal), 'Navigation:checkquery:badarg', 'goal location inside obstacle');
547+
assert(~nav.isoccupied(nav.goal(1:2)), 'Navigation:checkquery:badarg', 'goal location inside obstacle');
549548
end
550549
end
551550

552551

553552
function occ = isoccupied(nav, x, y)
554553
%Navigation.isoccupied Test if grid cell is occupied
555554
%
556-
% N.isoccupied(POS) is true if there is a valid grid map and the coordinate
557-
% POS (1x2) is occupied. P=[X,Y] rather than MATLAB row-column
558-
% coordinates.
555+
% N.isoccupied(POS) is true if there is a valid grid map and the
556+
% coordinates given by the columns of POS (2xN) are occupied.
559557
%
560558
% N.isoccupied(X,Y) as above but the coordinates given separately.
559+
%
560+
% Notes:
561+
% - X and Y are Cartesian rather than MATLAB row-column coordinates.
561562

562563
if isempty(nav.occgridnav)
563564
occ = false;
564565
return
565566
end
566567

567-
if nargin == 2 && length(x) >= 2
568-
pos = x(:);
569-
pos = pos(1:2);
568+
if nargin == 2
569+
% isoccupied(p)
570+
if numel(x) == 2
571+
x = x(:);
572+
end
573+
assert(size(x,1) == 2, 'RTB:Navigation:isoccupied', 'P must have 2 rows');
574+
pos = x;
570575
else
571-
pos = [x; y];
576+
% isoccupied(x,y)
577+
assert(numel(x) == numel(y), 'RTB:Navigation:isoccupied', 'X and Y must be same length');
578+
pos = [x(:)'; y(:)'];
572579
end
573580

574581
% convert from world coordinates to grid coordinates
575-
pos = round( nav.w2g * pos(:) );
582+
pos = round( nav.w2g * pos );
576583

577-
try
578-
occ = nav.occgridnav(pos(2), pos(1)) > 0;
579-
catch
580-
occ = true; % beyond the grid, all cells are implicitly occupied
581-
end
584+
% find all those that lie in the map
585+
k = pos(1,:) > 0 & pos(1,:) <= size(nav.occgrid,2) & pos(2,:) > 0 & pos(2,:) <= size(nav.occgrid,1);
586+
587+
% get the indices into the map
588+
i = sub2ind(size(nav.occgrid), pos(2,k), pos(1,k));
589+
590+
occ = ones(1, size(pos,2), 'logical'); % by default all occupied (true)
591+
occ(k) = nav.occgridnav(i) > 0;
582592
end
583593

584594
function goal_change(nav)

0 commit comments

Comments
 (0)