|
40 | 40 | % Copyright (C) 1993-2017, by Peter I. Corke |
41 | 41 | % |
42 | 42 | % This file is part of The Robotics Toolbox for MATLAB (RTB). |
43 | | -% |
| 43 | +% |
44 | 44 | % RTB is free software: you can redistribute it and/or modify |
45 | 45 | % it under the terms of the GNU Lesser General Public License as published by |
46 | 46 | % the Free Software Foundation, either version 3 of the License, or |
47 | 47 | % (at your option) any later version. |
48 | | -% |
| 48 | +% |
49 | 49 | % RTB is distributed in the hope that it will be useful, |
50 | 50 | % but WITHOUT ANY WARRANTY; without even the implied warranty of |
51 | 51 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
52 | 52 | % GNU Lesser General Public License for more details. |
53 | | -% |
| 53 | +% |
54 | 54 | % You should have received a copy of the GNU Leser General Public License |
55 | 55 | % along with RTB. If not, see <http://www.gnu.org/licenses/>. |
56 | 56 | % |
57 | 57 | % http://www.petercorke.com |
58 | 58 |
|
59 | | -function d = distancexform(occgrid, varargin) |
| 59 | +function dx = distancexform(occgrid, varargin) |
60 | 60 |
|
61 | 61 | opt.show = 0; |
62 | 62 | opt.ipt = true; |
|
68 | 68 | opt.ipt = false; |
69 | 69 | opt.vlfeat = false; |
70 | 70 | end |
| 71 | + count = []; |
| 72 | + switch opt.metric |
| 73 | + case 'cityblock' |
| 74 | + ipt_metric = opt.metric; % if we use bwdistgeodesic |
| 75 | + m = [ inf 1 inf |
| 76 | + 1 0 1 |
| 77 | + inf 1 inf ]; |
| 78 | + case 'euclidean' |
| 79 | + ipt_metric = 'quasi-euclidean'; % if we use bwdistgeodesic |
| 80 | + r2 = sqrt(2); |
| 81 | + m = [ r2 1 r2 |
| 82 | + 1 0 1 |
| 83 | + r2 1 r2 ]; |
| 84 | + end |
71 | 85 |
|
72 | 86 | if ~isempty(args) && isvec(args{1}, 2) |
73 | 87 | %% path planning interpretation |
|
76 | 90 | goal = args{1}; |
77 | 91 | occgrid = double(occgrid); |
78 | 92 |
|
79 | | - if exist('imorph', 'file') ~= 3 |
80 | | - error('Machine Vision Toolbox is required by this function'); |
81 | | - end |
82 | | - |
83 | | - switch opt.metric |
84 | | - case 'cityblock' |
85 | | - m = [ inf 1 inf |
86 | | - 1 0 1 |
87 | | - inf 1 inf ]; |
88 | | - case 'euclidean' |
89 | | - r2 = sqrt(2); |
90 | | - m = [ r2 1 r2 |
91 | | - 1 0 1 |
92 | | - r2 1 r2 ]; |
93 | | - otherwise |
94 | | - error('unknown distance metric'); |
95 | | - end |
96 | | - |
97 | 93 | % check the goal point is sane |
98 | | - if occgrid(goal(2), goal(1)) > 0 |
99 | | - error('goal inside obstacle') |
100 | | - end |
| 94 | + assert(occgrid(goal(2), goal(1)) == 0, 'RTB:distancexform:badarg', 'goal inside obstacle') |
101 | 95 |
|
102 | | - if opt.fast && exist('imorph', 'file') == 3 |
| 96 | + if exist('imorph', 'file') && opt.fast |
| 97 | + if opt.verbose |
| 98 | + fprintf('using MVTB:imorph\n'); |
| 99 | + end |
103 | 100 | % setup to use imorph |
104 | 101 | % - set obstacles to NaN |
105 | 102 | % - set free space to Inf |
|
132 | 129 | end |
133 | 130 | ninf = ninfnow; |
134 | 131 | end |
| 132 | + dx = occgrid; |
| 133 | + |
| 134 | + elseif exist('bwdistgeodesic', 'file') && opt.ipt |
| 135 | + if opt.verbose |
| 136 | + fprintf('using IPT:bwdistgeodesic\n'); |
| 137 | + end |
| 138 | + % solve using IPT |
| 139 | + |
| 140 | + dx = double( bwdistgeodesic(occgrid==0, goal(1), goal(2), ipt_metric) ); |
| 141 | + |
135 | 142 | else |
| 143 | + if opt.verbose |
| 144 | + fprintf('using MATLAB code, faster if you install MVTB\n'); |
| 145 | + end |
136 | 146 | % setup to use M-function |
137 | 147 |
|
138 | 148 | occgrid(occgrid>0) = NaN; |
|
146 | 156 |
|
147 | 157 | occgrid = dxstep(occgrid, m); |
148 | 158 | occgrid(nans) = NaN; |
149 | | - |
| 159 | + |
150 | 160 | count = count+1; |
151 | 161 | if opt.show |
152 | 162 | cmap = [1 0 0; gray(count)]; |
|
166 | 176 | end |
167 | 177 | ninf = ninfnow; |
168 | 178 | end |
| 179 | + dx = occgrid; |
169 | 180 | end |
170 | 181 |
|
171 | | - if opt.show |
| 182 | + if opt.show && ~isempty(count) |
172 | 183 | fprintf('%d iterations, %d unreachable cells\n', count, ninf); |
173 | 184 | end |
174 | 185 |
|
175 | | - d = occgrid; |
176 | 186 | else |
177 | 187 | %% image processing interpretation |
178 | 188 | % distancexform(world, [metric]) |
179 | 189 |
|
180 | | - % use other toolboxes if they exist |
181 | | - if opt.fast && exist('bwdist') && opt.ipt |
182 | | - d = bwdist(occgrid, opt.metric); |
183 | | - |
184 | | - elseif exist('vl_imdisttf') == 3 && opt.vlfeat |
185 | | - im = double(occgrid); |
186 | | - im(im==0) = inf; |
187 | | - im(im==1) = 0; |
188 | | - d2 = vl_imdisttf(im); |
189 | | - d = sqrt(d2); |
190 | | - |
191 | | - elseif opt.fast && exist('imorph', 'file') == 3 |
192 | | - |
193 | | - switch opt.metric |
194 | | - case 'cityblock' |
195 | | - m = ones(3,3); |
196 | | - m(2,2) = 0; |
197 | | - case 'euclidean' |
198 | | - r2 = sqrt(2); |
199 | | - m = [r2 1 r2; 1 0 1; r2 1 r2]; |
200 | | - otherwise |
201 | | - error('unknown distance metric'); |
| 190 | + if exist('imorph', 'file') && opt.fast |
| 191 | + if opt.verbose |
| 192 | + fprintf('using MVTB:imorph\n'); |
202 | 193 | end |
203 | 194 |
|
204 | 195 | % setup to use imorph |
|
228 | 219 | break; |
229 | 220 | end |
230 | 221 | end |
231 | | - d = occgrid; |
| 222 | + dx = occgrid; |
| 223 | + elseif exist('bwdist') && opt.ipt |
| 224 | + if opt.verbose |
| 225 | + fprintf('using IPT:bwdist\n'); |
| 226 | + end |
| 227 | + % use IPT |
| 228 | + dx = bwdist(occgrid, ipt_metric); |
| 229 | + |
| 230 | + elseif exist('vl_imdisttf') && opt.vlfeat |
| 231 | + if opt.verbose |
| 232 | + fprintf('using VLFEAT:vl_imsdisttf\n'); |
| 233 | + end |
| 234 | + im = double(occgrid); |
| 235 | + im(im==0) = inf; |
| 236 | + im(im==1) = 0; |
| 237 | + d2 = vl_imdisttf(im); |
| 238 | + dx = sqrt(d2); |
| 239 | + |
232 | 240 | else |
233 | | - switch opt.metric |
234 | | - case 'cityblock' |
235 | | - m = ones(3,3); |
236 | | - m(2,2) = 0; |
237 | | - case 'euclidean' |
238 | | - r2 = sqrt(2); |
239 | | - m = [r2 1 r2; 1 0 1; r2 1 r2]; |
240 | | - otherwise |
241 | | - error('unknown distance metric'); |
| 241 | + if opt.verbose |
| 242 | + fprintf('using MATLAB code, faster if you install MVTB\n'); |
242 | 243 | end |
243 | 244 |
|
244 | 245 | occgrid = double(occgrid); |
|
265 | 266 | break; |
266 | 267 | end |
267 | 268 | end |
268 | | - d = occgrid; |
| 269 | + dx = occgrid; |
269 | 270 | end |
270 | 271 | end |
271 | 272 | end |
272 | 273 |
|
| 274 | +% MATLAB implementation of computational kernel |
| 275 | + |
273 | 276 | function out = dxstep(G, m) |
274 | 277 |
|
275 | 278 | [h,w] = size(G); % get size of occ grid |
|
0 commit comments