Zm2OSl>41&-{h|?YVVPan`tiW|Ub^x5F
z4G@+LJgq-Y0C5Fnb8~@ZcI__);X^qF%9gjWckH(z#%Lu4R_YowU01vAfcU2JiiZ$V>k@h!25`dk?-!}yfW
zCY_{|0mUNp^2&c;$KcY8UsN&Lvd*@DV0S5s+_tZF3-L-K5+(n--9z|1k1lQH3^&Vb
z&xL>2ZjYrTX06!gxmb6~DbTda(vgOiZxC4#uuEwBJ?m3IN~R6O1C7{x1{#^
zteZzTjGWsPh(s=MZ^Rt%hw|t}$j0IJVIx70vR{1i)AD@xa_>Elq2V#w>cfByJwxGk
z9)D8wy#&1ZB_CqIsQ7@OLXvXPrk;nW$}b>|km+O&&`i-mZuP%TC7Z~~gOJbg2c%f}
zo`%T{jV!sfgoWjh6vN!qFGVUtR
zwcl*e$AHis`i_%Xjx&tB@qo&8$2lCkgQBPEI9}9t97*yiUnfHToATzC97j?Ik_19I
zj#A0Y0v)QP`~?yOLXuJ&Z~%pQ#4sCayeIAqEb
zpoBPoq)lN(5PzUHqhJx?;EWZaAz?vJE1o{n@a>H>N@c$(p3{QzO%Rm7iR?L@zE$(b
z?LpxAZa5Klu7MqN7)j1eX5KHpvZ+_dYHk=HGKXnK=%yB29fVf4WY)r9&ULl7Ze^Bn?b3@zE
L8XvH?z%~9KyL;g`
literal 0
HcmV?d00001
diff --git a/src/Search_2D/__pycache__/env.cpython-37.pyc b/src/Search_2D/__pycache__/env.cpython-37.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..945aa4dd30ff0b41097d4b473bf4321682bfd244
GIT binary patch
literal 1434
zcmah}&2G~`5Z+xovFrX&Ri)|y6$@2@94Jt3QH3fR)N&xIRG~^y(Bfv@#wD@SU8hQ;
zL_(wwz$3I5BwmCocOT(GUV#hDtR449NNl?^s8KyAa^f~lT@5OhE|
z90(*FNa)SN61JEU&XEnP;JGj^30S5e061M8KZkwe`yfhe{0GJuOt2-~pNugB*ac9s
znA)gr*yw~9y^fnE@tKWEgOv)2)#K6&kNm_sn;7jV4x&&cR&=0v+v_9-7$usR%5NQh
zC2|(F|NgX9uD?~jRP~*#nl-3qz2d76anz}A2XV7|@VK_~roQXN&E1w4hEVeQp6|&<
zlOK4>7yS0>dgaO58vg$$s_uuUYn`*i<~#_4m~*VS(mbI>__OI8?ax44)+PZBY%C7c
zICXz;#~|$wR-RT%R8GShlxqf*w)JgOF$Zgj)9nZ^_BoW~4ty&OO#5?~?aGz&0XuZ=APMay^i0zvp}{StNX)SSQz0BFA~B0>jxGQ>mvTL?zZY1l7g>KAiIhFO
zYN?1E552a}dE#*1jzqVG_6+AIU9XjTB;G;d$#u?a=fIaLk+u?lHSj(P$!JsCvJJgf
cEwRMnTtp4d^}@e)C-z2~`33%RXv&+$U$g)@-2eap
literal 0
HcmV?d00001
diff --git a/src/Search_2D/__pycache__/env.cpython-38.pyc b/src/Search_2D/__pycache__/env.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e45c75b8d0504fc65225c15ff892fb552c211b30
GIT binary patch
literal 1405
zcmah}&2G~`5Z+z?#!X9Am8#-Ud_V$U8dM|>6+)FLDqNyU6&xa=m78@Nm&8ujcGX7C
zDSZSUpgnTqz;o~bd*x&vflHaO6E{Ifth2MT`^}F%^KCvXFFOPVZG7iVosgfnnI9T#
z_FyI(AOz`<10twk*F>-h>rkN`5ln_u%8XoZJ2LhCeJ|#niCE$
z1`=LOlmUb#Y|#+TsST%q+-SE1G+ht~y3{USfM4+#gvW|I7zL=HOQ;1YFaziYEYhrW
zTo!Z$!KOS%rBIz8^(U0wnrtN
zL5-GRDfRLbE3ph`%E^YpPXi8hcmVsP3{FQYnDHK3AOf}k>tE(%(6pSKkul^wqhpq`
z2^njtmeUE{C!f~Fdam8*xi07lyQP$zKdP~f8J07_Hpvu!2{@bg1)Awo>|>41eBo|v
zk{Xw3$>s@L$ZSl#zW{11L^f;BZ-@zN-cwjL`U6mV!Lw0gzjC~j&gjT-r{g{JGxYo6
zC~%>wso(7f$y0Y2CvXhptL=7WkY+O4b%BU(d~$DGTijoT0{d7zM1gH8)=_MsSVi#+
zgl9+#7KubsS`wtnsOYcxLI8*qQ1nvKtC9$chJSHEHoyWIm|!?!A`MN}q^q<^*Xwnq
z+^@3PI$A=iOz%_MGm+7eKL|Ki4(EedWPQ||oS$cYze3~+#FzLXWzMy&t;Q7J37-C?se`I2;Tl
zJt0E-fuBYX`pU_V|&X1cH|dhx6#}-t&4L|Npbs951&RFGfSF)9Vj}rWR-@~*MmH
3i#-?4flp8(F(v*S;P)g*HJjR&trfAB$CSmn
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
literal 0
HcmV?d00001
diff --git a/src/Search_2D/__pycache__/plotting.cpython-39.pyc b/src/Search_2D/__pycache__/plotting.cpython-39.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c381ea6565fe0c10189368e3029be1494803ece1
GIT binary patch
literal 5332
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
JSzBLQ{|}hB_<#Ta
literal 0
HcmV?d00001
diff --git a/src/Search_2D/__pycache__/queue.cpython-38.pyc b/src/Search_2D/__pycache__/queue.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..69c46c686152f84441b374e99fc01ccabf6439d4
GIT binary patch
literal 2668
zcmcIlQIFe15Z<-pi<7$?rB?w31g-=^5i|jW1gfAq>8dM8RXB9w#T6{Bckklj*uGsG
z=}viTe+YTZJHKXMdFo%_iJ5gAn>&Y!12)<5?vB0R&g?fc-wy_T0*&^5V;?z${Em}m
zvthCiUEK%438yjf%O~~eL&7a?KPTLNX89J(I^2Po12Y?DTf7UiF3dWd9+RQ_0`?%2
z5M{GjFxiK$J_aF(PdV`|PJO%F9lkdE`cAo{zr|hNdrtf=@58R!y7yfn3UT<&;kOq*
z_C06^aiG*aZ@p|59|#r7D9fWXX{fwNd0eRIG!fi8Nu_rfNtNG?lDp*~Epks5u^5>>
zLJB9W8jkVk2hi0nh@AXN7i3PD#mO;Q(#g`++hH2VB1BZB9WKrap&bx~SW?|lB0gCX
ziC6H)Y&=b8Vtg@8i}AxK|GIcGJ__>bQ5+;ml$?%_MIgf|dlD$Y+2z$wAB;yM{J-oi
z13k*lwaZwPL^)&Iczm>j(2JXEmyIg*%S@h=r}P=+^k)l9wk8t2vb3}vi$r!|EL{|6
zVJQ$!J7SjQ=jgKv`IQ>k=t6TMcmW%Zk%-3AH(&su;OjYEPzq!`CK9zv%K+-FAj?F;
zVcLULzmud~Tt0xE75S^6t>6bWJZLuCjCPdZiwbtQg6(E$7K@X-)nNNn
mo
zcpphH6O8FTW3!Y4=U}|U*jW+8D@~U%o`#Ic9oR~uBP4DrUqey5*o@H65*-IoO%yJ<
zwBxuo{>*v^OMhwj@;>x`7lw~841c&1hPb>T3{iC@3?BvmO%xht$PSp*b}z<}@1V_S
z{5k;eMAr%cIY1!fbt@X)*d6E6H23SdP19n}C+d%PF
z!;pXIC10dg1aNs22m>H^F`+qf}n}
zbcLyAeFIgE&XXdQkW!Q0 else 0
+ heapq.heappush(self.OPEN, (prior, s_n))
+
+ return self.extract_path(self.PARENT), self.CLOSED
+
+
+def main():
+ s_start = (5, 5)
+ s_goal = (45, 25)
+
+ bfs = BFS(s_start, s_goal, 'None')
+ plot = plotting.Plotting(s_start, s_goal)
+
+ path, visited = bfs.searching()
+ plot.animation(path, visited, "Breadth-first Searching (BFS)")
+
+
+if __name__ == '__main__':
+ main()
diff --git a/src/Search_2D/dfs.py b/src/Search_2D/dfs.py
new file mode 100644
index 0000000..3b30b03
--- /dev/null
+++ b/src/Search_2D/dfs.py
@@ -0,0 +1,65 @@
+
+import os
+import sys
+import math
+import heapq
+
+sys.path.append(os.path.dirname(os.path.abspath(__file__)) +
+ "/../../Search_based_Planning/")
+
+from Search_2D import plotting, env
+from Search_2D.Astar import AStar
+
+class DFS(AStar):
+ """DFS add the new visited node in the front of the openset
+ """
+ def searching(self):
+ """
+ Breadth-first Searching.
+ :return: path, visited order
+ """
+
+ self.PARENT[self.s_start] = self.s_start
+ self.g[self.s_start] = 0
+ self.g[self.s_goal] = math.inf
+ heapq.heappush(self.OPEN,
+ (0, self.s_start))
+
+ while self.OPEN:
+ _, s = heapq.heappop(self.OPEN)
+ self.CLOSED.append(s)
+
+ if s == self.s_goal:
+ break
+
+ for s_n in self.get_neighbor(s):
+ new_cost = self.g[s] + self.cost(s, s_n)
+
+ if s_n not in self.g:
+ self.g[s_n] = math.inf
+
+ if new_cost < self.g[s_n]: # conditions for updating Cost
+ self.g[s_n] = new_cost
+ self.PARENT[s_n] = s
+
+ # dfs, add new node to the front of the openset
+ prior = self.OPEN[0][0]-1 if len(self.OPEN)>0 else 0
+ heapq.heappush(self.OPEN, (prior, s_n))
+
+ return self.extract_path(self.PARENT), self.CLOSED
+
+
+def main():
+ s_start = (5, 5)
+ s_goal = (45, 25)
+
+ dfs = DFS(s_start, s_goal, 'None')
+ plot = plotting.Plotting(s_start, s_goal)
+
+ path, visited = dfs.searching()
+ visited = list(dict.fromkeys(visited))
+ plot.animation(path, visited, "Depth-first Searching (DFS)") # animation
+
+
+if __name__ == '__main__':
+ main()
diff --git a/src/Search_2D/env.py b/src/Search_2D/env.py
new file mode 100644
index 0000000..9523c98
--- /dev/null
+++ b/src/Search_2D/env.py
@@ -0,0 +1,52 @@
+"""
+Env 2D
+@author: huiming zhou
+"""
+
+
+class Env:
+ def __init__(self):
+ self.x_range = 51 # size of background
+ self.y_range = 31
+ self.motions = [(-1, 0), (-1, 1), (0, 1), (1, 1),
+ (1, 0), (1, -1), (0, -1), (-1, -1)]
+ self.obs = self.obs_map()
+
+ def update_obs(self, obs):
+ self.obs = obs
+
+ def obs_map(self):
+ """
+ Initialize obstacles' positions
+ :return: map of obstacles
+ """
+
+ x = self.x_range #51
+ y = self.y_range #31
+ obs = set()
+ #画上下边框
+ for i in range(x):
+ obs.add((i, 0))
+ for i in range(x):
+ obs.add((i, y - 1))
+ #画左右边框
+ for i in range(y):
+ obs.add((0, i))
+ for i in range(y):
+ obs.add((x - 1, i))
+
+ for i in range(2, 21):
+ obs.add((i, 15))
+ for i in range(15):
+ obs.add((20, i))
+
+ for i in range(15, 30):
+ obs.add((30, i))
+ for i in range(16):
+ obs.add((40, i))
+
+ return obs
+
+# if __name__ == '__main__':
+# a = Env()
+# print(a.obs)
\ No newline at end of file
diff --git a/src/Search_2D/plotting.py b/src/Search_2D/plotting.py
new file mode 100644
index 0000000..1cf98a3
--- /dev/null
+++ b/src/Search_2D/plotting.py
@@ -0,0 +1,165 @@
+"""
+Plot tools 2D
+@author: huiming zhou
+"""
+
+import os
+import sys
+import matplotlib.pyplot as plt
+
+sys.path.append(os.path.dirname(os.path.abspath(__file__)) +
+ "/../../Search_based_Planning/")
+
+from Search_2D import env
+
+
+class Plotting:
+ def __init__(self, xI, xG):
+ self.xI, self.xG = xI, xG
+ self.env = env.Env()
+ self.obs = self.env.obs_map()
+
+ def update_obs(self, obs):
+ self.obs = obs
+
+ def animation(self, path, visited, name):
+ self.plot_grid(name)
+ self.plot_visited(visited)
+ self.plot_path(path)
+ plt.show()
+
+ def animation_lrta(self, path, visited, name):
+ self.plot_grid(name)
+ cl = self.color_list_2()
+ path_combine = []
+
+ for k in range(len(path)):
+ self.plot_visited(visited[k], cl[k])
+ plt.pause(0.2)
+ self.plot_path(path[k])
+ path_combine += path[k]
+ plt.pause(0.2)
+ if self.xI in path_combine:
+ path_combine.remove(self.xI)
+ self.plot_path(path_combine)
+ plt.show()
+
+ def animation_ara_star(self, path, visited, name):
+ self.plot_grid(name)
+ cl_v, cl_p = self.color_list()
+
+ for k in range(len(path)):
+ self.plot_visited(visited[k], cl_v[k])
+ self.plot_path(path[k], cl_p[k], True)
+ plt.pause(0.5)
+
+ plt.show()
+
+ def animation_bi_astar(self, path, v_fore, v_back, name):
+ self.plot_grid(name)
+ self.plot_visited_bi(v_fore, v_back)
+ self.plot_path(path)
+ plt.show()
+
+ def plot_grid(self, name):
+ obs_x = [x[0] for x in self.obs]
+ obs_y = [x[1] for x in self.obs]
+
+ plt.plot(self.xI[0], self.xI[1], "bs")
+ plt.plot(self.xG[0], self.xG[1], "gs")
+ plt.plot(obs_x, obs_y, "sk")
+ plt.title(name)
+ plt.axis("equal")
+
+ def plot_visited(self, visited, cl='gray'):
+ if self.xI in visited:
+ visited.remove(self.xI)
+
+ if self.xG in visited:
+ visited.remove(self.xG)
+
+ count = 0
+
+ for x in visited:
+ count += 1
+ plt.plot(x[0], x[1], color=cl, marker='o')
+ plt.gcf().canvas.mpl_connect('key_release_event',
+ lambda event: [exit(0) if event.key == 'escape' else None])
+
+ if count < len(visited) / 3:
+ length = 20
+ elif count < len(visited) * 2 / 3:
+ length = 30
+ else:
+ length = 40
+ #
+ # length = 15
+
+ if count % length == 0:
+ plt.pause(0.001)
+ plt.pause(0.01)
+
+ def plot_path(self, path, cl='r', flag=False):
+ path_x = [path[i][0] for i in range(len(path))]
+ path_y = [path[i][1] for i in range(len(path))]
+
+ if not flag:
+ plt.plot(path_x, path_y, linewidth='3', color='r')
+ else:
+ plt.plot(path_x, path_y, linewidth='3', color=cl)
+
+ plt.plot(self.xI[0], self.xI[1], "bs")
+ plt.plot(self.xG[0], self.xG[1], "gs")
+
+ plt.pause(0.01)
+
+ def plot_visited_bi(self, v_fore, v_back):
+ if self.xI in v_fore:
+ v_fore.remove(self.xI)
+
+ if self.xG in v_back:
+ v_back.remove(self.xG)
+
+ len_fore, len_back = len(v_fore), len(v_back)
+
+ for k in range(max(len_fore, len_back)):
+ if k < len_fore:
+ plt.plot(v_fore[k][0], v_fore[k][1], linewidth='3', color='gray', marker='o')
+ if k < len_back:
+ plt.plot(v_back[k][0], v_back[k][1], linewidth='3', color='cornflowerblue', marker='o')
+
+ plt.gcf().canvas.mpl_connect('key_release_event',
+ lambda event: [exit(0) if event.key == 'escape' else None])
+
+ if k % 10 == 0:
+ plt.pause(0.001)
+ plt.pause(0.01)
+
+ @staticmethod
+ def color_list():
+ cl_v = ['silver',
+ 'wheat',
+ 'lightskyblue',
+ 'royalblue',
+ 'slategray']
+ cl_p = ['gray',
+ 'orange',
+ 'deepskyblue',
+ 'red',
+ 'm']
+ return cl_v, cl_p
+
+ @staticmethod
+ def color_list_2():
+ cl = ['silver',
+ 'steelblue',
+ 'dimgray',
+ 'cornflowerblue',
+ 'dodgerblue',
+ 'royalblue',
+ 'plum',
+ 'mediumslateblue',
+ 'mediumpurple',
+ 'blueviolet',
+ ]
+ return cl
diff --git a/src/Search_2D/queue.py b/src/Search_2D/queue.py
new file mode 100644
index 0000000..51703ae
--- /dev/null
+++ b/src/Search_2D/queue.py
@@ -0,0 +1,62 @@
+import collections
+import heapq
+
+
+class QueueFIFO:
+ """
+ Class: QueueFIFO
+ Description: QueueFIFO is designed for First-in-First-out rule.
+ """
+
+ def __init__(self):
+ self.queue = collections.deque()
+
+ def empty(self):
+ return len(self.queue) == 0
+
+ def put(self, node):
+ self.queue.append(node) # enter from back
+
+ def get(self):
+ return self.queue.popleft() # leave from front
+
+
+class QueueLIFO:
+ """
+ Class: QueueLIFO
+ Description: QueueLIFO is designed for Last-in-First-out rule.
+ """
+
+ def __init__(self):
+ self.queue = collections.deque()
+
+ def empty(self):
+ return len(self.queue) == 0
+
+ def put(self, node):
+ self.queue.append(node) # enter from back
+
+ def get(self):
+ return self.queue.pop() # leave from back
+
+
+class QueuePrior:
+ """
+ Class: QueuePrior
+ Description: QueuePrior reorders elements using value [priority]
+ """
+
+ def __init__(self):
+ self.queue = []
+
+ def empty(self):
+ return len(self.queue) == 0
+
+ def put(self, item, priority):
+ heapq.heappush(self.queue, (priority, item)) # reorder s using priority
+
+ def get(self):
+ return heapq.heappop(self.queue)[1] # pop out the smallest item
+
+ def enumerate(self):
+ return self.queue