utils3D.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. import numpy as np
  2. from numpy.matlib import repmat
  3. import pyrr as pyrr
  4. # plotting
  5. import matplotlib.pyplot as plt
  6. from mpl_toolkits.mplot3d import Axes3D
  7. from mpl_toolkits.mplot3d.art3d import Poly3DCollection
  8. import mpl_toolkits.mplot3d as plt3d
  9. def getRay(x, y):
  10. direc = [y[0] - x[0], y[1] - x[1], y[2] - x[2]]
  11. return np.array([x, direc])
  12. def getAABB(blocks):
  13. AABB = []
  14. for i in blocks:
  15. AABB.append(np.array([np.add(i[0:3], -0), np.add(i[3:6], 0)])) # make AABBs alittle bit of larger
  16. return AABB
  17. def getDist(pos1, pos2):
  18. return np.sqrt(sum([(pos1[0] - pos2[0]) ** 2, (pos1[1] - pos2[1]) ** 2, (pos1[2] - pos2[2]) ** 2]))
  19. def draw_block_list(ax, blocks):
  20. '''
  21. Subroutine used by draw_map() to display the environment blocks
  22. '''
  23. v = np.array([[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0], [0, 0, 1], [1, 0, 1], [1, 1, 1], [0, 1, 1]],
  24. dtype='float')
  25. f = np.array([[0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7], [0, 1, 2, 3], [4, 5, 6, 7]])
  26. # clr = blocks[:,6:]/255
  27. n = blocks.shape[0]
  28. d = blocks[:, 3:6] - blocks[:, :3]
  29. vl = np.zeros((8 * n, 3))
  30. fl = np.zeros((6 * n, 4), dtype='int64')
  31. # fcl = np.zeros((6*n,3))
  32. for k in range(n):
  33. vl[k * 8:(k + 1) * 8, :] = v * d[k] + blocks[k, :3]
  34. fl[k * 6:(k + 1) * 6, :] = f + k * 8
  35. # fcl[k*6:(k+1)*6,:] = clr[k,:]
  36. if type(ax) is Poly3DCollection:
  37. ax.set_verts(vl[fl])
  38. else:
  39. pc = Poly3DCollection(vl[fl], alpha=0.15, linewidths=1, edgecolors='k')
  40. # pc.set_facecolor(fcl)
  41. h = ax.add_collection3d(pc)
  42. return h
  43. ''' The following utils can be used for rrt or rrt*,
  44. required param initparams should have
  45. env, environement generated from env3D
  46. V, node set
  47. E, edge set
  48. i, nodes added
  49. maxiter, maximum iteration allowed
  50. stepsize, leaf growth restriction
  51. '''
  52. def sampleFree(initparams):
  53. x = np.random.uniform(initparams.env.boundary[0:3], initparams.env.boundary[3:6])
  54. if isinside(initparams, x):
  55. return sampleFree(initparams)
  56. else:
  57. return np.array(x)
  58. def isinside(initparams, x):
  59. '''see if inside obstacle'''
  60. for i in initparams.env.blocks:
  61. if i[0] <= x[0] < i[3] and i[1] <= x[1] < i[4] and i[2] <= x[2] < i[5]:
  62. return True
  63. return False
  64. def isCollide(initparams, x, y):
  65. '''see if line intersects obstacle'''
  66. ray = getRay(x, y)
  67. dist = getDist(x, y)
  68. for i in getAABB(initparams.env.blocks):
  69. shot = pyrr.geometric_tests.ray_intersect_aabb(ray, i)
  70. if shot is not None:
  71. dist_wall = getDist(x, shot)
  72. if dist_wall <= dist: # collide
  73. return True
  74. return False
  75. def nearest(initparams, x):
  76. V = np.array(initparams.V)
  77. if initparams.i == 0:
  78. return initparams.V[0]
  79. xr = repmat(x, len(V), 1)
  80. dists = np.linalg.norm(xr - V, axis=1)
  81. return initparams.V[np.argmin(dists)]
  82. def steer(initparams, x, y):
  83. direc = (y - x) / np.linalg.norm(y - x)
  84. xnew = x + initparams.stepsize * direc
  85. return xnew
  86. def near(initparams, x, r=2):
  87. # TODO: r = min{gamma*log(card(V)/card(V)1/d),eta}
  88. V = np.array(initparams.V)
  89. if initparams.i == 0:
  90. return initparams.V[0]
  91. xr = repmat(x, len(V), 1)
  92. inside = np.linalg.norm(xr - V, axis=1) < r
  93. nearpoints = V[inside]
  94. return np.array(nearpoints)
  95. def cost(initparams, x):
  96. '''here use the additive recursive cost function'''
  97. if all(x == initparams.env.start):
  98. return 0
  99. xparent = initparams.Parent[str(x[0])][str(x[1])][str(x[2])]
  100. return cost(initparams, xparent) + getDist(x, xparent)
  101. def visualization(initparams):
  102. V = np.array(initparams.V)
  103. E = np.array(initparams.E)
  104. Path = np.array(initparams.Path)
  105. start = initparams.env.start
  106. goal = initparams.env.goal
  107. ax = plt.subplot(111, projection='3d')
  108. ax.view_init(elev=0., azim=90)
  109. ax.clear()
  110. draw_block_list(ax, initparams.env.blocks)
  111. if E != []:
  112. for i in E:
  113. xs = i[0][0], i[1][0]
  114. ys = i[0][1], i[1][1]
  115. zs = i[0][2], i[1][2]
  116. line = plt3d.art3d.Line3D(xs, ys, zs)
  117. ax.add_line(line)
  118. if Path != []:
  119. for i in Path:
  120. xs = i[0][0], i[1][0]
  121. ys = i[0][1], i[1][1]
  122. zs = i[0][2], i[1][2]
  123. line = plt3d.art3d.Line3D(xs, ys, zs, color='r')
  124. ax.add_line(line)
  125. ax.plot(start[0:1], start[1:2], start[2:], 'go', markersize=7, markeredgecolor='k')
  126. ax.plot(goal[0:1], goal[1:2], goal[2:], 'ro', markersize=7, markeredgecolor='k')
  127. ax.scatter3D(V[:, 0], V[:, 1], V[:, 2])
  128. plt.xlim(initparams.env.boundary[0], initparams.env.boundary[3])
  129. plt.ylim(initparams.env.boundary[1], initparams.env.boundary[4])
  130. ax.set_zlim(initparams.env.boundary[2], initparams.env.boundary[5])
  131. plt.xlabel('x')
  132. plt.ylabel('y')
  133. if not Path != []:
  134. plt.pause(0.001)
  135. else:
  136. plt.show()
  137. def path(initparams, Path=[], dist=0):
  138. x = initparams.env.goal
  139. while not all(x == initparams.env.start):
  140. x2 = initparams.Parent[str(x[0])][str(x[1])][str(x[2])]
  141. Path.append(np.array([x, x2]))
  142. dist += getDist(x, x2)
  143. x = x2
  144. return Path, dist