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 ;
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 );
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