utils3D.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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.1:
  35. return initparams.env.goal + 1
  36. else:
  37. return np.array(x)
  38. return np.array(x)
  39. def isinside(initparams, x):
  40. '''see if inside obstacle'''
  41. for i in initparams.env.blocks:
  42. if i[0] <= x[0] < i[3] and i[1] <= x[1] < i[4] and i[2] <= x[2] < i[5]:
  43. return True
  44. return False
  45. def isinbound(i, x):
  46. if i[0] <= x[0] < i[3] and i[1] <= x[1] < i[4] and i[2] <= x[2] < i[5]:
  47. return True
  48. return False
  49. def isCollide(initparams, x, y):
  50. '''see if line intersects obstacle'''
  51. ray = getRay(x, y)
  52. dist = getDist(x, y)
  53. if not isinbound(initparams.env.boundary, y):
  54. return True
  55. for i in getAABB(initparams.env.blocks):
  56. shot = pyrr.geometric_tests.ray_intersect_aabb(ray, i)
  57. if shot is not None:
  58. dist_wall = getDist(x, shot)
  59. if dist_wall <= dist: # collide
  60. return True
  61. for i in initparams.env.balls:
  62. shot = pyrr.geometric_tests.ray_intersect_sphere(ray, i)
  63. if shot != []:
  64. dists_ball = [getDist(x, j) for j in shot]
  65. if all(dists_ball <= dist): # collide
  66. return True
  67. return False
  68. def nearest(initparams, x):
  69. V = np.array(initparams.V)
  70. if initparams.i == 0:
  71. return initparams.V[0]
  72. xr = repmat(x, len(V), 1)
  73. dists = np.linalg.norm(xr - V, axis=1)
  74. return initparams.V[np.argmin(dists)]
  75. def steer(initparams, x, y):
  76. direc = (y - x) / np.linalg.norm(y - x)
  77. xnew = x + initparams.stepsize * direc
  78. return xnew
  79. def near(initparams, x):
  80. cardV = len(initparams.V)
  81. eta = initparams.eta
  82. gamma = initparams.gamma
  83. r = min(gamma * (np.log(cardV) / cardV), eta)
  84. if initparams.done: r = 1
  85. V = np.array(initparams.V)
  86. if initparams.i == 0:
  87. return [initparams.V[0]]
  88. xr = repmat(x, len(V), 1)
  89. inside = np.linalg.norm(xr - V, axis=1) < r
  90. nearpoints = V[inside]
  91. return np.array(nearpoints)
  92. def cost(initparams, x):
  93. '''here use the additive recursive cost function'''
  94. if all(x == initparams.env.start):
  95. return 0
  96. xparent = initparams.Parent[hash3D(x)]
  97. return cost(initparams, xparent) + getDist(x, xparent)
  98. def path(initparams, Path=[], dist=0):
  99. x = initparams.env.goal
  100. while not all(x == initparams.env.start):
  101. x2 = initparams.Parent[hash3D(x)]
  102. Path.append(np.array([x, x2]))
  103. dist += getDist(x, x2)
  104. x = x2
  105. return Path, dist
  106. def hash3D(x):
  107. return str(x[0]) + ' ' + str(x[1]) + ' ' + str(x[2])
  108. def dehash(x):
  109. return np.array([float(i) for i in x.split(' ')])
  110. class edgeset(object):
  111. def __init__(self):
  112. self.E = {}
  113. def add_edge(self, edge):
  114. x, y = hash3D(edge[0]), hash3D(edge[1])
  115. if x in self.E:
  116. self.E[x].append(y)
  117. else:
  118. self.E[x] = [y]
  119. def remove_edge(self, edge):
  120. x, y = edge[0], edge[1]
  121. self.E[hash3D(x)].remove(hash3D(y))
  122. def get_edge(self):
  123. edges = []
  124. for v in self.E:
  125. for n in self.E[v]:
  126. # if (n,v) not in edges:
  127. edges.append((dehash(v), dehash(n)))
  128. return edges