-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
170 additions
and
5 deletions.
There are no files selected for viewing
Binary file modified
BIN
+910 Bytes
(140%)
Sampling_based_Planning/rrt_3D/__pycache__/queue.cpython-37.pyc
Binary file not shown.
Binary file modified
BIN
+0 Bytes
(100%)
Sampling_based_Planning/rrt_3D/__pycache__/utils3D.cpython-37.pyc
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,166 @@ | ||
# informed RRT star in 3D | ||
# informed RRT star in 3D | ||
""" | ||
This is IRRT* code for 3D | ||
@author: yue qi | ||
source: J. D. Gammell, S. S. Srinivasa, and T. D. Barfoot, “Informed RRT*: | ||
Optimal sampling-based path planning focused via direct sampling of | ||
an admissible ellipsoidal heuristic,” in IROS, 2997–3004, 2014. | ||
""" | ||
import numpy as np | ||
import matplotlib.pyplot as plt | ||
import time | ||
import copy | ||
|
||
|
||
import os | ||
import sys | ||
|
||
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + "/../../Sampling_based_Planning/") | ||
from rrt_3D.env3D import env | ||
from rrt_3D.utils3D import getDist, sampleFree, nearest, steer, isCollide, isinside, near, nearest | ||
from rrt_3D.plot_util3D import make_get_proj, draw_block_list, draw_Spheres, draw_obb, draw_line, make_transparent | ||
from rrt_3D.queue import MinheapPQ | ||
|
||
class IRRT: | ||
|
||
def __init__(self): | ||
self.env = env() | ||
self.xstart, self.xgoal = tuple(self.env.start), tuple(self.env.goal) | ||
self.x0, self.xt = tuple(self.env.start), tuple(self.env.goal) | ||
self.Parent = {} | ||
self.N = 10000 # used for determining how many batches needed | ||
self.ind = 0 | ||
self.i = 0 | ||
# rrt* near | ||
self.stepsize = 0.5 | ||
self.gamma = 500 | ||
self.eta = self.stepsize | ||
self.rgoal = self.stepsize | ||
|
||
self.done = False | ||
|
||
def Informed_rrt(self): | ||
self.V = [self.xstart] | ||
self.E = set() | ||
self.Xsoln = set() | ||
self.T = (self.V, self.E) | ||
|
||
c = 1 | ||
while self.ind <= self.N: | ||
print(self.ind) | ||
# print(self.i) | ||
if len(self.Xsoln) == 0: | ||
cbest = np.inf | ||
else: | ||
cbest = min({self.cost(xsln) for xsln in self.Xsoln}) | ||
xrand = self.Sample(self.xstart, self.xgoal, cbest) | ||
xnearest = nearest(self, xrand) | ||
xnew, dist = steer(self, xnearest, xrand) | ||
# print(xnew) | ||
collide, _ = isCollide(self, xnearest, xnew, dist=dist) | ||
if not collide: | ||
self.V.append(xnew) | ||
Xnear = near(self, xnew) | ||
xmin = xnearest | ||
cmin = self.cost(xmin) + c * self.line(xnearest, xnew) | ||
for xnear in Xnear: | ||
xnear = tuple(xnear) | ||
cnew = self.cost(xnear) + c * self.line(xnear, xnew) | ||
if cnew < cmin: | ||
collide, _ = isCollide(self, xnear, xnew) | ||
if not collide: | ||
xmin = xnear | ||
cmin = cnew | ||
self.E.add((xmin, xnew)) | ||
self.Parent[xnew] = xmin | ||
|
||
for xnear in Xnear: | ||
xnear = tuple(xnear) | ||
cnear = self.cost(xnear) | ||
cnew = self.cost(xnew) + c * self.line(xnew, xnear) | ||
# rewire | ||
if cnew < cnear: | ||
collide, _ = isCollide(self, xnew, xnear) | ||
if not collide: | ||
xparent = self.Parent[xnear] | ||
self.E.difference_update((xparent, xnear)) | ||
self.E.add((xnew, xnear)) | ||
self.Parent[xnear] = xnew | ||
self.i += 1 | ||
if self.InGoalRegion(xnew): | ||
print('reached') | ||
self.Xsoln.add(xnew) | ||
|
||
self.ind += 1 | ||
# return tree | ||
return self.T | ||
|
||
def Sample(self, xstart, xgoal, cmax): | ||
# sample within a eclipse | ||
if cmax < np.inf: | ||
cmin = getDist(xgoal, xstart) | ||
xcenter = np.array([(xgoal[0] + xstart[0]) / 2, (xgoal[1] + xstart[1]) / 2, (xgoal[2] + xstart[2]) / 2]) | ||
C = self.RotationToWorldFrame(xstart, xgoal) | ||
r = np.zeros(3) | ||
r[0] = cmax /2 | ||
for i in range(1,3): | ||
r[i] = np.sqrt(cmax**2 - cmin**2) / 2 | ||
L = np.diag(r) # R3*3 | ||
xball = self.SampleUnitBall() # np.array | ||
x = C@L@xball + xcenter | ||
if not isinside(self, x): # intersection with the state space | ||
xrand = x | ||
else: | ||
return self.Sample(xstart, xgoal, cmax) | ||
else: | ||
xrand = sampleFree(self, bias = 0.0) | ||
return xrand | ||
|
||
def SampleUnitBall(self): | ||
# uniform sampling in spherical coordinate system in 3D | ||
# sample radius | ||
r = np.random.uniform(0.0, 1.0) | ||
theta = np.random.uniform(0, np.pi) | ||
phi = np.random.uniform(0, 2 * np.pi) | ||
x = r * np.sin(theta) * np.cos(phi) | ||
y = r * np.sin(theta) * np.sin(phi) | ||
z = r * np.cos(theta) | ||
return np.array([x,y,z]) | ||
|
||
def RotationToWorldFrame(self, xstart, xgoal): | ||
# S0(n): such that the xstart and xgoal are the center points | ||
d = getDist(xstart, xgoal) | ||
xstart, xgoal = np.array(xstart), np.array(xgoal) | ||
a1 = (xgoal - xstart) / d | ||
M = np.outer(a1,[1,0,0]) | ||
U, S, V = np.linalg.svd(M) | ||
C = U@np.diag([1, 1, np.linalg.det(U)*np.linalg.det(V)])@V.T | ||
return C | ||
|
||
def InGoalRegion(self, x): | ||
# Xgoal = {x in Xfree | \\x-xgoal\\2 <= rgoal} | ||
return getDist(x, self.xgoal) <= self.rgoal | ||
|
||
def cost(self, x): | ||
# actual cost | ||
'''here use the additive recursive cost function''' | ||
if x == self.xstart: | ||
return 0.0 | ||
if x not in self.Parent: | ||
return np.inf | ||
return self.cost(self.Parent[x]) + getDist(x, self.Parent[x]) | ||
|
||
def line(self, x, y): | ||
return getDist(x, y) | ||
|
||
def g_hat(self, x): | ||
# heuristic estimate from start to x | ||
return getDist(x, self.xstart) | ||
|
||
def h_hat(self, x): | ||
# heuristic estimate from x to goal | ||
return getDist(x, self.xgoal) | ||
|
||
if __name__ == '__main__': | ||
A = IRRT() | ||
A.Informed_rrt() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters