utils3D.py 4.2 KB

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