Files
PathPlanning/Sampling-based Planning/rrt_3D/utils3D.py
T

167 lines
4.5 KiB
Python
Raw Normal View History

2020-06-24 22:01:12 -07:00
import numpy as np
from numpy.matlib import repmat
import pyrr as pyrr
import os
import sys
2020-07-25 23:16:54 -07:00
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + "/../../Sampling-based Planning/")
2020-06-24 22:01:12 -07:00
from rrt_3D.plot_util3D import visualization
2020-07-25 23:16:54 -07:00
2020-06-24 22:01:12 -07:00
def getRay(x, y):
direc = [y[0] - x[0], y[1] - x[1], y[2] - x[2]]
return np.array([x, direc])
2020-07-25 23:16:54 -07:00
2020-06-24 22:01:12 -07:00
def getAABB(blocks):
AABB = []
for i in blocks:
AABB.append(np.array([np.add(i[0:3], -0), np.add(i[3:6], 0)])) # make AABBs alittle bit of larger
return AABB
def getDist(pos1, pos2):
return np.sqrt(sum([(pos1[0] - pos2[0]) ** 2, (pos1[1] - pos2[1]) ** 2, (pos1[2] - pos2[2]) ** 2]))
2020-07-25 23:16:54 -07:00
2020-06-24 22:01:12 -07:00
''' The following utils can be used for rrt or rrt*,
required param initparams should have
env, environement generated from env3D
V, node set
E, edge set
i, nodes added
maxiter, maximum iteration allowed
stepsize, leaf growth restriction
'''
def sampleFree(initparams):
'''biased sampling'''
x = np.random.uniform(initparams.env.boundary[0:3], initparams.env.boundary[3:6])
i = np.random.random()
if isinside(initparams, x):
return sampleFree(initparams)
else:
2020-07-25 23:16:54 -07:00
if i < 0.1:
return initparams.env.goal + 1
else:
return np.array(x)
2020-06-25 01:53:19 -07:00
return np.array(x)
2020-06-24 22:01:12 -07:00
def isinside(initparams, x):
'''see if inside obstacle'''
for i in initparams.env.blocks:
if i[0] <= x[0] < i[3] and i[1] <= x[1] < i[4] and i[2] <= x[2] < i[5]:
return True
return False
2020-07-25 23:16:54 -07:00
2020-06-25 18:18:33 -07:00
def isinbound(i, x):
if i[0] <= x[0] < i[3] and i[1] <= x[1] < i[4] and i[2] <= x[2] < i[5]:
return True
return False
2020-06-24 22:01:12 -07:00
2020-07-25 23:16:54 -07:00
2020-06-24 22:01:12 -07:00
def isCollide(initparams, x, y):
'''see if line intersects obstacle'''
ray = getRay(x, y)
dist = getDist(x, y)
2020-07-25 23:16:54 -07:00
if not isinbound(initparams.env.boundary, y):
2020-06-25 18:18:33 -07:00
return True
2020-06-24 22:01:12 -07:00
for i in getAABB(initparams.env.blocks):
shot = pyrr.geometric_tests.ray_intersect_aabb(ray, i)
if shot is not None:
dist_wall = getDist(x, shot)
if dist_wall <= dist: # collide
return True
for i in initparams.env.balls:
shot = pyrr.geometric_tests.ray_intersect_sphere(ray, i)
if shot != []:
2020-06-25 18:18:33 -07:00
dists_ball = [getDist(x, j) for j in shot]
if all(dists_ball <= dist): # collide
2020-06-24 22:01:12 -07:00
return True
return False
def nearest(initparams, x):
V = np.array(initparams.V)
if initparams.i == 0:
return initparams.V[0]
xr = repmat(x, len(V), 1)
dists = np.linalg.norm(xr - V, axis=1)
return initparams.V[np.argmin(dists)]
def steer(initparams, x, y):
direc = (y - x) / np.linalg.norm(y - x)
xnew = x + initparams.stepsize * direc
return xnew
def near(initparams, x):
2020-06-25 01:53:19 -07:00
cardV = len(initparams.V)
eta = initparams.eta
gamma = initparams.gamma
2020-07-25 23:16:54 -07:00
r = min(gamma * (np.log(cardV) / cardV), eta)
2020-06-25 01:53:19 -07:00
if initparams.done: r = 1
2020-06-24 22:01:12 -07:00
V = np.array(initparams.V)
if initparams.i == 0:
2020-06-25 18:55:55 -07:00
return [initparams.V[0]]
2020-06-24 22:01:12 -07:00
xr = repmat(x, len(V), 1)
inside = np.linalg.norm(xr - V, axis=1) < r
nearpoints = V[inside]
return np.array(nearpoints)
def cost(initparams, x):
'''here use the additive recursive cost function'''
if all(x == initparams.env.start):
return 0
2020-06-25 01:53:19 -07:00
xparent = initparams.Parent[hash3D(x)]
2020-06-24 22:01:12 -07:00
return cost(initparams, xparent) + getDist(x, xparent)
def path(initparams, Path=[], dist=0):
x = initparams.env.goal
while not all(x == initparams.env.start):
2020-06-25 01:53:19 -07:00
x2 = initparams.Parent[hash3D(x)]
2020-06-24 22:01:12 -07:00
Path.append(np.array([x, x2]))
dist += getDist(x, x2)
x = x2
return Path, dist
2020-07-25 23:16:54 -07:00
2020-06-25 01:53:19 -07:00
def hash3D(x):
2020-07-25 23:16:54 -07:00
return str(x[0]) + ' ' + str(x[1]) + ' ' + str(x[2])
2020-06-25 01:53:19 -07:00
def dehash(x):
return np.array([float(i) for i in x.split(' ')])
2020-07-25 23:16:54 -07:00
2020-06-24 22:01:12 -07:00
class edgeset(object):
def __init__(self):
self.E = {}
2020-07-25 23:16:54 -07:00
def add_edge(self, edge):
x, y = hash3D(edge[0]), hash3D(edge[1])
2020-06-24 22:01:12 -07:00
if x in self.E:
self.E[x].append(y)
else:
self.E[x] = [y]
2020-07-25 23:16:54 -07:00
def remove_edge(self, edge):
x, y = edge[0], edge[1]
2020-06-25 01:53:19 -07:00
self.E[hash3D(x)].remove(hash3D(y))
2020-06-24 22:01:12 -07:00
def get_edge(self):
edges = []
for v in self.E:
for n in self.E[v]:
2020-07-25 23:16:54 -07:00
# if (n,v) not in edges:
edges.append((dehash(v), dehash(n)))
return edges