00001
00002 #ifndef _GENERIC_RRT_H_
00003 #define _GENERIC_RRT_H_
00004
00005 #include <vector>
00006 #include <ostream>
00007 #include <cmath>
00008
00009 #include "Shared/Measures.h"
00010
00011 using namespace DualCoding;
00012
00013
00014
00015
00016
00017
00018
00019
00020 class RRTNodeBase {
00021 public:
00022 RRTNodeBase(unsigned int p) : parent(p) {}
00023 unsigned int parent;
00024 enum Interp_t { COLLISION, APPROACHED, REACHED };
00025
00026 static float randRange(float minVal, float maxVal) {
00027 return (maxVal - minVal) * (rand()/((float)RAND_MAX)) + minVal;
00028 }
00029 virtual ~RRTNodeBase() {}
00030 virtual std::string toString() const = 0;
00031 };
00032
00033
00034
00035
00036
00037
00038
00039
00040 template<typename NODE>
00041 class AdmissibilityPredicate {
00042 public:
00043
00044 AdmissibilityPredicate() {}
00045
00046
00047 virtual ~AdmissibilityPredicate() {}
00048
00049
00050 virtual bool admissible(typename NODE::NodeValue_t q, std::vector<NODE>& tree, unsigned int parent) = 0;
00051 };
00052
00053
00054
00055 class GenericRRTBase {
00056 public:
00057 enum PlanPathResultCode {SUCCESS, START_COLLIDES, END_COLLIDES, MAX_ITER};
00058
00059
00060
00061
00062 template <size_t N>
00063 class PlannerResult {
00064 public:
00065 GenericRRTBase::PlanPathResultCode code;
00066 PlannerObstacle<N> *movingObstacle;
00067 PlannerObstacle<N> *collidingObstacle;
00068
00069 PlannerResult() : code(), movingObstacle(NULL), collidingObstacle(NULL) {}
00070
00071 ~PlannerResult() {
00072 delete movingObstacle;
00073 delete collidingObstacle;
00074 }
00075
00076
00077 PlannerResult(const PlannerResult &other) :
00078 code(other.code),
00079 movingObstacle(other.movingObstacle ? dynamic_cast<PlannerObstacle<N>*>(other.movingObstacle->clone()) : NULL),
00080 collidingObstacle(other.collidingObstacle ? dynamic_cast<PlannerObstacle<N>*>(other.collidingObstacle->clone()) : NULL) {}
00081
00082
00083 PlannerResult& operator=(const PlannerResult &other) {
00084 delete movingObstacle;
00085 delete collidingObstacle;
00086 code = other.code;
00087 movingObstacle = other.movingObstacle ? dynamic_cast<PlannerObstacle<N>*>(other.movingObstacle->clone()) : NULL;
00088 collidingObstacle = other.collidingObstacle ? dynamic_cast<PlannerObstacle<N>*>(other.collidingObstacle->clone()) : NULL;
00089 return *this;
00090 }
00091
00092 };
00093
00094 virtual ~GenericRRTBase() {}
00095
00096 typedef PlannerResult<2> PlannerResult2D;
00097 typedef PlannerResult<3> PlannerResult3D;
00098 };
00099
00100
00101 template<typename NODE, size_t N>
00102 class GenericRRT : public GenericRRTBase {
00103 public:
00104 typedef typename NODE::NodeValue_t NodeValue_t;
00105 protected:
00106
00107 NodeValue_t lowerLimits;
00108
00109 NodeValue_t upperLimits;
00110
00111 NodeValue_t extendingInterpolationStep;
00112
00113 NodeValue_t smoothingInterpolationStep;
00114
00115 typename NODE::CollisionChecker *cc;
00116
00117 AdmissibilityPredicate<NODE> *predicate;
00118
00119 public:
00120
00121 GenericRRT(typename NODE::CollisionChecker *collCheck, AdmissibilityPredicate<NODE> *predicate=NULL);
00122
00123
00124 GenericRRT(const GenericRRT &other) :
00125 GenericRRTBase(other),
00126 lowerLimits(other.lowerLimits), upperLimits(other.upperLimits),
00127 extendingInterpolationStep(other.extendingInterpolationStep),
00128 smoothingInterpolationStep(other.smoothingInterpolationStep),
00129 cc(other.cc), predicate(other.predicate) {}
00130
00131
00132
00133 virtual ~GenericRRT() { delete cc; delete predicate; }
00134
00135
00136 void setLimits(const NodeValue_t &_lowerLimits, const NodeValue_t &_upperLimits) {
00137 lowerLimits = _lowerLimits;
00138 upperLimits = _upperLimits;
00139 }
00140
00141
00142 virtual void setInterpolation(const NodeValue_t &_interpolationStep) {
00143 setSmoothingInterpolation(_interpolationStep);
00144 setExtendingInterpolation(_interpolationStep);
00145 }
00146
00147
00148 virtual void setExtendingInterpolation(const NodeValue_t &_extendingInterpolationStep) {
00149 extendingInterpolationStep = _extendingInterpolationStep;
00150 }
00151
00152
00153 virtual void setSmoothingInterpolation(const NodeValue_t &_smoothingInterpolationStep) {
00154 smoothingInterpolationStep = _smoothingInterpolationStep;
00155 }
00156
00157
00158 virtual PlannerResult<N> planPath(const NodeValue_t &start,
00159 const NodeValue_t &end,
00160 unsigned int maxIterations,
00161 std::vector<NodeValue_t> *pathResult=NULL,
00162 std::vector<NODE> *treeStartResult=NULL,
00163 std::vector<NODE> *treeEndResult=NULL);
00164
00165 typename NODE::CollisionChecker* getCC() { return cc; }
00166
00167 virtual void dumpTree(const std::vector<NODE> &tree, const std::string &header="");
00168
00169 void addObstaclesToShapeSpace(ShapeSpace &space, const fmat::Transform &t=fmat::Transform()) const;
00170
00171 protected:
00172
00173 virtual void initialize(const NodeValue_t &start, std::vector<NODE> &treeStartResult,
00174 const NodeValue_t &end, std::vector<NODE> &treeEndResult);
00175 virtual void buildPath(const std::vector<NODE> *treeStart, const std::vector<NODE> *treeEnd,
00176 std::vector<NodeValue_t> &path);
00177
00178 void addNode(std::vector<NODE> *tree, const NodeValue_t &q, unsigned int parent);
00179
00180 private:
00181 unsigned int nearestNode(std::vector<NODE> *tree, const NodeValue_t &target);
00182 RRTNodeBase::Interp_t extend(std::vector<NODE> *tree, const NodeValue_t &q, bool truncate, bool searchingBackwards);
00183
00184 GenericRRT& operator=(const GenericRRT&);
00185 };
00186
00187
00188
00189 template<typename NODE, size_t N>
00190 GenericRRT<NODE, N>::GenericRRT(typename NODE::CollisionChecker *collCheck,
00191 AdmissibilityPredicate<NODE> *_predicate) :
00192 lowerLimits(), upperLimits(), extendingInterpolationStep(), smoothingInterpolationStep(), cc(collCheck), predicate(_predicate) {}
00193
00194 template<typename NODE, size_t N>
00195 void GenericRRT<NODE, N>::initialize(const NodeValue_t &start, std::vector<NODE> &treeStart,
00196 const NodeValue_t &end, std::vector<NODE> &treeEnd) {
00197 addNode(&treeStart, start, 0);
00198 addNode(&treeEnd, end, 0);
00199 }
00200
00201 template<typename NODE, size_t N>
00202 GenericRRTBase::PlannerResult<N>
00203 GenericRRT<NODE, N>::planPath(const NodeValue_t &start, const NodeValue_t &end,
00204 unsigned int maxIterations,
00205 std::vector<NodeValue_t> *pathResult,
00206 std::vector<NODE> *treeStartResult, std::vector<NODE> *treeEndResult) {
00207 PlannerResult<N> result;
00208
00209
00210 std::vector<NODE> privateTreeStart, privateTreeEnd;
00211 std::vector<NODE> *treeStart = treeStartResult ? treeStartResult : &privateTreeStart;
00212 std::vector<NODE> *treeEnd = treeEndResult ? treeEndResult : &privateTreeEnd;
00213 treeStart->clear();
00214 treeEnd->clear();
00215
00216
00217 initialize(start, *treeStart, end, *treeEnd);
00218
00219 std::vector<NODE> *A = treeStart;
00220 std::vector<NODE> *B = treeEnd;
00221
00222
00223 if ( cc->collides(start, &result) ) {
00224 result.code = START_COLLIDES;
00225 return result;
00226 }
00227
00228
00229
00230
00231
00232 if ( treeEnd->size() <= 2 && cc->collides(end, &result) ) {
00233 result.code = END_COLLIDES;
00234 return result;
00235 }
00236
00237 unsigned int iter = 0;
00238 bool searchingBackwards = false;
00239
00240 if ( treeEnd->size() == 1 && extend(A, end, false, searchingBackwards) == RRTNodeBase::REACHED )
00241 ;
00242 else
00243
00244 while ( iter++ < maxIterations ) {
00245 NodeValue_t qrand;
00246 if ( iter == 1 && (*B)[0].parent < B->size() )
00247 qrand = (*B)[nearestNode(B, start)].q;
00248 else
00249 NODE::generateSample(lowerLimits,upperLimits,qrand);
00250 if ( extend(A, qrand, true, searchingBackwards) != RRTNodeBase::COLLISION ) {
00251 if ( extend(B, A->back().q, true, !searchingBackwards) == RRTNodeBase::REACHED )
00252 break;
00253 swap(A,B);
00254 searchingBackwards = ! searchingBackwards;
00255 }
00256 }
00257
00258 if ( iter >= maxIterations ) {
00259
00260
00261 result.code = MAX_ITER;
00262 return result;
00263 }
00264
00265 if ( pathResult != NULL )
00266 buildPath(treeStart, treeEnd, *pathResult);
00267
00268 result.code = SUCCESS;
00269 return result;
00270 }
00271
00272
00273 template<typename NODE, size_t N>
00274 unsigned int GenericRRT<NODE, N>::nearestNode(std::vector<NODE> *tree, const NodeValue_t &target) {
00275
00276
00277
00278
00279 unsigned int nearest = (*tree)[0].parent;
00280 float dist = (*tree)[nearest].distance(target);
00281 for (unsigned int i = nearest+1; i < tree->size(); i++) {
00282 float d = (*tree)[i].distance(target);
00283 if (d < dist) {
00284 nearest = i;
00285 dist = d;
00286 }
00287 }
00288 return nearest;
00289 }
00290
00291
00292 template<typename NODE, size_t N>
00293 RRTNodeBase::Interp_t GenericRRT<NODE, N>::extend(std::vector<NODE> *tree, const NodeValue_t &target,
00294 bool truncate, bool searchingBackwards) {
00295 unsigned int nearest = nearestNode(tree, target);
00296 NodeValue_t reached;
00297
00298 RRTNodeBase::Interp_t result =
00299 NODE::interpolate((*tree)[nearest].q, target, extendingInterpolationStep, truncate, cc, reached, searchingBackwards);
00300 if ( result != RRTNodeBase::COLLISION ) {
00301 if ( predicate != NULL && predicate->admissible(reached, *tree, nearest) == false )
00302 result = RRTNodeBase::COLLISION;
00303 else
00304 addNode(tree, reached, nearest);
00305 }
00306 return result;
00307 }
00308
00309
00310 template<typename NODE, size_t N>
00311 void GenericRRT<NODE, N>::addNode(std::vector<NODE> *tree, const NodeValue_t &q, unsigned int parent) {
00312 tree->push_back(NODE(q, parent));
00313 }
00314
00315
00316 template<typename NODE, size_t N>
00317 void GenericRRT<NODE, N>::buildPath(const std::vector<NODE> *treeStart, const std::vector<NODE> *treeEnd,
00318 std::vector<NodeValue_t> &path) {
00319
00320
00321 unsigned int n = treeStart->size() - 1;
00322 while (n != 0) {
00323 n = (*treeStart)[n].parent;
00324 path.push_back((*treeStart)[n].q);
00325 }
00326
00327 std::reverse(path.begin(), path.end());
00328 path.push_back(treeEnd->back().q);
00329
00330 n = treeEnd->size() - 1;
00331 while (n != 0) {
00332 n = (*treeEnd)[n].parent;
00333 path.push_back((*treeEnd)[n].q);
00334 }
00335
00336
00337 size_t maxIter = max((size_t)20, 2*path.size());
00338
00339 for (size_t i = 0; i < maxIter; i++) {
00340 int a = rand() % path.size();
00341 int b = rand() % path.size();
00342 if (a > b)
00343 std::swap(a,b);
00344 else if (a == b)
00345 continue;
00346
00347 NodeValue_t dummy;
00348 if ( NODE::interpolate(path[a], path[b], smoothingInterpolationStep, false, cc, dummy, true) == RRTNodeBase::REACHED ) {
00349 path.erase(path.begin()+a+1,path.begin()+b);
00350 }
00351 }
00352
00353 for (size_t i = 0; i+2 < path.size(); i++) {
00354 size_t j;
00355 for (j = i + 2; j < path.size(); j++) {
00356 NodeValue_t dummy;
00357 if ( NODE::interpolate(path[i], path[j], smoothingInterpolationStep, false, cc, dummy, true) != RRTNodeBase::REACHED )
00358 break;
00359 }
00360 if (j > i + 3 && j < path.size())
00361 path.erase(path.begin()+i+1, path.begin()+j-1);
00362 }
00363 }
00364
00365 template<typename NODE, size_t N>
00366 void GenericRRT<NODE, N>::dumpTree(const std::vector<NODE> &tree, const std::string &header) {
00367 if ( header.size() > 0 )
00368 std::cout << header << std::endl;
00369 for ( size_t i = 0; i < tree.size(); i++ )
00370 if ( tree[i].parent != 0 )
00371 std::cout << " " << tree[i].toString() << " " << tree[tree[i].parent].toString() << std::endl;
00372 }
00373
00374 template<typename NODE, size_t N>
00375 void GenericRRT<NODE, N>::addObstaclesToShapeSpace(ShapeSpace &space, const fmat::Transform &t) const {
00376 cc->addObstaclesToShapeSpace(space,t);
00377 }
00378
00379 #endif