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