From f1cbb3171cdf9b5c2292510223a537bd1a1e09ee Mon Sep 17 00:00:00 2001 From: saurabhkgpee Date: Sun, 13 Aug 2017 02:44:11 +0530 Subject: [PATCH 1/6] RRT Connect --- include/RRT.hpp | 58 ++++++-- include/RRTConnect.hpp | 331 +++++++++++++++++++++++++++++++++++++++++ src/main.cpp | 38 +++-- 3 files changed, 406 insertions(+), 21 deletions(-) create mode 100644 include/RRTConnect.hpp diff --git a/include/RRT.hpp b/include/RRT.hpp index e718bac..df00797 100644 --- a/include/RRT.hpp +++ b/include/RRT.hpp @@ -19,19 +19,19 @@ namespace rrt double stepLength; std::vector > pathPoints; int maxIterations; - std::vector< std::pair< Utils::Point, Utils::Point > > tree; + std::vector< std::pair< Utils::Point, Utils::Point > > tree; unsigned int biasParameter; - + public: RRT(){}; RRT(Utils::Point start,Utils::Point end) { - //srand(time(NULL)); + //srand(time(NULL)); startPoint=start; endPoint=end; } - + virtual bool plan(); virtual std::vector > getPointsOnPath(); @@ -59,13 +59,51 @@ namespace rrt void generatePath(Utils::Point first,Utils::Point last); double dist(Utils::Point a,Utils::Point b); }; + + template + class RRTConnect: public RRT{ + + public: + bool plan(); + std::vector > getPointsOnPath(); + + void setEndPoints(Utils::Point start, Utils::Point end); + void setCheckPointFunction(bool (*f)(Utils::Point)); + void setStepLength(double value); + void setOrigin(Utils::Point origin); + void setHalfDimensions(double x,double y); + void setBiasParameter(unsigned int); + void setMaxIterations(int); + private: + double halfDimensionX; + double halfDimensionY; + Utils::Point origin; + Utils::Point connectA; + Utils::Point connectB; + Utils::Point startPoint; + Utils::Point endPoint; + double stepLength; + std::vector > pathPoints; + int maxIterations; + std::vector< std::pair< Utils::Point, Utils::Point > > treeA; + std::vector< std::pair< Utils::Point, Utils::Point > > treeB; + std::vector< std::pair< Utils::Point, Utils::Point > > mainTree; + std::vector< std::pair< Utils::Point, Utils::Point > > supportTree; + + unsigned int biasParameter; + bool (*userCheck)(Utils::Point); + bool checkPoint(Utils::Point pt); + Utils::Point generatePoint(std::vector< std::pair< Utils::Point, Utils::Point > >); + Utils::Point generateBiasedPoint(Utils::Point ,std::vector< std::pair< Utils::Point, Utils::Point > >); + Utils::Point findClosestNode(Utils::Point,std::vector< std::pair< Utils::Point, Utils::Point > > tree); + void growTree(Utils::Point); + Utils::Point getParent(Utils::Point,std::vector< std::pair< Utils::Point, Utils::Point > > tree); + bool treeComplete(); + void generatePath(Utils::Point first,Utils::Point last); + double dist(Utils::Point a,Utils::Point b); + }; } -//************* ToDo ************* -// Implement derived classes for variants of RRT -// Optimize the generate path and other -// Tweak with the parameters to check their effects on runtime and path -// Implement Pruning function to keep a check on size of tree -#endif +#endif \ No newline at end of file diff --git a/include/RRTConnect.hpp b/include/RRTConnect.hpp new file mode 100644 index 0000000..b5ca20d --- /dev/null +++ b/include/RRTConnect.hpp @@ -0,0 +1,331 @@ +#include +#include "./RRT.hpp" +#include "./RRT_implementation.hpp" +#include "./utils.hpp" + +using namespace std; +namespace rrt +{ + template + void RRTConnect::setEndPoints(Utils::Point start, Utils::Point end) + { + startPoint=start; + endPoint=end; + } + + template + void RRTConnect::setHalfDimensions(double a, double b) + { + halfDimensionX=a; + halfDimensionY=b; + } + + template + void RRTConnect::setOrigin(Utils::Point pt) + { + origin=pt; + } + + template + std::vector > RRTConnect::getPointsOnPath() + { + return pathPoints; + } + + template + void RRTConnect::setStepLength(double value) + { + stepLength=value; + } + + template + void RRTConnect::setMaxIterations(int value) + { + maxIterations=value; + } + + template + bool RRTConnect:: plan() + { + int count=0; + int check=0; + treeA.push_back(std::pair< Utils::Point, Utils::Point > (startPoint,startPoint)); + treeB.push_back(std::pair< Utils::Point, Utils::Point > (endPoint,endPoint)); + + int start_time=clock(); + while( check < maxIterations) + { + //std::cout<<"In Planning Loop"< next; + + + if (check%2 == 0) + { + mainTree = treeA; + supportTree = treeB; + } + else{ + mainTree = treeB; + supportTree = treeA; + } + + if(treeComplete()==true) + { + std::cout<<"Tree complete!!"< + + void RRTConnect::growTree(Utils::Point temp) + { + //growing the tree by adding node + //std::cout<<"finding parent in tree of size = "< closest; + closest = findClosestNode(temp,treeA); + double theta = atan2(temp.y-closest.y,temp.x-closest.x); + double dis = dist(temp,closest); + if (dis > stepLength) + { + temp.x=closest.x+stepLength*cos(theta); + temp.y=closest.y+stepLength*sin(theta); + } + treeA.push_back( std::pair< Utils::Point, Utils::Point > (temp,closest)); + + closest = findClosestNode(temp,treeB); + theta = atan2(temp.y - closest.y , temp.x - closest.x); + dis = dist(temp,closest); + if (dis > stepLength) + { + temp.x=closest.x+stepLength*cos(theta); + temp.y=closest.y+stepLength*sin(theta); + } + treeB.push_back( std::pair< Utils::Point, Utils::Point > (temp,closest)); + //std::cout<<"Point Generated = "< + void RRTConnect::setCheckPointFunction(bool (*f)(Utils::Point)) + { + userCheck=f; + } + + template + Utils::Point RRTConnect::findClosestNode(Utils::Point cur,std::vector< std::pair< Utils::Point, Utils::Point > >tree) + { + double min_dist=INT_MAX; + Utils::Point closest; + for(int i=0;i + Utils::Point RRTConnect::generatePoint(std::vector< std::pair< Utils::Point, Utils::Point > > tree) + { + Utils::Point temp; + int signX,signY; + + if(rand()%2==0) + signX=-1; + else + signX=1; + if(rand()%2==0) + signY=-1; + else + signY=1; + temp.x = origin.x + signX* ( rand() % (int)halfDimensionX ); + temp.y = origin.y + signY* ( rand() % (int)halfDimensionY ); + + + return temp; + Utils::Point closest=findClosestNode(temp,tree); + double theta = atan2(temp.y-closest.y,temp.x-closest.x); + double dis = dist(temp,closest); + if (dis < stepLength) + { + return temp; + } + Utils::Point next; + + next.x=closest.x+stepLength*cos(theta); + next.y=closest.y+stepLength*sin(theta); + // std::cout<<"origin,"< + Utils::Point RRTConnect::generateBiasedPoint(Utils::Point endPoint,std::vector< std::pair< Utils::Point, Utils::Point > >tree) + { + Utils::Point closest=findClosestNode(endPoint,tree); + double theta = atan2(endPoint.y-closest.y,endPoint.x-closest.x); + + Utils::Point next; + next.x=closest.x+stepLength*cos(theta); + next.y=closest.y+stepLength*sin(theta); + //std::cout<<"Biased Point Generated = "< + bool RRTConnect::checkPoint(Utils::Point next) + { + return userCheck(next); + } + + template + bool RRTConnect::treeComplete() + { + std::vector< std::pair< Utils::Point, Utils::Point > > conn; + //std::cout<<"Checking if tree is complete? "<, Utils::Point > (connectA,connectB)); + // std::cout<<"distance = "< + void RRTConnect::setBiasParameter(unsigned int param) + { + biasParameter=param; + } + + template + void RRTConnect::generatePath(Utils::Point first,Utils::Point last) + { + + Utils::Point cur=connectA; + while(cur!=startPoint){ + pathPoints.insert(pathPoints.begin(),cur); + cur = getParent(cur,treeA); + } + + pathPoints.insert(pathPoints.begin(),cur); + + cur = connectB; + + // std::cout< parent= getParent(cur); + // std::cout<<"current : "< + Utils::Point RRTConnect::getParent(Utils::Point cur,std::vector< std::pair< Utils::Point, Utils::Point > >tree) + { + for(int i=0;i + double RRTConnect::dist(Utils::Point a,Utils::Point b) + { + return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y)); + } +} + diff --git a/src/main.cpp b/src/main.cpp index 8e5a1d1..0e712f2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,13 +1,18 @@ #include -#include "./RRT_implementation.hpp" +#include "./../include/RRTConnect.hpp" using namespace std; using namespace rrt; bool check(Utils::Point cur) { - if(abs(cur.x)<2000 && abs(cur.y)<2000) + if(abs(cur.x)<2000 && abs(cur.y)<2000){ + // if (cur.x < 550 && cur.x > 450 && cur.y < 550 & cur.y > 450) + // { + // return false; + // } return true; + } return false; } @@ -15,24 +20,35 @@ int main() { srand(time(NULL)); Utils::Point start,finish,origin; - start.x=-10; - start.y=10; - finish.x=1000; - finish.y=730; + start.x=30; + start.y=30; + finish.x=1500; + finish.y=1730; origin.x=0; origin.y=0; - RRT test; + RRTConnect test; test.setEndPoints(start,finish); test.setCheckPointFunction(*(check)); - test.setStepLength(200); + test.setStepLength(50); test.setHalfDimensions(2000.0,2000.0); test.setBiasParameter(100); test.setOrigin(origin); test.setMaxIterations(10000); test.plan(); - cout<<"#################################################"< > path=test.getPointsOnPath(); + cout<<"#################################################"< Date: Sat, 2 Sep 2017 23:42:00 +0530 Subject: [PATCH 2/6] fix conficts --- include/RT_RRT_star.hpp | 30 ++++++++++++---- src/RT_RRT_star.cpp | 77 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+), 7 deletions(-) diff --git a/include/RT_RRT_star.hpp b/include/RT_RRT_star.hpp index 81bde9d..74927a5 100644 --- a/include/RT_RRT_star.hpp +++ b/include/RT_RRT_star.hpp @@ -47,8 +47,11 @@ namespace rrt { // Grid density long int k_max; + // Useful parameters for setting some search parameters + unsigned int width, length; + public: - RT_RRT(){}; + RT_RRT(); RT_RRT(T goal_radius, T obstacle_radius, T search_radius, T node_thresh, T epsilon_radius, long int k_max); @@ -60,9 +63,10 @@ namespace rrt { { return sqrt(pow(first.x-second.x,2)+pow(first.y-second.y,2)); } + /** @brief Return Grid Id */ - std::pair Grid_Id(Utils::point gride_idx); + std::pair Grid_Id(Utils::Point gride_idx); /** @brief Return cost */ @@ -93,8 +97,7 @@ namespace rrt { /** @brief Add a new point to the tree */ - void add_node_to_tree(Utils::Point rand, Utils::Point closest, - std::vector > nearest_nodes); + void add_node_to_tree(Utils::Point rand); /** @brief Rewire the tree from the latest node added to the tree */ @@ -103,11 +106,11 @@ namespace rrt { Utils::Point me = Qr.pop(); std::pair> now = getCost(me); int cost = now.first; - Utils::Point parent = now.second; + Utils::Point parent = now.second; std::vector > neighbours= find_near_nodes(Qr); for (int i=0;i = neighbours[i]; + Utils::Point neighbour = neighbours[i]; if (cost > cost - dist(me,parent) + dist(parent,neighbour) + dist(neighbour,me)) { for(int j=0;i > neighbours= find_near_nodes(Xa); for (int i=0;i = neighbours[i]; + Utils::Point neighbour = neighbours[i]; if (cost > cost - dist(me,Xa) + dist(Xa,neighbour) + dist(neighbour,me)) { for(int j=0;i closest_node(Utils::Point rand); + + /** @brief Verify if the line crosses any obstacle + */ + bool line_path_obs(Utils::Point p1, Utils::Point p2); }; } diff --git a/src/RT_RRT_star.cpp b/src/RT_RRT_star.cpp index 2f35b65..8a6cb42 100644 --- a/src/RT_RRT_star.cpp +++ b/src/RT_RRT_star.cpp @@ -1 +1,78 @@ #include "RT_RRT_star.hpp" + +namespace rrt { + + template + RT_RRT::RT_RRT() { + // TODO : set these parameters + // TODO : Set all parameters in one scale + goal_radius = 20.0; + obstacle_radius = 20.0; + search_radius = 20.0; + node_thresh = 20.0; + epsilon_radius = 20.0; + k_max = 20.0; + + width = 6; + length = 9; + } + + template + RT_RRT::RT_RRT(T goal_radius, T obstacle_radius, T search_radius, + T node_thresh, T epsilon_radius, long int k_max) { + + this->goal_radius = goal_radius; + this->obstacle_radius = obstacle_radius; + this->search_radius = search_radius; + this->node_thresh = node_thresh; + this->epsilon_radius = epsilon_radius; + this->k_max = k_max; + width = 6; + length = 9; + } + + template + void RT_RRT::update_epsilon_radius() { + size_t total_nodes = this->tree.size(); + + } + + template + std::vector > RT_RRT::find_near_nodes(Utils::Point query) { + + std::pair grid_idx = this->Grid_Id(query); + std::vector > nearest_points; + for (typename std::vector >::iterator + itr = grid_nodes[grid_idx].begin(); itr != grid_nodes[grid_idx].end(); + ++itr) { + this->update_epsilon_radius(); + if (this->dist(query, *itr) < this->epsilon_radius) { + nearest_points.push_back(*itr); + } + } + return nearest_points; + } + + template + std::pair RT_RRT::Grid_Id(Utils::Point node) { + + } + + template + void RT_RRT::add_node_to_tree(Utils::Point rand) { + + Utils::Point closest = closest_node(rand); + std::vector > x_near = find_near_nodes(rand); + + Utils::Point x_min = closest; + int c_min = cost(closest) + dist(closest, rand); + for (typename std::vector >::iterator itr = x_near.begin(); + itr != x_near.end(); ++itr) { + + int c_new = cost(*itr) + dist(*itr, rand); + + } + + } + +} From 4e8eb0ba50d74b7fadcc4dc189f866e43919d84f Mon Sep 17 00:00:00 2001 From: saurabhkgpee Date: Sun, 3 Sep 2017 01:20:00 +0530 Subject: [PATCH 3/6] Planner --- CMakeLists.txt | 6 +- include/DRRT.hpp | 570 +++++++++++++++++++++++++++++++++ include/RRT.hpp | 78 ++++- include/RRT_implementation.hpp | 35 +- test/main.cpp | 67 ++++ 5 files changed, 723 insertions(+), 33 deletions(-) create mode 100644 include/DRRT.hpp create mode 100644 test/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 3334ca3..aa66045 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,8 +4,10 @@ set(CMAKE_CXX_FLAGS "-std=c++11") include_directories("include") -set(SRCS src/Random_sampling.cpp - src/RT_RRT_star.cpp) +set(SRCS src/Random_sampling.cpp) set(PLANNERS planners) add_library(${PLANNERS} SHARED ${SRCS}) + +add_executable(target test/main.cpp) +target_link_libraries(target ${PLANNERS}) diff --git a/include/DRRT.hpp b/include/DRRT.hpp new file mode 100644 index 0000000..ef1b96a --- /dev/null +++ b/include/DRRT.hpp @@ -0,0 +1,570 @@ + +#include +#include "./RRT.hpp" +#include "./RRT_implementation.hpp" +#include "./utils.hpp" + +using namespace std; +namespace rrt +{ + + template + void DRRT::setBucketSize(unsigned int size){ + BucketSize = size; + } + + template + void DRRT::setPointsInBucket(unsigned int num){ + PointsInBucket = num; + } + + template + void DRRT::generateGrid(){ + numX = 2*halfDimensionX/BucketSize; + if (numX != (int)numX) + { + numX = (int)numX + 1; + } + numY = 2*halfDimensionY/BucketSize; + if (numY != (int)numY) + { + numY = (int)numY + 1; + } + int num = numX*numY; + for (int i = 0; i < num; ++i) + { + std::vector v; + bucket.push_back(std::pair > (i,v)); + } + } + + template < class T> + int DRRT::findBucket(Utils::Point pt){ + int x = pt.x + halfDimensionX ; + int y = pt.y + halfDimensionX ; + int numx = (int)(x/BucketSize) + 1; + if (numx > numX) + { + numx = numx - 1; + } + int numy = (int)(y/BucketSize) + 1; + if (numy > numY) + { + numy = numy - 1; + } + int num = (numy - 1)*numX + numx - 1; + return num; + } + + template + void DRRT::setEndPoints(Utils::Point start, Utils::Point end) + { + startPoint=start; + endPoint=end; + } + + template + void DRRT::setTimeOut(float time) + { + timeOut = time; + } + + template + void DRRT::setHalfDimensions(double a, double b) + { + halfDimensionX=a; + halfDimensionY=b; + } + + template + void DRRT::setOrigin(Utils::Point pt) + { + origin=pt; + } + + template + std::vector > DRRT::getPointsOnPath(Utils::Point goal) + { + // clear vector before use + pathPoints.clear(); + Utils::Point cur; + int numBucket = findBucket(goal); + float minDist = 9999; + int min = -1; + + // checking point at minimum distance from goal + // in goal's bucket, + // If any change...... do here + for (int i = 0; i < bucket[numBucket].second.size(); ++i) + { + int id = bucket[numBucket].second[i]; + float Dist = dist(goal,tree[id].first); + if (Dist < minDist) + { + minDist = Dist; + min = id; + } + } + if (goal != tree[min].first) + { + pathPoints.push_back(goal); + } + cur = tree[min].first; + while(cur != getParent(cur)){ + pathPoints.push_back(cur); + cur = getParent(cur); + } + pathPoints.push_back(cur); + return pathPoints; + } + + template + std::vector > DRRT::getPath(Utils::Point start,Utils::Point goal){ + reWireRoot(start); + std::vector > path; + cout<<"Current Root"< + void DRRT::setStepLength(double length) + { + stepLength=length; + } + + template + void DRRT::setMaxIterations(int maxIt) + { + maxIterations=maxIt; + } + + + template + bool DRRT::saturation(){ + for (int i = 0; i < bucket.size(); ++i) + { + if (bucket[i].second.size() < PointsInBucket) + { + return true; + } + } + + return false; + } + + template + bool DRRT::dense(Utils::Point pt){ + int numBucket = findBucket(pt); + int density = bucket[numBucket].second.size(); + if (density > PointsInBucket) + { + return false; + } + return true; + + } + + template + bool DRRT::collision(Utils::Point pt){ + for (int i = 0; i < obstacles.size(); ++i) + { + std::vector obstacleBucket; + Utils::Point ob = obstacles[i].first; + int radius = obstacles[i].second; + int numbucket = findBucket(ob); + obstacleBucket.push_back(numbucket); + if (numbucket%(int)numX == 0) + { + obstacleBucket.push_back(numbucket + 1); + } + else if(numbucket % (int)numX == (int)numX - 1) + obstacleBucket.push_back(numbucket - 1); + else{ + obstacleBucket.push_back(numbucket + 1); + obstacleBucket.push_back(numbucket - 1); + } + + if (numbucket/(int)numX == 0) + { + obstacleBucket.push_back(numbucket + (int)numX); + } + + else if(numbucket/(int)numX == (int)numY - 1){ + obstacleBucket.push_back(numbucket - (int)numX); + } + + else{ + obstacleBucket.push_back(numbucket + (int)numX); + obstacleBucket.push_back(numbucket - (int)numX); + } + + for (int n = 0; n < obstacleBucket.size(); ++n) + { + int numBucket = obstacleBucket[n]; + for (int j = 0; j < bucket[numBucket].second.size(); ++j) + { + int id = bucket[numBucket].second[j]; + Utils::Point node = tree[id].first; + if (dist(pt,node) < radius) + { + cout<<"Obstacle\n"; + return false; + } + } + } + } + + + return true; + } + + template + bool DRRT:: plan() + { + // unordered_map, float > costMap; + cout<<"Planning\n"; + int count=0; + int check=0; + int numBucket = findBucket(startPoint); + bucket[numBucket].second.push_back(tree.size()); + //storing index of node in bucket + tree.push_back(std::pair< Utils::Point, Utils::Point > (startPoint,startPoint)); + root = startPoint; + Utils::Point next; + float start_time = clock(); + while( check < maxIterations && saturation()) + { + do{ + next = generatePoint(); + }while(checkPoint(next)==false || dense(next)==false); + int numBucket = findBucket(next); + /*storing index of node in bucket*/ + bucket[numBucket].second.push_back(tree.size()); + growTree(next); + check ++; + + } + float end_time = clock(); + + + cout< + + void DRRT::growTree(Utils::Point temp) + { + Utils::Point parent; + parent = findClosestNode(temp); + tree.push_back(std::pair< Utils::Point,Utils::Point >(temp,parent)); + } + + + template + void DRRT::setCheckPointFunction(bool (*f)(Utils::Point)) + { + userCheck=f; + } + + template + Utils::Point DRRT::findClosestNode(Utils::Point cur) + { + double min_dist=INT_MAX; + Utils::Point closest; + for(int i=0;i + Utils::Point DRRT::generatePoint() + { + Utils::Point temp; + int signX,signY; + + if(rand()%2==0) + signX=-1; + else + signX=1; + if(rand()%2==0) + signY=-1; + else + signY=1; + temp.x = origin.x + signX* ( rand() % (int)halfDimensionX ); + temp.y = origin.y + signY* ( rand() % (int)halfDimensionY ); + + + Utils::Point closest=findClosestNode(temp); + double theta = atan2(temp.y-closest.y,temp.x-closest.x); + double dis = dist(temp,closest); + if (dis < stepLength) + { + return temp; + } + Utils::Point next; + + next.x=closest.x+stepLength*cos(theta); + next.y=closest.y+stepLength*sin(theta); + return next; + } + + + template + bool DRRT::checkPoint(Utils::Point next) + { + return userCheck(next); + } + + template + float DRRT::cost(Utils::Point point){ + + + Utils::Point parent; + parent = getParent(point); + if (point == parent) + { + if (point == root) + { + return 0; + } + return 9999; + } + + else{ + float costValue; + costValue = cost(parent) + dist(parent,point); + // costMap[point] = costValue; + return costValue; + } + } + + template + std::vector< Utils::Point > DRRT::getChild(Utils::Point point){ + std::vector< Utils::Point > child; + int numBucket = findBucket(point); + std::vector list; + list.push_back(numBucket); + + // only searching one layer around newRoot + if (numBucket%(int)numX == 0) + { + list.push_back(numBucket + 1); + } + else if(numBucket % (int)numX == (int)numX - 1) + list.push_back(numBucket - 1); + else{ + list.push_back(numBucket + 1); + list.push_back(numBucket - 1); + } + + if (numBucket/(int)numX == 0) + { + list.push_back(numBucket + (int)numX); + } + + else if(numBucket/(int)numX == (int)numY - 1){ + list.push_back(numBucket - (int)numX); + } + + else{ + list.push_back(numBucket + (int)numX); + list.push_back(numBucket - (int)numX); + } + + for (int i = 0; i < list.size(); ++i) + { + int numBucket = list[i]; + for (int j = 0; j < bucket[numBucket].second.size(); ++j) + { + int id = bucket[numBucket].second[j]; + if (tree[id].second == point) + { + child.push_back(tree[id].first); + } + } + } + + return child; + }; + + + template + Utils::Point DRRT::getParent(Utils::Point cur) + { + int numBucket = findBucket(cur); + // iterate over cur point bucket + for(int i=0; i + double DRRT::dist(Utils::Point a,Utils::Point b) + { + return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y)); + } + + + template + void DRRT::reWireRoot(Utils::Point newRoot){ + // unordered_map, float> costMap; + std::vector > path = getPointsOnPath(newRoot); + + std::vector ids; + for (int i = 0; i < path.size(); ++i) + { + int numBucket = findBucket(path[i]); + for (int j = 0; j < bucket[numBucket].second.size(); ++j) + { + int id = bucket[numBucket].second[j]; + if (path[i] ==tree[id].first) + { + ids.push_back(id); + break; + } + } + } + if (path.size() != ids.size()) + { + path.erase(path.begin()); + } + cout<<"\n"< , Utils::Point > (path[0],path[0]); + root = path[0]; + for (int i = 1; i < ids.size(); ++i) + { + int id = ids[i]; + tree[id] = std::pair< Utils::Point, Utils::Point > (path[i],path[i - 1]); + } + + // New Root of tree is "nearest point" to given point if point is not in tree + // std::vector > temppath = getPointsOnPath(startPoint); + + std::vector > nodes; + nodes.push_back(path[0]); + + float start = clock(); + int ptr = 0; + cout<<"\n"; + while(((clock() - start)/CLOCKS_PER_SEC) < timeOut && ptr < nodes.size()) + { + int numBucket = findBucket(nodes[ptr]); + + int myId = -1; + for (int i = 0; i < bucket[numBucket].second.size(); ++i) + { + int id = bucket[numBucket].second[i]; + if (tree[id].first == nodes[ptr]) + { + myId = id; + break; + } + } + + std::vector list; //buckets adjacent to rewiring point + std::vector ids; //id of nodes in adjacent buckets + list.push_back(numBucket); + + // only searching one layer around newRoot + if (numBucket%(int)numX == 0) + { + list.push_back(numBucket + 1); + } + else if(numBucket % (int)numX == (int)numX - 1) + list.push_back(numBucket - 1); + else{ + list.push_back(numBucket + 1); + list.push_back(numBucket - 1); + } + + if (numBucket/(int)numX == 0) + { + list.push_back(numBucket + (int)numX); + } + + else if(numBucket/(int)numX == (int)numY - 1){ + list.push_back(numBucket - (int)numX); + } + + else{ + list.push_back(numBucket + (int)numX); + list.push_back(numBucket - (int)numX); + } + + //list contains bucket id for all buckets surrounding newroot + for (int i = 0; i < list.size(); ++i) + { + int numBucket = list[i]; + for (int j = 0; j < bucket[numBucket].second.size(); ++j) + { + int id = bucket[numBucket].second[j]; + if (id != myId) + { + ids.push_back(id); + } + } + } + + float score = cost(nodes[ptr]); + + + for (int i = 0; i < ids.size(); ++i) + { + int id = ids[i]; + if (dist(tree[id].first,tree[myId].first) < stepLength) + { + if ((cost(tree[id].first) + dist(tree[id].first, tree[myId].first)) < score) + { + tree[myId] = pair< Utils::Point, Utils::Point > (tree[myId].first, tree[id].first); + score = cost(tree[id].first) + dist(tree[id].first, tree[myId].first); + } + } + + + bool flag = false; + for (int j = 0; j < nodes.size(); ++j) + { + if (nodes[j] == tree[id].first) + { + flag = true; + break; + } + } + + if (!flag) + { + nodes.push_back(tree[id].first); + } + } + ptr++; + } + cout< #include +// #include #include "utils.hpp" namespace rrt @@ -17,12 +18,9 @@ namespace rrt Utils::Point startPoint; Utils::Point endPoint; double stepLength; - std::deque > pathPoints; + std::vector > pathPoints; int maxIterations; std::vector< std::pair< Utils::Point, Utils::Point > > tree; - - std::vector< std::pair< Utils::Point, Utils::Point > > tree1; - std::vector< std::pair< Utils::Point, Utils::Point > > tree2; unsigned int biasParameter; public: @@ -36,7 +34,7 @@ namespace rrt } virtual bool plan(); - virtual std::deque > getPointsOnPath(); + virtual std::vector > getPointsOnPath(); virtual void setEndPoints(Utils::Point start, Utils::Point end); virtual void setCheckPointFunction(bool (*f)(Utils::Point)); @@ -54,11 +52,11 @@ namespace rrt bool (*userCheck)(Utils::Point); bool checkPoint(Utils::Point pt); Utils::Point generatePoint(); - Utils::Point generateBiasedPoint(int); + Utils::Point generateBiasedPoint(); void growTree(Utils::Point); - std::pair, int> findClosestNode(Utils::Point); + Utils::Point findClosestNode(Utils::Point); Utils::Point getParent(Utils::Point); - std::pair ,Utils::Point > treeComplete(int*); + bool treeComplete(); void generatePath(Utils::Point first,Utils::Point last); double dist(Utils::Point a,Utils::Point b); }; @@ -105,13 +103,67 @@ namespace rrt void generatePath(Utils::Point first,Utils::Point last); double dist(Utils::Point a,Utils::Point b); }; + + + template + class DRRT: public RRT{ + private: + std::vector obstacleBucket; + std::vector > > bucket; + float numX; + float numY; + double halfDimensionX; + double halfDimensionY; + Utils::Point origin; + Utils::Point startPoint; + Utils::Point endPoint; + double stepLength; + std::vector > pathPoints; + int maxIterations; + std::vector< std::pair< Utils::Point, Utils::Point > > tree; + unsigned int biasParameter; + unsigned int BucketSize; + unsigned int PointsInBucket; + float timeOut; + Utils::Point root; + + public: + bool plan(); + std::vector > getPath(Utils::Point,Utils::Point); + std::vector > getPointsOnPath(Utils::Point); + std::vector, int > > obstacles; + void setEndPoints(Utils::Point start, Utils::Point end); + void setCheckPointFunction(bool (*f)(Utils::Point)); + void setStepLength(double value); + void setOrigin(Utils::Point origin); + void setHalfDimensions(double x,double y); + void setMaxIterations(int); + void setBucketSize(unsigned int); + void setPointsInBucket(unsigned int); + void generateGrid(); + void setTimeOut(float time); + + + private: + void reWireRoot(Utils::Point point); + int findBucket(Utils::Point); + bool saturation(); + bool collision(Utils::Point); + bool dense(Utils::Point); + bool (*userCheck)(Utils::Point); + bool checkPoint(Utils::Point pt); + Utils::Point generatePoint(); + Utils::Point findClosestNode(Utils::Point); + void growTree(Utils::Point); + Utils::Point getParent(Utils::Point); + bool treeComplete(); + void generatePath(Utils::Point first,Utils::Point last); + double dist(Utils::Point a,Utils::Point b); + float cost(Utils::Point point); + std::vector< Utils::Point > getChild(Utils::Point point); + }; } -//************* ToDo ************* -// Implement derived classes for variants of RRT -// Optimize the generate path and other -// Tweak with the parameters to check their effects on runtime and path -// Implement Pruning function to keep a check on size of tree #endif \ No newline at end of file diff --git a/include/RRT_implementation.hpp b/include/RRT_implementation.hpp index 5e9bbd9..7220afa 100644 --- a/include/RRT_implementation.hpp +++ b/include/RRT_implementation.hpp @@ -25,7 +25,7 @@ namespace rrt } template - std::deque > RRT::getPointsOnPath() + std::vector > RRT::getPointsOnPath() { return pathPoints; } @@ -52,9 +52,7 @@ namespace rrt { //std::cout<<"In Planning Loop"< next; - int arr[]={1}; - std::pair ,Utils::Point > mid = treeComplete(arr); - if(mid.first!=mid.second) + if(treeComplete()==true) { std::cout<<"Tree complete!!"< void RRT::growTree(Utils::Point next) { - //growing the tree by adding node + //growing the tree by adding node //std::cout<<"finding parent in tree of size = "< parent; - parent= findClosestNode(next).first; - //std::cout<<"current : "<, Utils::Point > (next,parent)); //std::cout<<"Tree grown"< - std::pair, int> RRT::findClosestNode(Utils::Point cur) + Utils::Point RRT::findClosestNode(Utils::Point cur) { double min_dist=INT_MAX; Utils::Point closest; @@ -124,7 +122,7 @@ namespace rrt closest=tree[i].first; } } - return std::make_pair(closest,1); + return closest; } template @@ -139,13 +137,13 @@ namespace rrt signX=1; if(rand()%2==0) signY=-1; - else + else signY=1; temp.x = origin.x + signX* ( rand() % (int)halfDimensionX ); temp.y = origin.y + signY* ( rand() % (int)halfDimensionY ); - Utils::Point closest=findClosestNode(temp).first; + Utils::Point closest=findClosestNode(temp); double theta = atan2(temp.y-closest.y,temp.x-closest.x); Utils::Point next; @@ -156,9 +154,9 @@ namespace rrt } template - Utils::Point RRT::generateBiasedPoint(int which) + Utils::Point RRT::generateBiasedPoint() { - Utils::Point closest=findClosestNode(endPoint).first; + Utils::Point closest=findClosestNode(endPoint); double theta = atan2(endPoint.y-closest.y,endPoint.x-closest.x); Utils::Point next; @@ -175,11 +173,11 @@ namespace rrt } template - std::pair ,Utils::Point > RRT::treeComplete(int arr[1]) + bool RRT::treeComplete() { //std::cout<<"Checking if tree is complete? "< cur) +{ + if(abs(cur.x)<2000 && abs(cur.y)<2000){ + Utils::Point a,b; + a.x = 530; + a.y = 570; + b = cur; + double dist = sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y)); + return true; + } + cout<<"False check"; + return false; +} + +int main() +{ + srand(time(NULL)); + Utils::Point start,finish,origin,checkpt; + start.x=30; + start.y=30; + finish.x=1500; + finish.y=1730; + origin.x=0; + origin.y=0; + checkpt.x = 400; + checkpt.y = 0; + + // steplength << bucketsize (finding child using bucket) + DRRT test; + test.setEndPoints(start,finish); + test.setCheckPointFunction(*(check)); + test.setStepLength(50); + test.setHalfDimensions(2000.0,2000.0); + test.setBucketSize(100); + test.setPointsInBucket(3); + test.setBiasParameter(100); + test.setOrigin(origin); + test.setMaxIterations(50000); + test.generateGrid(); + test.setTimeOut(0.010); + Utils::Point ob; + ob.x = 200; + ob.y = 0; + + + test.plan(); + vector > path; + + float starttime = clock(); + path =test.getPath(start,checkpt); + float endtime = clock(); + + cout<<"Time taken = "<<(endtime - starttime)/CLOCKS_PER_SEC; + cout<<"\n"< Date: Sun, 13 Aug 2017 02:44:11 +0530 Subject: [PATCH 4/6] RRT Connect --- include/RRT.hpp | 44 ++++++ include/RRTConnect.hpp | 331 +++++++++++++++++++++++++++++++++++++++++ src/main.cpp | 27 ++-- 3 files changed, 393 insertions(+), 9 deletions(-) create mode 100644 include/RRTConnect.hpp diff --git a/include/RRT.hpp b/include/RRT.hpp index 70c728d..c542273 100644 --- a/include/RRT.hpp +++ b/include/RRT.hpp @@ -61,6 +61,49 @@ namespace rrt void generatePath(Utils::Point first,Utils::Point last); double dist(Utils::Point a,Utils::Point b); }; + + template + class RRTConnect: public RRT{ + + public: + bool plan(); + std::vector > getPointsOnPath(); + + void setEndPoints(Utils::Point start, Utils::Point end); + void setCheckPointFunction(bool (*f)(Utils::Point)); + void setStepLength(double value); + void setOrigin(Utils::Point origin); + void setHalfDimensions(double x,double y); + void setBiasParameter(unsigned int); + void setMaxIterations(int); + private: + double halfDimensionX; + double halfDimensionY; + Utils::Point origin; + Utils::Point connectA; + Utils::Point connectB; + Utils::Point startPoint; + Utils::Point endPoint; + double stepLength; + std::vector > pathPoints; + int maxIterations; + std::vector< std::pair< Utils::Point, Utils::Point > > treeA; + std::vector< std::pair< Utils::Point, Utils::Point > > treeB; + std::vector< std::pair< Utils::Point, Utils::Point > > mainTree; + std::vector< std::pair< Utils::Point, Utils::Point > > supportTree; + + unsigned int biasParameter; + bool (*userCheck)(Utils::Point); + bool checkPoint(Utils::Point pt); + Utils::Point generatePoint(std::vector< std::pair< Utils::Point, Utils::Point > >); + Utils::Point generateBiasedPoint(Utils::Point ,std::vector< std::pair< Utils::Point, Utils::Point > >); + Utils::Point findClosestNode(Utils::Point,std::vector< std::pair< Utils::Point, Utils::Point > > tree); + void growTree(Utils::Point); + Utils::Point getParent(Utils::Point,std::vector< std::pair< Utils::Point, Utils::Point > > tree); + bool treeComplete(); + void generatePath(Utils::Point first,Utils::Point last); + double dist(Utils::Point a,Utils::Point b); + }; } //************* ToDo ************* @@ -70,4 +113,5 @@ namespace rrt // Implement Pruning function to keep a check on size of tree + #endif \ No newline at end of file diff --git a/include/RRTConnect.hpp b/include/RRTConnect.hpp new file mode 100644 index 0000000..b5ca20d --- /dev/null +++ b/include/RRTConnect.hpp @@ -0,0 +1,331 @@ +#include +#include "./RRT.hpp" +#include "./RRT_implementation.hpp" +#include "./utils.hpp" + +using namespace std; +namespace rrt +{ + template + void RRTConnect::setEndPoints(Utils::Point start, Utils::Point end) + { + startPoint=start; + endPoint=end; + } + + template + void RRTConnect::setHalfDimensions(double a, double b) + { + halfDimensionX=a; + halfDimensionY=b; + } + + template + void RRTConnect::setOrigin(Utils::Point pt) + { + origin=pt; + } + + template + std::vector > RRTConnect::getPointsOnPath() + { + return pathPoints; + } + + template + void RRTConnect::setStepLength(double value) + { + stepLength=value; + } + + template + void RRTConnect::setMaxIterations(int value) + { + maxIterations=value; + } + + template + bool RRTConnect:: plan() + { + int count=0; + int check=0; + treeA.push_back(std::pair< Utils::Point, Utils::Point > (startPoint,startPoint)); + treeB.push_back(std::pair< Utils::Point, Utils::Point > (endPoint,endPoint)); + + int start_time=clock(); + while( check < maxIterations) + { + //std::cout<<"In Planning Loop"< next; + + + if (check%2 == 0) + { + mainTree = treeA; + supportTree = treeB; + } + else{ + mainTree = treeB; + supportTree = treeA; + } + + if(treeComplete()==true) + { + std::cout<<"Tree complete!!"< + + void RRTConnect::growTree(Utils::Point temp) + { + //growing the tree by adding node + //std::cout<<"finding parent in tree of size = "< closest; + closest = findClosestNode(temp,treeA); + double theta = atan2(temp.y-closest.y,temp.x-closest.x); + double dis = dist(temp,closest); + if (dis > stepLength) + { + temp.x=closest.x+stepLength*cos(theta); + temp.y=closest.y+stepLength*sin(theta); + } + treeA.push_back( std::pair< Utils::Point, Utils::Point > (temp,closest)); + + closest = findClosestNode(temp,treeB); + theta = atan2(temp.y - closest.y , temp.x - closest.x); + dis = dist(temp,closest); + if (dis > stepLength) + { + temp.x=closest.x+stepLength*cos(theta); + temp.y=closest.y+stepLength*sin(theta); + } + treeB.push_back( std::pair< Utils::Point, Utils::Point > (temp,closest)); + //std::cout<<"Point Generated = "< + void RRTConnect::setCheckPointFunction(bool (*f)(Utils::Point)) + { + userCheck=f; + } + + template + Utils::Point RRTConnect::findClosestNode(Utils::Point cur,std::vector< std::pair< Utils::Point, Utils::Point > >tree) + { + double min_dist=INT_MAX; + Utils::Point closest; + for(int i=0;i + Utils::Point RRTConnect::generatePoint(std::vector< std::pair< Utils::Point, Utils::Point > > tree) + { + Utils::Point temp; + int signX,signY; + + if(rand()%2==0) + signX=-1; + else + signX=1; + if(rand()%2==0) + signY=-1; + else + signY=1; + temp.x = origin.x + signX* ( rand() % (int)halfDimensionX ); + temp.y = origin.y + signY* ( rand() % (int)halfDimensionY ); + + + return temp; + Utils::Point closest=findClosestNode(temp,tree); + double theta = atan2(temp.y-closest.y,temp.x-closest.x); + double dis = dist(temp,closest); + if (dis < stepLength) + { + return temp; + } + Utils::Point next; + + next.x=closest.x+stepLength*cos(theta); + next.y=closest.y+stepLength*sin(theta); + // std::cout<<"origin,"< + Utils::Point RRTConnect::generateBiasedPoint(Utils::Point endPoint,std::vector< std::pair< Utils::Point, Utils::Point > >tree) + { + Utils::Point closest=findClosestNode(endPoint,tree); + double theta = atan2(endPoint.y-closest.y,endPoint.x-closest.x); + + Utils::Point next; + next.x=closest.x+stepLength*cos(theta); + next.y=closest.y+stepLength*sin(theta); + //std::cout<<"Biased Point Generated = "< + bool RRTConnect::checkPoint(Utils::Point next) + { + return userCheck(next); + } + + template + bool RRTConnect::treeComplete() + { + std::vector< std::pair< Utils::Point, Utils::Point > > conn; + //std::cout<<"Checking if tree is complete? "<, Utils::Point > (connectA,connectB)); + // std::cout<<"distance = "< + void RRTConnect::setBiasParameter(unsigned int param) + { + biasParameter=param; + } + + template + void RRTConnect::generatePath(Utils::Point first,Utils::Point last) + { + + Utils::Point cur=connectA; + while(cur!=startPoint){ + pathPoints.insert(pathPoints.begin(),cur); + cur = getParent(cur,treeA); + } + + pathPoints.insert(pathPoints.begin(),cur); + + cur = connectB; + + // std::cout< parent= getParent(cur); + // std::cout<<"current : "< + Utils::Point RRTConnect::getParent(Utils::Point cur,std::vector< std::pair< Utils::Point, Utils::Point > >tree) + { + for(int i=0;i + double RRTConnect::dist(Utils::Point a,Utils::Point b) + { + return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y)); + } +} + diff --git a/src/main.cpp b/src/main.cpp index bc9d7da..10911d4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,13 +1,19 @@ #include #include "../include/RRT_implementation.hpp" + using namespace std; using namespace rrt; bool check(Utils::Point cur) { - if(abs(cur.x)<2000 && abs(cur.y)<2000) + if(abs(cur.x)<2000 && abs(cur.y)<2000){ + // if (cur.x < 550 && cur.x > 450 && cur.y < 550 & cur.y > 450) + // { + // return false; + // } return true; + } return false; } @@ -15,17 +21,17 @@ int main() { srand(time(NULL)); Utils::Point start,finish,origin; - start.x=-10; - start.y=10; - finish.x=1000; - finish.y=730; + start.x=30; + start.y=30; + finish.x=1500; + finish.y=1730; origin.x=0; origin.y=0; - RRT test; + RRTConnect test; test.setEndPoints(start,finish); test.setCheckPointFunction(*(check)); - test.setStepLength(200); + test.setStepLength(50); test.setHalfDimensions(2000.0,2000.0); test.setBiasParameter(100); test.setOrigin(origin); @@ -33,6 +39,9 @@ int main() test.plan(); cout<<"#################################################"< > path=test.getPointsOnPath(); + for(int i=0;i Date: Sun, 3 Sep 2017 01:20:00 +0530 Subject: [PATCH 5/6] Planner --- CMakeLists.txt | 6 +- include/DRRT.hpp | 570 +++++++++++++++++++++++++++++++++ include/RRT.hpp | 75 ++++- include/RRT_implementation.hpp | 35 +- test/main.cpp | 67 ++++ 5 files changed, 723 insertions(+), 30 deletions(-) create mode 100644 include/DRRT.hpp create mode 100644 test/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 3334ca3..aa66045 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,8 +4,10 @@ set(CMAKE_CXX_FLAGS "-std=c++11") include_directories("include") -set(SRCS src/Random_sampling.cpp - src/RT_RRT_star.cpp) +set(SRCS src/Random_sampling.cpp) set(PLANNERS planners) add_library(${PLANNERS} SHARED ${SRCS}) + +add_executable(target test/main.cpp) +target_link_libraries(target ${PLANNERS}) diff --git a/include/DRRT.hpp b/include/DRRT.hpp new file mode 100644 index 0000000..ef1b96a --- /dev/null +++ b/include/DRRT.hpp @@ -0,0 +1,570 @@ + +#include +#include "./RRT.hpp" +#include "./RRT_implementation.hpp" +#include "./utils.hpp" + +using namespace std; +namespace rrt +{ + + template + void DRRT::setBucketSize(unsigned int size){ + BucketSize = size; + } + + template + void DRRT::setPointsInBucket(unsigned int num){ + PointsInBucket = num; + } + + template + void DRRT::generateGrid(){ + numX = 2*halfDimensionX/BucketSize; + if (numX != (int)numX) + { + numX = (int)numX + 1; + } + numY = 2*halfDimensionY/BucketSize; + if (numY != (int)numY) + { + numY = (int)numY + 1; + } + int num = numX*numY; + for (int i = 0; i < num; ++i) + { + std::vector v; + bucket.push_back(std::pair > (i,v)); + } + } + + template < class T> + int DRRT::findBucket(Utils::Point pt){ + int x = pt.x + halfDimensionX ; + int y = pt.y + halfDimensionX ; + int numx = (int)(x/BucketSize) + 1; + if (numx > numX) + { + numx = numx - 1; + } + int numy = (int)(y/BucketSize) + 1; + if (numy > numY) + { + numy = numy - 1; + } + int num = (numy - 1)*numX + numx - 1; + return num; + } + + template + void DRRT::setEndPoints(Utils::Point start, Utils::Point end) + { + startPoint=start; + endPoint=end; + } + + template + void DRRT::setTimeOut(float time) + { + timeOut = time; + } + + template + void DRRT::setHalfDimensions(double a, double b) + { + halfDimensionX=a; + halfDimensionY=b; + } + + template + void DRRT::setOrigin(Utils::Point pt) + { + origin=pt; + } + + template + std::vector > DRRT::getPointsOnPath(Utils::Point goal) + { + // clear vector before use + pathPoints.clear(); + Utils::Point cur; + int numBucket = findBucket(goal); + float minDist = 9999; + int min = -1; + + // checking point at minimum distance from goal + // in goal's bucket, + // If any change...... do here + for (int i = 0; i < bucket[numBucket].second.size(); ++i) + { + int id = bucket[numBucket].second[i]; + float Dist = dist(goal,tree[id].first); + if (Dist < minDist) + { + minDist = Dist; + min = id; + } + } + if (goal != tree[min].first) + { + pathPoints.push_back(goal); + } + cur = tree[min].first; + while(cur != getParent(cur)){ + pathPoints.push_back(cur); + cur = getParent(cur); + } + pathPoints.push_back(cur); + return pathPoints; + } + + template + std::vector > DRRT::getPath(Utils::Point start,Utils::Point goal){ + reWireRoot(start); + std::vector > path; + cout<<"Current Root"< + void DRRT::setStepLength(double length) + { + stepLength=length; + } + + template + void DRRT::setMaxIterations(int maxIt) + { + maxIterations=maxIt; + } + + + template + bool DRRT::saturation(){ + for (int i = 0; i < bucket.size(); ++i) + { + if (bucket[i].second.size() < PointsInBucket) + { + return true; + } + } + + return false; + } + + template + bool DRRT::dense(Utils::Point pt){ + int numBucket = findBucket(pt); + int density = bucket[numBucket].second.size(); + if (density > PointsInBucket) + { + return false; + } + return true; + + } + + template + bool DRRT::collision(Utils::Point pt){ + for (int i = 0; i < obstacles.size(); ++i) + { + std::vector obstacleBucket; + Utils::Point ob = obstacles[i].first; + int radius = obstacles[i].second; + int numbucket = findBucket(ob); + obstacleBucket.push_back(numbucket); + if (numbucket%(int)numX == 0) + { + obstacleBucket.push_back(numbucket + 1); + } + else if(numbucket % (int)numX == (int)numX - 1) + obstacleBucket.push_back(numbucket - 1); + else{ + obstacleBucket.push_back(numbucket + 1); + obstacleBucket.push_back(numbucket - 1); + } + + if (numbucket/(int)numX == 0) + { + obstacleBucket.push_back(numbucket + (int)numX); + } + + else if(numbucket/(int)numX == (int)numY - 1){ + obstacleBucket.push_back(numbucket - (int)numX); + } + + else{ + obstacleBucket.push_back(numbucket + (int)numX); + obstacleBucket.push_back(numbucket - (int)numX); + } + + for (int n = 0; n < obstacleBucket.size(); ++n) + { + int numBucket = obstacleBucket[n]; + for (int j = 0; j < bucket[numBucket].second.size(); ++j) + { + int id = bucket[numBucket].second[j]; + Utils::Point node = tree[id].first; + if (dist(pt,node) < radius) + { + cout<<"Obstacle\n"; + return false; + } + } + } + } + + + return true; + } + + template + bool DRRT:: plan() + { + // unordered_map, float > costMap; + cout<<"Planning\n"; + int count=0; + int check=0; + int numBucket = findBucket(startPoint); + bucket[numBucket].second.push_back(tree.size()); + //storing index of node in bucket + tree.push_back(std::pair< Utils::Point, Utils::Point > (startPoint,startPoint)); + root = startPoint; + Utils::Point next; + float start_time = clock(); + while( check < maxIterations && saturation()) + { + do{ + next = generatePoint(); + }while(checkPoint(next)==false || dense(next)==false); + int numBucket = findBucket(next); + /*storing index of node in bucket*/ + bucket[numBucket].second.push_back(tree.size()); + growTree(next); + check ++; + + } + float end_time = clock(); + + + cout< + + void DRRT::growTree(Utils::Point temp) + { + Utils::Point parent; + parent = findClosestNode(temp); + tree.push_back(std::pair< Utils::Point,Utils::Point >(temp,parent)); + } + + + template + void DRRT::setCheckPointFunction(bool (*f)(Utils::Point)) + { + userCheck=f; + } + + template + Utils::Point DRRT::findClosestNode(Utils::Point cur) + { + double min_dist=INT_MAX; + Utils::Point closest; + for(int i=0;i + Utils::Point DRRT::generatePoint() + { + Utils::Point temp; + int signX,signY; + + if(rand()%2==0) + signX=-1; + else + signX=1; + if(rand()%2==0) + signY=-1; + else + signY=1; + temp.x = origin.x + signX* ( rand() % (int)halfDimensionX ); + temp.y = origin.y + signY* ( rand() % (int)halfDimensionY ); + + + Utils::Point closest=findClosestNode(temp); + double theta = atan2(temp.y-closest.y,temp.x-closest.x); + double dis = dist(temp,closest); + if (dis < stepLength) + { + return temp; + } + Utils::Point next; + + next.x=closest.x+stepLength*cos(theta); + next.y=closest.y+stepLength*sin(theta); + return next; + } + + + template + bool DRRT::checkPoint(Utils::Point next) + { + return userCheck(next); + } + + template + float DRRT::cost(Utils::Point point){ + + + Utils::Point parent; + parent = getParent(point); + if (point == parent) + { + if (point == root) + { + return 0; + } + return 9999; + } + + else{ + float costValue; + costValue = cost(parent) + dist(parent,point); + // costMap[point] = costValue; + return costValue; + } + } + + template + std::vector< Utils::Point > DRRT::getChild(Utils::Point point){ + std::vector< Utils::Point > child; + int numBucket = findBucket(point); + std::vector list; + list.push_back(numBucket); + + // only searching one layer around newRoot + if (numBucket%(int)numX == 0) + { + list.push_back(numBucket + 1); + } + else if(numBucket % (int)numX == (int)numX - 1) + list.push_back(numBucket - 1); + else{ + list.push_back(numBucket + 1); + list.push_back(numBucket - 1); + } + + if (numBucket/(int)numX == 0) + { + list.push_back(numBucket + (int)numX); + } + + else if(numBucket/(int)numX == (int)numY - 1){ + list.push_back(numBucket - (int)numX); + } + + else{ + list.push_back(numBucket + (int)numX); + list.push_back(numBucket - (int)numX); + } + + for (int i = 0; i < list.size(); ++i) + { + int numBucket = list[i]; + for (int j = 0; j < bucket[numBucket].second.size(); ++j) + { + int id = bucket[numBucket].second[j]; + if (tree[id].second == point) + { + child.push_back(tree[id].first); + } + } + } + + return child; + }; + + + template + Utils::Point DRRT::getParent(Utils::Point cur) + { + int numBucket = findBucket(cur); + // iterate over cur point bucket + for(int i=0; i + double DRRT::dist(Utils::Point a,Utils::Point b) + { + return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y)); + } + + + template + void DRRT::reWireRoot(Utils::Point newRoot){ + // unordered_map, float> costMap; + std::vector > path = getPointsOnPath(newRoot); + + std::vector ids; + for (int i = 0; i < path.size(); ++i) + { + int numBucket = findBucket(path[i]); + for (int j = 0; j < bucket[numBucket].second.size(); ++j) + { + int id = bucket[numBucket].second[j]; + if (path[i] ==tree[id].first) + { + ids.push_back(id); + break; + } + } + } + if (path.size() != ids.size()) + { + path.erase(path.begin()); + } + cout<<"\n"< , Utils::Point > (path[0],path[0]); + root = path[0]; + for (int i = 1; i < ids.size(); ++i) + { + int id = ids[i]; + tree[id] = std::pair< Utils::Point, Utils::Point > (path[i],path[i - 1]); + } + + // New Root of tree is "nearest point" to given point if point is not in tree + // std::vector > temppath = getPointsOnPath(startPoint); + + std::vector > nodes; + nodes.push_back(path[0]); + + float start = clock(); + int ptr = 0; + cout<<"\n"; + while(((clock() - start)/CLOCKS_PER_SEC) < timeOut && ptr < nodes.size()) + { + int numBucket = findBucket(nodes[ptr]); + + int myId = -1; + for (int i = 0; i < bucket[numBucket].second.size(); ++i) + { + int id = bucket[numBucket].second[i]; + if (tree[id].first == nodes[ptr]) + { + myId = id; + break; + } + } + + std::vector list; //buckets adjacent to rewiring point + std::vector ids; //id of nodes in adjacent buckets + list.push_back(numBucket); + + // only searching one layer around newRoot + if (numBucket%(int)numX == 0) + { + list.push_back(numBucket + 1); + } + else if(numBucket % (int)numX == (int)numX - 1) + list.push_back(numBucket - 1); + else{ + list.push_back(numBucket + 1); + list.push_back(numBucket - 1); + } + + if (numBucket/(int)numX == 0) + { + list.push_back(numBucket + (int)numX); + } + + else if(numBucket/(int)numX == (int)numY - 1){ + list.push_back(numBucket - (int)numX); + } + + else{ + list.push_back(numBucket + (int)numX); + list.push_back(numBucket - (int)numX); + } + + //list contains bucket id for all buckets surrounding newroot + for (int i = 0; i < list.size(); ++i) + { + int numBucket = list[i]; + for (int j = 0; j < bucket[numBucket].second.size(); ++j) + { + int id = bucket[numBucket].second[j]; + if (id != myId) + { + ids.push_back(id); + } + } + } + + float score = cost(nodes[ptr]); + + + for (int i = 0; i < ids.size(); ++i) + { + int id = ids[i]; + if (dist(tree[id].first,tree[myId].first) < stepLength) + { + if ((cost(tree[id].first) + dist(tree[id].first, tree[myId].first)) < score) + { + tree[myId] = pair< Utils::Point, Utils::Point > (tree[myId].first, tree[id].first); + score = cost(tree[id].first) + dist(tree[id].first, tree[myId].first); + } + } + + + bool flag = false; + for (int j = 0; j < nodes.size(); ++j) + { + if (nodes[j] == tree[id].first) + { + flag = true; + break; + } + } + + if (!flag) + { + nodes.push_back(tree[id].first); + } + } + ptr++; + } + cout< #include +// #include #include "utils.hpp" namespace rrt @@ -17,7 +18,7 @@ namespace rrt Utils::Point startPoint; Utils::Point endPoint; double stepLength; - std::deque > pathPoints; + std::vector > pathPoints; int maxIterations; std::vector< std::pair< Utils::Point, Utils::Point > > tree; std::vector< std::pair< Utils::Point, Utils::Point > > tree1; @@ -35,7 +36,7 @@ namespace rrt } virtual bool plan(); - virtual std::deque > getPointsOnPath(); + virtual std::vector > getPointsOnPath(); virtual void setEndPoints(Utils::Point start, Utils::Point end); virtual void setCheckPointFunction(bool (*f)(Utils::Point)); @@ -53,11 +54,11 @@ namespace rrt bool (*userCheck)(Utils::Point); bool checkPoint(Utils::Point pt); Utils::Point generatePoint(); - Utils::Point generateBiasedPoint(int); + Utils::Point generateBiasedPoint(); void growTree(Utils::Point); - std::pair, int> findClosestNode(Utils::Point); + Utils::Point findClosestNode(Utils::Point); Utils::Point getParent(Utils::Point); - std::pair ,Utils::Point > treeComplete(int*); + bool treeComplete(); void generatePath(Utils::Point first,Utils::Point last); double dist(Utils::Point a,Utils::Point b); }; @@ -104,13 +105,67 @@ namespace rrt void generatePath(Utils::Point first,Utils::Point last); double dist(Utils::Point a,Utils::Point b); }; + + + template + class DRRT: public RRT{ + private: + std::vector obstacleBucket; + std::vector > > bucket; + float numX; + float numY; + double halfDimensionX; + double halfDimensionY; + Utils::Point origin; + Utils::Point startPoint; + Utils::Point endPoint; + double stepLength; + std::vector > pathPoints; + int maxIterations; + std::vector< std::pair< Utils::Point, Utils::Point > > tree; + unsigned int biasParameter; + unsigned int BucketSize; + unsigned int PointsInBucket; + float timeOut; + Utils::Point root; + + public: + bool plan(); + std::vector > getPath(Utils::Point,Utils::Point); + std::vector > getPointsOnPath(Utils::Point); + std::vector, int > > obstacles; + void setEndPoints(Utils::Point start, Utils::Point end); + void setCheckPointFunction(bool (*f)(Utils::Point)); + void setStepLength(double value); + void setOrigin(Utils::Point origin); + void setHalfDimensions(double x,double y); + void setMaxIterations(int); + void setBucketSize(unsigned int); + void setPointsInBucket(unsigned int); + void generateGrid(); + void setTimeOut(float time); + + + private: + void reWireRoot(Utils::Point point); + int findBucket(Utils::Point); + bool saturation(); + bool collision(Utils::Point); + bool dense(Utils::Point); + bool (*userCheck)(Utils::Point); + bool checkPoint(Utils::Point pt); + Utils::Point generatePoint(); + Utils::Point findClosestNode(Utils::Point); + void growTree(Utils::Point); + Utils::Point getParent(Utils::Point); + bool treeComplete(); + void generatePath(Utils::Point first,Utils::Point last); + double dist(Utils::Point a,Utils::Point b); + float cost(Utils::Point point); + std::vector< Utils::Point > getChild(Utils::Point point); + }; } -//************* ToDo ************* -// Implement derived classes for variants of RRT -// Optimize the generate path and other -// Tweak with the parameters to check their effects on runtime and path -// Implement Pruning function to keep a check on size of tree diff --git a/include/RRT_implementation.hpp b/include/RRT_implementation.hpp index 5e9bbd9..7220afa 100644 --- a/include/RRT_implementation.hpp +++ b/include/RRT_implementation.hpp @@ -25,7 +25,7 @@ namespace rrt } template - std::deque > RRT::getPointsOnPath() + std::vector > RRT::getPointsOnPath() { return pathPoints; } @@ -52,9 +52,7 @@ namespace rrt { //std::cout<<"In Planning Loop"< next; - int arr[]={1}; - std::pair ,Utils::Point > mid = treeComplete(arr); - if(mid.first!=mid.second) + if(treeComplete()==true) { std::cout<<"Tree complete!!"< void RRT::growTree(Utils::Point next) { - //growing the tree by adding node + //growing the tree by adding node //std::cout<<"finding parent in tree of size = "< parent; - parent= findClosestNode(next).first; - //std::cout<<"current : "<, Utils::Point > (next,parent)); //std::cout<<"Tree grown"< - std::pair, int> RRT::findClosestNode(Utils::Point cur) + Utils::Point RRT::findClosestNode(Utils::Point cur) { double min_dist=INT_MAX; Utils::Point closest; @@ -124,7 +122,7 @@ namespace rrt closest=tree[i].first; } } - return std::make_pair(closest,1); + return closest; } template @@ -139,13 +137,13 @@ namespace rrt signX=1; if(rand()%2==0) signY=-1; - else + else signY=1; temp.x = origin.x + signX* ( rand() % (int)halfDimensionX ); temp.y = origin.y + signY* ( rand() % (int)halfDimensionY ); - Utils::Point closest=findClosestNode(temp).first; + Utils::Point closest=findClosestNode(temp); double theta = atan2(temp.y-closest.y,temp.x-closest.x); Utils::Point next; @@ -156,9 +154,9 @@ namespace rrt } template - Utils::Point RRT::generateBiasedPoint(int which) + Utils::Point RRT::generateBiasedPoint() { - Utils::Point closest=findClosestNode(endPoint).first; + Utils::Point closest=findClosestNode(endPoint); double theta = atan2(endPoint.y-closest.y,endPoint.x-closest.x); Utils::Point next; @@ -175,11 +173,11 @@ namespace rrt } template - std::pair ,Utils::Point > RRT::treeComplete(int arr[1]) + bool RRT::treeComplete() { //std::cout<<"Checking if tree is complete? "< cur) +{ + if(abs(cur.x)<2000 && abs(cur.y)<2000){ + Utils::Point a,b; + a.x = 530; + a.y = 570; + b = cur; + double dist = sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y)); + return true; + } + cout<<"False check"; + return false; +} + +int main() +{ + srand(time(NULL)); + Utils::Point start,finish,origin,checkpt; + start.x=30; + start.y=30; + finish.x=1500; + finish.y=1730; + origin.x=0; + origin.y=0; + checkpt.x = 400; + checkpt.y = 0; + + // steplength << bucketsize (finding child using bucket) + DRRT test; + test.setEndPoints(start,finish); + test.setCheckPointFunction(*(check)); + test.setStepLength(50); + test.setHalfDimensions(2000.0,2000.0); + test.setBucketSize(100); + test.setPointsInBucket(3); + test.setBiasParameter(100); + test.setOrigin(origin); + test.setMaxIterations(50000); + test.generateGrid(); + test.setTimeOut(0.010); + Utils::Point ob; + ob.x = 200; + ob.y = 0; + + + test.plan(); + vector > path; + + float starttime = clock(); + path =test.getPath(start,checkpt); + float endtime = clock(); + + cout<<"Time taken = "<<(endtime - starttime)/CLOCKS_PER_SEC; + cout<<"\n"< Date: Sun, 3 Sep 2017 14:25:59 +0530 Subject: [PATCH 6/6] Updated Grid_Id,cost,rewire_node,rewire_root,closest_node,getParent --- CMakeLists.txt | 3 +- include/RT_RRT_star.hpp | 202 ++++++++++++++++++++++++++++++++-------- src/RT_RRT_star.cpp | 5 +- 3 files changed, 164 insertions(+), 46 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index aa66045..412c10b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,8 @@ set(CMAKE_CXX_FLAGS "-std=c++11") include_directories("include") -set(SRCS src/Random_sampling.cpp) +set(SRCS src/Random_sampling.cpp + src/RT_RRT_star.cpp) set(PLANNERS planners) add_library(${PLANNERS} SHARED ${SRCS}) diff --git a/include/RT_RRT_star.hpp b/include/RT_RRT_star.hpp index 74927a5..f09dc3f 100644 --- a/include/RT_RRT_star.hpp +++ b/include/RT_RRT_star.hpp @@ -17,8 +17,8 @@ namespace rrt { // Queue at the root of the tree std::queue, Utils::Point > > Qs; - // Grid based subset of nodes for grid based search - std::map , std::vector > > grid_nodes; + // Grid based subset of nodes for grid based search, value === id of point in main tree + std::map , std::vector > grid_nodes; // Position of the agent Utils::Point Xa; @@ -50,6 +50,11 @@ namespace rrt { // Useful parameters for setting some search parameters unsigned int width, length; + //half Dimension + unsigned int halfDimensionX, halfDimensionY; + + unsigned int bucketSize; + public: RT_RRT(); @@ -66,25 +71,39 @@ namespace rrt { /** @brief Return Grid Id */ - std::pair Grid_Id(Utils::Point gride_idx); + std::pair Grid_Id(Utils::Point gride_idx){ + int x = gride_idx.x + halfDimensionX; + int y = gride_idx.y + halfDimensionY; + + unsigned int gridX = x/bucketSize; + unsigned int gridY = y/bucketSize; + + unsigned int maxGridInX = 2*halfDimensionX/bucketSize; + unsigned int maxGridInY = 2*halfDimensionY/bucketSize; + + if (gridX == maxGridInX) + { + gridX --; + } + + if (gridY == maxGridInY) + { + gridY --; + } + + return std::pair (gridX, gridY); + } /** @brief Return cost */ - std::pair > cost(Utils::point child, int count=0) + std::pair > cost(Utils::Point child) { - if (child==Xa) - return std::pair > (0,Xa); - for(int j=0;i > here = cost(tree[j].second,1); - if (count) - return std::pair > (dist(child,tree[j].second)+here.first.first,here.second); - else - return std::pair > (dist(child,tree[j].second)+here.first.first,tree[j].second); - } - } + if (child==Xa) + return std::pair > (0,Xa); + else{ + Utils::Point parent = getParent(child); + return std::pair >(cost(parent).first + dist(child,parent), parent); + } } /** @brief Simultaneously expand and rewire the tree @@ -103,22 +122,41 @@ namespace rrt { */ void rewire_node(std::queue, Utils::Point > > Qr) { - Utils::Point me = Qr.pop(); - std::pair> now = getCost(me); - int cost = now.first; - Utils::Point parent = now.second; - std::vector > neighbours= find_near_nodes(Qr); - for (int i=0;i neighbour = neighbours[i]; - if (cost > cost - dist(me,parent) + dist(parent,neighbour) + dist(neighbour,me)) + float start = clock(); + float timeLimit; + while(clock() - start < timeLimit && !Qr.empty()){ + Utils::Point cur = Qr.front(); + std::pair> now = cost(cur); + double myScore = now.first; + Utils::Point parent = now.second; + std::vector > neighbours= find_near_nodes(cur); + + int myId; + std::pair gridId = Grid_Id(cur); + std::vector ids = grid_nodes[gridId]; + for (int i = 0; i < ids.size(); ++i) + { + if (tree[ids[i]].first == cur) + { + myId = ids[i]; + break; + } + } + + for (int i=0;i neighbour = neighbours[i]; + if (cost(neighbour).first + dist(neighbour,cur) < myScore) + { + myScore = cost(neighbour).first + dist(neighbour,cur); + tree[myId].second = neighbour; + } + if (find(Qr.front(), Qr.back() + 1 , neighbour) != Qr.back() + 1) + { + Qr.push(neighbour); + } } + Qr.pop(); } } @@ -126,19 +164,48 @@ namespace rrt { */ void rewire_root(std::queue, Utils::Point > > Qs) { - std::vector > neighbours= find_near_nodes(Xa); - for (int i=0;i neighbour = neighbours[i]; - if (cost > cost - dist(me,Xa) + dist(Xa,neighbour) + dist(neighbour,me)) + Qs.push(Xa); + } + + float start = clock(); + + + float timeLimit; //to declare by calling file + + while(!Qs.empty() && (clock() - start) > timeLimit){ + Utils::Point cur = Qs.front(); + std::vector > neighbours= find_near_nodes(cur); + float myScore = cost(cur).first; + std::pair gridID = Grid_Id(cur); + int myId; + for (int i = 0; i < grid_nodes[gridID].size(); ++i) { - for(int j=0;i neighbour = neighbours[i]; + float nbScore = cost(neighbour).first; + if (nbScore + dist(neighbour,cur) < myScore) + { + myScore = nbScore; + tree[myId].second = neighbour; + } + if (find(Qs.front(), Qs.back() + 1, neighbour) != Qs.back() +1) + { + Qs.push(neighbour); + } + } + Qs.pop(); } + } /** @brief Update the radius of neareset nodes prior to calling `find_near_nodes` @@ -147,11 +214,64 @@ namespace rrt { /** @brief Find the closest node */ - Utils::Point closest_node(Utils::Point rand); + Utils::Point closest_node(Utils::Point rand){ + Utils::Point closest; + + std::pair gridId = Grid_Id(rand); + unsigned int maxGridInX = 2*halfDimensionX/bucketSize; + unsigned int maxGridInY = 2*halfDimensionY/bucketSize; + std::vector > adjacentGrid; + adjacentGrid.push_back(gridId); + int x[] = {-1,-1,-1,0,0,1,1,1}; + int y[] = {-1,0,1,-1,1,-1,0,1}; + for (int i = 0; i < 8; ++i) + { + unsigned int gridX = gridId.first + x[i]; + unsigned int gridY = gridId.second + y[i]; + if (gridX >= 0 && gridX < maxGridInX && gridY >=0 && gridY < maxGridInY) + { + adjacentGrid.push_back(std::pair (gridX,gridY)); + } + } + float minDist = 999999; + for (int i = 0; i < adjacentGrid.size(); ++i) + { + std::vector ids = grid_nodes[adjacentGrid[i]]; + for (int j = 0; j < ids.size(); ++j) + { + float distance = dist(rand,tree[ids[j]].first); + if (distance < minDist) + { + minDist = distance; + closest = tree[ids[j]].first; + } + } + } + + return closest; + } /** @brief Verify if the line crosses any obstacle */ bool line_path_obs(Utils::Point p1, Utils::Point p2); + + + /**@brief Return Parent of Node + */ + Utils::Point getParent(Utils::Point cur) + { + std::pair gridId= Grid_Id(cur); + std::vector ids = grid_nodes[gridId]; + // iterate over cur point bucket + for(int i=0; i - std::pair RT_RRT::Grid_Id(Utils::Point node) { - - } + template void RT_RRT::add_node_to_tree(Utils::Point rand) {