utils3D.py 5.0 KB

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