utils3D.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. import numpy as np
  2. from numpy.matlib import repmat
  3. import pyrr as pyrr
  4. import os
  5. import sys
  6. sys.path.append(os.path.dirname(os.path.abspath(__file__))+"/../../Sampling-based Planning/")
  7. from rrt_3D.plot_util3D import visualization
  8. def getRay(x, y):
  9. direc = [y[0] - x[0], y[1] - x[1], y[2] - x[2]]
  10. return np.array([x, direc])
  11. def getAABB(blocks):
  12. AABB = []
  13. for i in blocks:
  14. AABB.append(np.array([np.add(i[0:3], -0), np.add(i[3:6], 0)])) # make AABBs alittle bit of larger
  15. return AABB
  16. def getDist(pos1, pos2):
  17. return np.sqrt(sum([(pos1[0] - pos2[0]) ** 2, (pos1[1] - pos2[1]) ** 2, (pos1[2] - pos2[2]) ** 2]))
  18. ''' The following utils can be used for rrt or rrt*,
  19. required param initparams should have
  20. env, environement generated from env3D
  21. V, node set
  22. E, edge set
  23. i, nodes added
  24. maxiter, maximum iteration allowed
  25. stepsize, leaf growth restriction
  26. '''
  27. def sampleFree(initparams):
  28. '''biased sampling'''
  29. x = np.random.uniform(initparams.env.boundary[0:3], initparams.env.boundary[3:6])
  30. i = np.random.random()
  31. if isinside(initparams, x):
  32. return sampleFree(initparams)
  33. else:
  34. #if i < 0.05:
  35. # return initparams.env.goal+0.01
  36. #else: return np.array(x)
  37. return np.array(x)
  38. def isinside(initparams, x):
  39. '''see if inside obstacle'''
  40. for i in initparams.env.blocks:
  41. if i[0] <= x[0] < i[3] and i[1] <= x[1] < i[4] and i[2] <= x[2] < i[5]:
  42. return True
  43. return False
  44. def isinbound(i, x):
  45. if i[0] <= x[0] < i[3] and i[1] <= x[1] < i[4] and i[2] <= x[2] < i[5]:
  46. return True
  47. return False
  48. def isCollide(initparams, x, y):
  49. '''see if line intersects obstacle'''
  50. ray = getRay(x, y)
  51. dist = getDist(x, y)
  52. if not isinbound(initparams.env.boundary,y):
  53. return True
  54. for i in getAABB(initparams.env.blocks):
  55. shot = pyrr.geometric_tests.ray_intersect_aabb(ray, i)
  56. if shot is not None:
  57. dist_wall = getDist(x, shot)
  58. if dist_wall <= dist: # collide
  59. return True
  60. for i in initparams.env.balls:
  61. shot = pyrr.geometric_tests.ray_intersect_sphere(ray, i)
  62. if shot != []:
  63. dists_ball = [getDist(x, j) for j in shot]
  64. if all(dists_ball <= dist): # collide
  65. return True
  66. return False
  67. def nearest(initparams, x):
  68. V = np.array(initparams.V)
  69. if initparams.i == 0:
  70. return initparams.V[0]
  71. xr = repmat(x, len(V), 1)
  72. dists = np.linalg.norm(xr - V, axis=1)
  73. return initparams.V[np.argmin(dists)]
  74. def steer(initparams, x, y):
  75. direc = (y - x) / np.linalg.norm(y - x)
  76. xnew = x + initparams.stepsize * direc
  77. return xnew
  78. def near(initparams, x):
  79. cardV = len(initparams.V)
  80. eta = initparams.eta
  81. gamma = initparams.gamma
  82. r = min(gamma*(np.log(cardV)/cardV),eta)
  83. if initparams.done: r = 1
  84. V = np.array(initparams.V)
  85. if initparams.i == 0:
  86. return initparams.V[0]
  87. xr = repmat(x, len(V), 1)
  88. inside = np.linalg.norm(xr - V, axis=1) < r
  89. nearpoints = V[inside]
  90. return np.array(nearpoints)
  91. def cost(initparams, x):
  92. '''here use the additive recursive cost function'''
  93. if all(x == initparams.env.start):
  94. return 0
  95. xparent = initparams.Parent[hash3D(x)]
  96. return cost(initparams, xparent) + getDist(x, xparent)
  97. def path(initparams, Path=[], dist=0):
  98. x = initparams.env.goal
  99. while not all(x == initparams.env.start):
  100. x2 = initparams.Parent[hash3D(x)]
  101. Path.append(np.array([x, x2]))
  102. dist += getDist(x, x2)
  103. x = x2
  104. return Path, dist
  105. def hash3D(x):
  106. return str(x[0])+' '+str(x[1])+' '+str(x[2])
  107. def dehash(x):
  108. return np.array([float(i) for i in x.split(' ')])
  109. class edgeset(object):
  110. def __init__(self):
  111. self.E = {}
  112. def add_edge(self,edge):
  113. x, y = hash3D(edge[0]),hash3D(edge[1])
  114. if x in self.E:
  115. self.E[x].append(y)
  116. else:
  117. self.E[x] = [y]
  118. def remove_edge(self,edge):
  119. x, y = edge[0],edge[1]
  120. self.E[hash3D(x)].remove(hash3D(y))
  121. def get_edge(self):
  122. edges = []
  123. for v in self.E:
  124. for n in self.E[v]:
  125. #if (n,v) not in edges:
  126. edges.append((dehash(v),dehash(n)))
  127. return edges