Dstar3D.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. import os
  4. import sys
  5. from collections import defaultdict
  6. sys.path.append(os.path.dirname(os.path.abspath(__file__)) + "/../../Search-based Planning/")
  7. from Search_3D.env3D import env
  8. from Search_3D import Astar3D
  9. from Search_3D.utils3D import StateSpace, getDist, getNearest, getRay, isinbound, isinball, isCollide, children, cost, initcost
  10. from Search_3D.plot_util3D import visualization
  11. class D_star(object):
  12. def __init__(self,resolution = 1):
  13. self.Alldirec = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1], [1, 1, 0], [1, 0, 1], [0, 1, 1], [1, 1, 1],
  14. [-1, 0, 0], [0, -1, 0], [0, 0, -1], [-1, -1, 0], [-1, 0, -1], [0, -1, -1],
  15. [-1, -1, -1],
  16. [1, -1, 0], [-1, 1, 0], [1, 0, -1], [-1, 0, 1], [0, 1, -1], [0, -1, 1],
  17. [1, -1, -1], [-1, 1, -1], [-1, -1, 1], [1, 1, -1], [1, -1, 1], [-1, 1, 1]])
  18. self.env = env(resolution = resolution)
  19. self.X = StateSpace(self.env)
  20. self.x0, self.xt = getNearest(self.X, self.env.start), getNearest(self.X, self.env.goal)
  21. self.b = defaultdict(lambda: defaultdict(dict))# back pointers every state has one except xt.
  22. self.OPEN = {} # OPEN list, here use a hashmap implementation. hash is point, key is value
  23. self.h = self.initH() # estimate from a point to the end point
  24. self.tag = self.initTag() # set all states to new
  25. self.V = set()# vertice in closed
  26. # initialize cost set
  27. # self.c = initcost(self)
  28. # for visualization
  29. self.ind = 0
  30. self.Path = []
  31. self.done = False
  32. def initH(self):
  33. # h set, all initialzed h vals are 0 for all states.
  34. h = {}
  35. for xi in self.X:
  36. h[xi] = 0
  37. return h
  38. def initTag(self):
  39. # tag , New point (never been in the OPEN list)
  40. # Open point ( currently in OPEN )
  41. # Closed (currently in CLOSED)
  42. t = {}
  43. for xi in self.X:
  44. t[xi] = 'New'
  45. return t
  46. def get_kmin(self):
  47. # get the minimum of the k val in OPEN
  48. # -1 if it does not exist
  49. if self.OPEN:
  50. minv = np.inf
  51. for v,k in enumerate(self.OPEN):
  52. if v < minv: minv = v
  53. return minv
  54. return -1
  55. def min_state(self):
  56. # returns the state in OPEN with min k(.)
  57. # if empty, returns None and -1
  58. # it also removes this min value form the OPEN set.
  59. if self.OPEN:
  60. minv = np.inf
  61. for v,k in enumerate(self.OPEN):
  62. if v < minv: mink, minv = k, v
  63. return mink, self.OPEN.pop(mink)
  64. return None, -1
  65. def insert(self, x, h_new):
  66. # inserting a key and value into OPEN list (x, kx)
  67. # depending on following situations
  68. if self.tag[x] == 'New':
  69. kx = h_new
  70. if self.tag[x] == 'Open':
  71. kx = min(self.OPEN[x],h_new)
  72. if self.tag[x] == 'Closed':
  73. kx = min(self.h[x], h_new)
  74. self.OPEN[x] = kx
  75. self.h[x],self.tag[x] = h_new, 'Open'
  76. def process_state(self):
  77. x, kold = self.min_state()
  78. self.tag[x] = 'Closed'
  79. self.V.add(x)
  80. if x == None: return -1
  81. if kold < self.h[x]: # raised states
  82. for y in children(self,x):
  83. a = self.h[y] + cost(self,y,x)
  84. if self.h[y] <= kold and self.h[x] > a:
  85. self.b[x], self.h[x] = y , a
  86. elif kold == self.h[x]:# lower
  87. for y in children(self,x):
  88. bb = self.h[x] + cost(self,x,y)
  89. if self.tag[y] == 'New' or \
  90. (self.b[y] == x and self.h[y] != bb) or \
  91. (self.b[y] != x and self.h[y] > bb):
  92. self.b[y] = x
  93. self.insert(y, bb)
  94. else:
  95. for y in children(self,x):
  96. bb = self.h[x] + cost(self,x,y)
  97. if self.tag[y] == 'New' or \
  98. (self.b[y] == x and self.h[y] != bb):
  99. self.b[y] = x
  100. self.insert(y, bb)
  101. else:
  102. if self.b[y] != x and self.h[y] > bb:
  103. self.insert(x, self.h[x])
  104. else:
  105. if self.b[y] != x and self.h[y] > bb and \
  106. self.tag[y] == 'Closed' and self.h[y] == kold:
  107. self.insert(y, self.h[y])
  108. return self.get_kmin()
  109. def modify_cost(self,x,y,cval):
  110. # TODO: implement own function
  111. # self.c[x][y] = cval
  112. # if self.tag[x] == 'Closed': self.insert(x,self.h[x])
  113. # return self.get_kmin()
  114. pass
  115. def path(self):
  116. path = []
  117. x = self.x0
  118. start = self.xt
  119. while x != start:
  120. path.append([np.array(x), np.array(self.b[x])])
  121. x = self.b[x]
  122. return path
  123. def run(self):
  124. # put G (ending state) into the OPEN list
  125. self.OPEN[self.xt] = 0
  126. # first run
  127. while True:
  128. #TODO: self.x0 =
  129. self.process_state()
  130. visualization(self)
  131. if self.tag[self.x0] == "Closed":
  132. break
  133. self.ind += 1
  134. self.Path = self.path()
  135. self.done = True
  136. visualization(self)
  137. # plt.show()
  138. # when the environemnt changes over time
  139. s = tuple(self.env.start)
  140. while s != self.xt:
  141. if s == tuple(self.env.start):
  142. s = self.b[self.x0]
  143. else:
  144. s = self.b[s]
  145. self.process_state()
  146. self.env.move_block(a=[0,0,0.1],s=0.5,mode='translation')
  147. self.Path = self.path()
  148. visualization(self)
  149. self.ind += 1
  150. if __name__ == '__main__':
  151. D = D_star(1)
  152. D.run()