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
diff --git a/src/Tello/KeyPress.py b/src/Tello/KeyPress.py
new file mode 100644
index 0000000..66e9f94
--- /dev/null
+++ b/src/Tello/KeyPress.py
@@ -0,0 +1,19 @@
+# @Time : 2022/5/9 20:49
+# @Author : 2890199310@qq.com
+# @File : KeyPress.py
+# @Software: PyCharm
+# @Function:
+
+def main():
+ keyPress()
+
+def keyPress(key):
+ if(key == 1):
+ return "e"
+
+def result():
+ return keyPress()
+
+
+if __name__ == '__main__':
+ main()
\ No newline at end of file
diff --git a/src/Tello/KeyPressModule.py b/src/Tello/KeyPressModule.py
new file mode 100644
index 0000000..bd7182a
--- /dev/null
+++ b/src/Tello/KeyPressModule.py
@@ -0,0 +1,31 @@
+# @Time : 2022/4/20 12:27
+# @Author : 2890199310@qq.com
+# @File : KeyPressModule.py.py
+# @Software: PyCharm
+# @Function:
+import os
+import sys
+sys.path.append(os.path.dirname(os.path.abspath(__file__)) + "/../../PaddleClas-release-2.3")
+
+# import pygame
+import Tello.KeyPress as k
+
+def init():
+ return
+
+def getKey(keyName):
+ # ans = False
+ # for eve in pygame.event.get(): pass
+ # keyInput = pygame.key.get_pressed()
+ # myKey = getattr(pygame,'K_{}'.format(keyName))
+ # if keyInput[myKey]:
+ if keyName == k.result():
+ ans = True
+ # pygame.display.update()
+ return ans
+
+def key(a):
+ return a
+
+if __name__ == '__main__':
+ init()
\ No newline at end of file
diff --git a/src/Tello/KeyboardControl.py b/src/Tello/KeyboardControl.py
new file mode 100644
index 0000000..6997c9f
--- /dev/null
+++ b/src/Tello/KeyboardControl.py
@@ -0,0 +1,105 @@
+# @Time : 2022/4/20 12:27
+# @Author : 2890199310@qq.com
+# @File : KeyboardControl.py.py
+# @Software: PyCharm
+# @Function:
+import os
+import sys
+sys.path.append(os.path.dirname(os.path.abspath(__file__)) + "/../../PaddleClas-release-2.3")
+import logging
+import time
+import cv2
+from djitellopy import tello
+# import Tello.KeyPressModule as kp # 用于获取键盘按键
+from time import sleep
+
+# Tello初始化设置
+Drone = tello.Tello() # 创建飞行器对象
+Drone.connect() # 连接到飞行器
+Drone.streamon() # 开启视频传输
+Drone.LOGGER.setLevel(logging.ERROR) # 只显示错误信息
+sleep(5) # 等待视频初始化
+# kp.init() # 初始化按键处理模块
+
+def getKeyboardInput(key):
+ image = cv2.resize(OriginalImage, (Camera_Width, Camera_Height))
+ speed = 70
+ drone = Drone
+ lr, fb, ud, yv = 0, 0, 0, 0
+ key_pressed = 0
+ # if kp.getKey("e"): #
+ if key == "e":
+ cv2.imwrite('D:/snap-{}.jpg'.format(time.strftime("%H%M%S", time.localtime())), image)
+ # if kp.getKey("UP"):# 上升
+ if key == "UP":
+ Drone.takeoff()
+ # elif kp.getKey("DOWN"):#下降
+ if key == "DOWN":
+ Drone.land()
+
+ # if kp.getKey("j"):# 向左飞行
+ if key == "j":
+ key_pressed = 1
+ lr = -speed
+ # elif kp.getKey("l"): #向右飞行
+ if key == "l":
+ key_pressed = 1
+ lr = speed
+
+ # if kp.getKey("i"): #向前飞行
+ if key == "i":
+ key_pressed = 1
+ fb = speed
+ # elif kp.getKey("k"):# 向后飞行
+ if key == "k":
+ key_pressed = 1
+ fb = -speed
+
+ # if kp.getKey("w"):# 向上飞行
+ if key == "w":
+ key_pressed = 1
+ ud = speed
+ # elif kp.getKey("s"): #向下飞行
+ if key == "s":
+ key_pressed = 1
+ ud = -speed
+
+ # if kp.getKey("a"): # 向左旋转
+ if key == "a":
+ key_pressed = 1
+ yv = -speed
+ # elif kp.getKey("d"): #向右旋转
+ if key == "d":
+ key_pressed = 1
+ yv = speed
+ InfoText = "battery : {0}% height: {1}cm time: {2}".format(drone.get_battery(), drone.get_height(), time.strftime("%H:%M:%S",time.localtime()))
+ cv2.putText(image, InfoText, (10, 20), font, fontScale, (0, 0, 255), lineThickness)
+ if key_pressed == 1:
+ InfoText = "Command : lr:{0}% fb:{1} ud:{2} yv:{3}".format(lr, fb, ud, yv)
+ cv2.putText(image, InfoText, (10, 40), font, fontScale, (0, 0, 255), lineThickness)
+
+ drone.send_rc_control(lr, fb, ud, yv)
+
+# 主程序
+# 摄像头设置
+Camera_Width = 720
+Camera_Height = 480
+DetectRange = [6000, 11000] # DetectRange[0] 是保持静止的检测人脸面积阈值下限,DetectRange[0] 是保持静止的检测人脸面积阈值上限
+PID_Parameter = [0.5, 0.0004, 0.4]
+pErrorRotate, pErrorUp = 0, 0
+
+# 字体设置
+font = cv2.FONT_HERSHEY_SIMPLEX
+fontScale = 0.5
+fontColor = (255, 0, 0)
+lineThickness = 1
+
+
+
+
+while True:
+ OriginalImage = Drone.get_frame_read().frame
+ Image = cv2.resize(OriginalImage, (Camera_Width, Camera_Height))
+ # getKeyboardInput(drone=Drone, speed=70, image=Image) # 按键控制
+ cv2.imshow("Drone Control Centre", Image)
+ cv2.waitKey(1)
\ No newline at end of file
diff --git a/src/Tello/__pycache__/KeyPress.cpython-39.pyc b/src/Tello/__pycache__/KeyPress.cpython-39.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..3608c273562197b015319bf3caa884701c678177
GIT binary patch
literal 564
zcmZ`#!Ait15S=vLZV*@YBSfgM74#+|!s1CN3-u%mrEcaRn{Fl9Jrum@&-9ma_2e&j
zawb|_!A_dVBr~0P?^Tn@0gyG*_VHK%yz^z>BD&nrcBkYtXz>OQpd&5m6gt);IwO=i
zSx5E+;S~hvaRI4XQT-pI?l7nAc;NQC5(?-<-U+YP*e)zO*MW^GAKWM2UM?4v)&}RM
zax;qtD~Gf5>|*Ho9*t?vvW&lhKSRm#?q^>1-1@k#o;G8K#%w{@g#3!}_Qo;i0{$rl
zFQf!9KGab`st{k9e{hi(7@()ZOQQ74#f~UzB{`<=m?H=!!ppE!41}dBz;buX81{Mw
zrMR(ANV}cc9#Pzr;5lBEC6g=5JdFdbFwpk7O;uxA{@YPq)s5a6ybi)BYNn)$X^AhT
C9%SSI
literal 0
HcmV?d00001
diff --git a/src/Tello/__pycache__/KeyPressModule.cpython-39.pyc b/src/Tello/__pycache__/KeyPressModule.cpython-39.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..1114802427f189c6218d58751d955cb5d2968986
GIT binary patch
literal 657
zcmaJ;v2NQi5WS;hiFNG2LxD~Kx_XETG+R*=1%ggRjR4I=7!{cC+A5}HLsSM8$&`LZ
zhj{GwWaFACzmO?M1`af&J?I|q$kXGyqaKfkz;-j~PW}jh+mQ4v=j0>1`^I3vpau1~
zqC&zmah(t_rV$5}ZE%A|yn+qlV_m+K>IKJ%Nq>VHnt{o9-Jy}m7ot%#yaGPOuP~K&
zda?Y$|A@EvJmEFD_y_8YRK9qqp@4o*W+-;k3-c9$|3U?QCTg@(K7!TsXXyZQ5k
z|Jpt#Yghl3GLI$m&(s|?y(E?B+Vz?YWIp>rEvuPu>@o((Mwp5w
zJffFnxztr%mea8pE9Vo}IiId|`_pH7y{6ju+*D1?+&HGw=a(q}
literal 0
HcmV?d00001
diff --git a/src/Tello/__pycache__/KeyboardControl.cpython-39.pyc b/src/Tello/__pycache__/KeyboardControl.cpython-39.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..aad69a24e4494962325000aa82ae17fa4da1fc3e
GIT binary patch
literal 2022
zcmaJ>&2Jk;6yMozf5!Q4OF!IFw{@kY&>{{NP$b7~BGM#sQWZu~t&L~wth3&AXD11E
zy%G}q0lmV>=Eez$KYKo>|koB0L~6_&;8Isvm@mYM1CR(rH^CXKekSTnT{B4Kdqd4U{+9;Ka;0n6%0E}lHH<_TzJXd#0ct_%=YxyE&w
zM}!E9RBl8XQFrx7kBrESETTnrUm^N|$~GY0B*wtv_8>t_u*sn^REMaKWabcMLDXYz
z3{tXwfNj7&;PeD10DnZ1z^JB_NQa0Nc%F?tF-`*>Ot1m-8NgqitdO28c)p%Qn1H7M
ze|HigJvs3FbmFnVGYy_!Cu=M+GqC!aJae$wp%U+A_GC9&lz@Fs^-(`T=6H@zlX*Tf
zv|v9rNgk-r5PM7(fI;sYeY0;3^;7YS|A^NHvoE5g=HN8XY>e(f`HQ-&zw$C85bb4G
zO1DDa=`1~smRp@>&n&DK9u&5P`fv;DE1Qot1Zs^Wfk2)>u0RI@9Sal+ruU(&*!<@rhsloJ-e`4Dm*9^wu|aW%40Mqlha=0HTn}A
zy=-FAEegdQu!oQ=H_(B%(F33&3|qteqmQBh^nlH`UYnG;(5=(aE!4c#6UnN8+4
zUElH6+D?;-blGWB=F}d!gzt;Y1g*x23S)%@KE;;XK4vbb!fXVr?Qo&X#DyJl)`&+5
zFQ_}79Ab+*2Q+9juFTchA<$l8d_ww)V$eX|W9_{W04kP7p#><_q$ideC
zcCY!c_cM?{SOue?9Ma)UBVD!8MQFBcnhib^MlctT}eRFvm;n@i>Mzx?oK>2CA0Pv!IdUC_*nn^1%xP~R+cr@Zn%
zt2Y;GB0t$%zD(g%Xz{vGgHUK;Hxzou0VSDErvnEkEaEaBBql6pFN|mGTCL%Fv{nXC915k`@RJirDEg*nq+`FxZIe%Ff9M3v}SqI>%Ce)M*DkHrF@r->+0b
zkd&{}BkBpGQmt-Q<3cc5X?9l9q*f@0l~u=YQk>aZTd8e1403}jiqoA6V*#rM+~E}4
zWAw0t=k9H8?9^5()$P^F2es|B2V3iv_t_=MnU|cgaLa)gFm_qutkifzveqCwB8+&<
z;0P4907e+`y~C#44)=p&Y#lqUR7R}GQ|7viwclz7lTj+fqd_)=a4yq?@1zHI4oPVo(@l
literal 0
HcmV?d00001
diff --git a/src/prepare/calculate.py b/src/prepare/calculate.py
new file mode 100644
index 0000000..7182c26
--- /dev/null
+++ b/src/prepare/calculate.py
@@ -0,0 +1,12 @@
+# @Time : 2022/5/9 8:45
+# @Author : 2890199310@qq.com
+# @File : calculate.py
+# @Software: PyCharm
+# @Function:
+import os
+
+os.chdir(r'E:\PaddleClas-release-2.3\PaddleClas-release-2.3\deploy')
+
+####
+
+os.system('python python/predict_system.py -c configs/inference_general.yaml -o Global.infer_imgs="./Trees/test_images/90.jpeg" -o IndexProcess.index_dir="./Trees/index" -o Global.use_gpu=False -o IndexProcess.Image_root="./Trees/gallery/" -o IndexProcess.data_file="./Trees/gallery/tree_list.txt')
diff --git a/src/prepare/change_file.py b/src/prepare/change_file.py
new file mode 100644
index 0000000..2c06271
--- /dev/null
+++ b/src/prepare/change_file.py
@@ -0,0 +1,84 @@
+# @Time : 2022/4/19 9:41
+# @Author : 2890199310@qq.com
+# @File : change_file.py
+# @Software: PyCharm
+# @Function:
+
+import os
+import shutil
+
+# 读取文件名
+def readname():
+ filepath = "/deploy/Trees/gallery/0"
+ name = os.listdir(filepath)
+ return name
+
+def main():
+ gallery = os.path.abspath(r"/deploy/drink_dataset_v1.0/gallery")
+ all_files = os.listdir(gallery)[:-2]
+ all_files.sort(key=lambda x:int(x))
+ # for file in all_files:
+ # print(file)
+
+ for i in range(0, 102): #创建文件夹
+ dire = "E:\\PaddleClas-release-2.3\\PaddleClas-release-2.3\\deploy\\flowers102\\gallery\\" + str(i)
+ if not os.path.exists(dire):
+ os.makedirs(dire)
+ print(f"{i}创建完毕")
+ f = open(r"/deploy/flowers102/train_extra_list.txt")
+ for line in f.readlines():
+ base = "E://PaddleClas-release-2.3//PaddleClas-release-2.3/deploy//flowers102//"
+ s = line.split('/')
+
+ str1 = s[0].strip() + "//"
+ str2 = s[1].split(' ')[0].strip()
+ str3 = s[1].split(' ')[1].strip() + "//"
+ # print(base + "gallery//" + str3 + str2)
+
+ # 复制训练文件
+ # shutil.copy(base + str1 + str2, base + "gallery/" + str3 + str2)
+ f.close()
+
+ f = open(r"/deploy/flowers102/val_list.txt")
+ for line in f.readlines():
+ base = "E://PaddleClas-release-2.3//PaddleClas-release-2.3/deploy//flowers102//"
+ s = line.split('/')
+ str1 = s[0].strip() + "//"
+ str2 = s[1].split(' ')[0].strip()
+ str3 = s[1].split(' ')[1].strip() + "//"
+ # 复制测试文件
+ # shutil.copy(base + str1 + str2, base + "test_images/" + str2)
+ f.close()
+
+ dit = dict()
+
+
+ with open(r"/deploy/flowers102/flowers102_label_list.txt", "r", encoding="utf-8") as f2:
+ for line in f2.readlines():
+ tmp = line.split(' ', 1)
+ dit[tmp[0]] = tmp[1].strip()
+ #print(dit)
+
+ #更改list内容
+ with open(r"/deploy/flowers102/train_list.txt", "r", encoding="utf-8") as f1, open(
+ r"/deploy/flowers102/train_label.txt", "w", encoding="utf-8") as f3:
+ for line1 in f1.readlines():
+ tmp1 = line1.split(' ', 1)
+ # f3.write(tmp1[1].strip() + '/' + tmp1[0].split('/', 1)[1].strip() + '\t' + dit[tmp1[1].strip()] + '\n')
+
+ # print(line1)
+ # print(line2)
+ # break
+ f1.close()
+ f2.close()
+ f3.close()
+ with open(r"/deploy/Trees/gallery/tree_list.txt", "w", encoding="utf-8") as f1:
+ name = readname()
+ for i in name:
+ if('GIF' not in i):
+ f1.write('0/' + i + '\t' + 'tree\n')
+ f1.close()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/src/prepare/spider.py b/src/prepare/spider.py
new file mode 100644
index 0000000..0373296
--- /dev/null
+++ b/src/prepare/spider.py
@@ -0,0 +1,5 @@
+# @Time : 2022/4/19 9:54
+# @Author : 2890199310@qq.com
+# @File : spider.py
+# @Software: PyCharm
+# @Function:
diff --git a/src/qt/__pycache__/page1.cpython-39.pyc b/src/qt/__pycache__/page1.cpython-39.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..54af08ca664089b785849ea89f949364e56dfb4f
GIT binary patch
literal 4957
zcmbtY-ESMm5#Ku=$slH&H7f<19p($PmA
zy?0D3LV2l;T6t+vz(xDggbY#y28yCUfjrc0`fn8XRG^hrJ@>6B>i%Z$NSzofw&J69
zZ+3QWW_EUVW>)s-XrAFIOm&ujGRfFKXpnre7(9>WZ=mChYc8|st-D%7xAaEJN@)?^
zunaYyw$j3=XS!LDMsKP
z#%`pnajq?}N_Gbtu-S?pX6Azno)lqjKDgrWRT21|6JMQ~p}#qsb5~q&ZU0#*Tw(j-
z*;6y8D_W?1rAD78A030|(fnu731(@WSvuFaev?@#p5g}HMx=<9=2>oHoZ&gBk`K)#
zr~0xd8z*bTrT?S=m}vC&|Av_jtqYUUk^zA;PxW+-1$sBN0qiEL8k?+cbkhOM#g#0c
z?HNQ58Z*%AW<3}6J^dYhL+|FfskrIgkpWatJVtx0TkI+Gs`1!{PLv8}Ja-VDkUbvj
zSHkzDSid|U;RQb0GxqSBQ2I?gM88sZuYRTOu70KNA*_Fr7kRPQ*SQ3{jm2{Mwwi)2
zQ?V}Nv@f62R#QW|OeJ)gg51)O+%n{rW4RNLA-6mvx15k$hTKE3+{3Z$ry+NG;2Q>?
z9*WG>(y-6KMx=x
zel*=B0ycy81u1Ht3Ge+b{7IEg4$X*0qh$>1`gKQ$CZduIIC*`JPCn3SPS!{M$E6YX8S|aq;^80Ie$5F
z8aWE3tlXRwD?&;rQ3T;-`?}L;H;5kk(n}UWCdX(2nfdRM+sFyRkW+-CP*mDY-?am=
zFqy*
znSkA3?`VOBo^p*I#Rg=q6lF!qTpKD|4e*&B(^%&=awT)K4f9<@l?}a~tLM8Tw=#$%
z$Y@a{0k)v9I`*y?A
zBLs^_5^T6)B^VOD*cbiz){>TVn1^^SJs!_2j%8amPY!W?ZsDi%?{uloS<<%E9#6P;>5R);J2>*Tnj=XG?ym*=k1y
zMvl_2E+*zy7at-&a_IwVVChS9`>XH`h$n{q9e9Wd
zl>Z-80pq3DugvbR!Z#tF>axBH4+&rW<5HQRWNSOkD^8PpZ(G^ec=9xOSp_6bRamG5
zPI*2o;EuP@UXI97slmgnsYT(s-c0|TTtM+5J=Yo=La2I1o&*uA)aJ&qYE|LQ8~%;~1`@`IP-=F$JwNHBd8Iv3}|boyG@B
z&$j>s(6COIUz8ym>Uw@dT@vF`gfOWACeuwT8e@RT#+dW~W5$@w0F#R`*$AVeuQ{s<
zIczXh@@-ngzyA8(y`TM7f!lw+v-O9cEAZa!Pqse%s7*!P*6-iD_p6V$Z{OYd%?I~>
z{mJ%+f7<@z-R-;Yw+r<3M?c;9;1^qe`Q_H;$CZ3kMvu?a|1n-@wNOghf#Ws9+@Jx@6+O`|bs3R-MjU{crBuNSB%0pCMq#dThSY5?T
z%{*nEFbzrAO3BK)-s-B;Tn*E6>+```Wvb|ElJeL6Q1|@MXxX?eWb9T;G*N+bN0I_z
z)?W7240K&_NI&byLQM+MM34w(cERe!wquzA#f<9GB`eSCjvC;?W&{r1h&**WQYt-Y
b1-REmCOA(wTA!{Fralf^n%Yy;r>OlOg)L(F
literal 0
HcmV?d00001
diff --git a/src/qt/__pycache__/page2.cpython-39.pyc b/src/qt/__pycache__/page2.cpython-39.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f7d7721151b6dc5300679df425356ec7e878bebf
GIT binary patch
literal 8353
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
qEzKPUa#W=<$)F)()8nO?9JkPusjd8= 1:
+ p_k, v_k = self.repeated_searching(self.s_start, self.s_goal, e)
+ path.append(p_k)
+ visited.append(v_k)
+ e -= 0.5
+
+ return path, visited
+
+ def repeated_searching(self, s_start, s_goal, e):
+ """
+ run A* with weight e.
+ :param s_start: starting state
+ :param s_goal: goal state
+ :param e: weight of a*
+ :return: path and visited order.
+ """
+
+ g = {s_start: 0, s_goal: float("inf")}
+ PARENT = {s_start: s_start}
+ OPEN = []
+ CLOSED = []
+ heapq.heappush(OPEN,
+ (g[s_start] + e * self.heuristic(s_start), s_start))
+
+ while OPEN:
+ _, s = heapq.heappop(OPEN)
+ CLOSED.append(s)
+
+ if s == s_goal:
+ break
+
+ for s_n in self.get_neighbor(s):
+ new_cost = g[s] + self.cost(s, s_n)
+
+ if s_n not in g:
+ g[s_n] = math.inf
+
+ if new_cost < g[s_n]: # conditions for updating Cost
+ g[s_n] = new_cost
+ PARENT[s_n] = s
+ heapq.heappush(OPEN, (g[s_n] + e * self.heuristic(s_n), s_n))
+
+ return self.extract_path(PARENT), CLOSED
+
+ def get_neighbor(self, s):
+ """
+ find neighbors of state s that not in obstacles.
+ :param s: state
+ :return: neighbors
+ """
+
+ return [(s[0] + u[0], s[1] + u[1]) for u in self.u_set]
+
+ def cost(self, s_start, s_goal):
+ """
+ Calculate Cost for this motion
+ :param s_start: starting node
+ :param s_goal: end node
+ :return: Cost for this motion
+ :note: Cost function could be more complicate!
+ """
+
+ if self.is_collision(s_start, s_goal):
+ return math.inf
+
+ return math.hypot(s_goal[0] - s_start[0], s_goal[1] - s_start[1])
+
+ def is_collision(self, s_start, s_end):
+ """
+ check if the line segment (s_start, s_end) is collision.
+ :param s_start: start node
+ :param s_end: end node
+ :return: True: is collision / False: not collision
+ """
+
+ if s_start in self.obs or s_end in self.obs:
+ return True
+
+ if s_start[0] != s_end[0] and s_start[1] != s_end[1]:
+ if s_end[0] - s_start[0] == s_start[1] - s_end[1]:
+ s1 = (min(s_start[0], s_end[0]), min(s_start[1], s_end[1]))
+ s2 = (max(s_start[0], s_end[0]), max(s_start[1], s_end[1]))
+ else:
+ s1 = (min(s_start[0], s_end[0]), max(s_start[1], s_end[1]))
+ s2 = (max(s_start[0], s_end[0]), min(s_start[1], s_end[1]))
+
+ if s1 in self.obs or s2 in self.obs:
+ return True
+
+ return False
+
+ def f_value(self, s):
+ """
+ f = g + h. (g: Cost to come, h: heuristic value)
+ :param s: current state
+ :return: f
+ """
+
+ return self.g[s] + self.heuristic(s)
+
+ def extract_path(self, PARENT):
+ """
+ Extract the path based on the PARENT set.
+ :return: The planning path
+ """
+
+ path = [self.s_goal]
+ s = self.s_goal
+
+ while True:
+ s = PARENT[s]
+ path.append(s)
+
+ if s == self.s_start:
+ break
+
+ return list(path)
+
+ def heuristic(self, s):
+ """
+ Calculate heuristic.
+ :param s: current node (state)
+ :return: heuristic function value
+ """
+
+ heuristic_type = self.heuristic_type # heuristic type
+ goal = self.s_goal # goal node
+
+ if heuristic_type == "manhattan":
+ return abs(goal[0] - s[0]) + abs(goal[1] - s[1])
+ else:
+ return math.hypot(goal[0] - s[0], goal[1] - s[1])
+
+
+
+class Ui_MainWindow1(object):
+ def setupUi(self, MainWindow):
+ MainWindow.setObjectName("MainWindow")
+ MainWindow.resize(1112, 766)
+ self.centralwidget = QtWidgets.QWidget(MainWindow)
+ self.centralwidget.setObjectName("centralwidget")
+ self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
+ self.gridLayout.setObjectName("gridLayout")
+ self.pushButton = QtWidgets.QPushButton(self.centralwidget)
+ self.pushButton.setObjectName("pushButton")
+ self.gridLayout.addWidget(self.pushButton, 2, 0, 1, 1)
+ self.mdiArea = QtWidgets.QMdiArea(self.centralwidget)
+ self.mdiArea.setObjectName("mdiArea")
+ self.gridLayout.addWidget(self.mdiArea, 1, 0, 1, 1)
+ self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
+ self.pushButton_2.setObjectName("pushButton_2")
+ self.gridLayout.addWidget(self.pushButton_2, 3, 0, 1, 1)
+ self.label = QtWidgets.QLabel(self.centralwidget)
+ self.label.setObjectName("label")
+ self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
+ MainWindow.setCentralWidget(self.centralwidget)
+ self.menubar = QtWidgets.QMenuBar(MainWindow)
+ self.menubar.setGeometry(QtCore.QRect(0, 0, 1112, 23))
+ self.menubar.setObjectName("menubar")
+ MainWindow.setMenuBar(self.menubar)
+ self.statusbar = QtWidgets.QStatusBar(MainWindow)
+ self.statusbar.setObjectName("statusbar")
+ MainWindow.setStatusBar(self.statusbar)
+ self.retranslateUi(MainWindow)
+ QtCore.QMetaObject.connectSlotsByName(MainWindow)
+ self.pushButton.clicked.connect(lambda: self.msg())
+ self.pushButton_2.clicked.connect(lambda: self.search())
+ def search(self):
+ s_start = (5, 5)
+ s_goal = (45, 25)
+
+ astar = AStar(s_start, s_goal, "euclidean")
+ plot = plotting.Plotting(s_start, s_goal)
+
+ path, visited = astar.searching()
+ plot.animation(path, visited, "A*") # animation
+ def msg(self):
+ MainWindow = QMainWindow()
+ ui = Ui_MainWindow()
+ ui.setupUi(MainWindow)
+ self.mdiArea.addSubWindow(MainWindow)
+ MainWindow.showMaximized()
+ ui.player = QMediaPlayer()
+ ui.player.setVideoOutput(ui.wgt_video)
+ ui.pushButton.clicked.connect(lambda: openVideoFile(ui))
+ ui.player.setMedia(QMediaContent(QFileDialog.getOpenFileUrl()[0]))
+ ui.pushButton_2.clicked.connect(lambda: pause(ui))
+ def pause(a):
+ a.player.pause()
+ def openVideoFile(a):
+ a.player.play()
+ def retranslateUi(self, MainWindow):
+ _translate = QtCore.QCoreApplication.translate
+ MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
+ self.pushButton.setText(_translate("MainWindow", "添加文件"))
+ self.pushButton_2.setText(_translate("MainWindow", "分析路径"))
+ self.label.setText(_translate("MainWindow", "路径分析界面"))
diff --git a/src/qt/system_main.py b/src/qt/system_main.py
new file mode 100644
index 0000000..e45f8b7
--- /dev/null
+++ b/src/qt/system_main.py
@@ -0,0 +1,96 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'system_main.ui'
+#
+# Created by: PyQt5 UI code generator 5.15.4
+#
+# WARNING: Any manual changes made to this file will be lost when pyuic5 is
+# run again. Do not edit this file unless you know what you are doing.
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+import sys
+import os
+from PyQt5.QtWidgets import *
+from page1 import Ui_Form1
+from page2 import Ui_MainWindow1
+
+sys.path.append(os.path.dirname(os.path.abspath(__file__)) + "/../../PaddleClas-release-2.3")
+class Ui_MainWindow(object):
+ def setupUi(self, MainWindow):
+ MainWindow.setObjectName("MainWindow")
+ MainWindow.resize(1275, 896)
+ self.centralwidget = QtWidgets.QWidget(MainWindow)
+ self.centralwidget.setObjectName("centralwidget")
+ self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
+ self.gridLayout.setObjectName("gridLayout")
+ self.label = QtWidgets.QLabel(self.centralwidget)
+ self.label.setMinimumSize(QtCore.QSize(0, 20))
+ self.label.setMaximumSize(QtCore.QSize(300, 20))
+ self.label.setTextFormat(QtCore.Qt.AutoText)
+ self.label.setAlignment(QtCore.Qt.AlignCenter)
+ self.label.setObjectName("label")
+ self.gridLayout.addWidget(self.label, 1, 0, 1, 1)
+ self.groupBox = QtWidgets.QGroupBox(self.centralwidget)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.groupBox.sizePolicy().hasHeightForWidth())
+ self.groupBox.setSizePolicy(sizePolicy)
+ self.groupBox.setMaximumSize(QtCore.QSize(600, 16777215))
+ self.groupBox.setFlat(False)
+ self.groupBox.setCheckable(False)
+ self.groupBox.setObjectName("groupBox")
+ self.gridLayout_2 = QtWidgets.QGridLayout(self.groupBox)
+ self.gridLayout_2.setObjectName("gridLayout_2")
+ self.pushButton = QtWidgets.QPushButton(self.groupBox)
+ self.pushButton.setObjectName("pushButton")
+ self.gridLayout_2.addWidget(self.pushButton, 0, 0, 1, 1)
+ self.pushButton_2 = QtWidgets.QPushButton(self.groupBox)
+ self.pushButton_2.setObjectName("pushButton_2")
+ self.gridLayout_2.addWidget(self.pushButton_2, 1, 0, 1, 1)
+ self.gridLayout.addWidget(self.groupBox, 2, 0, 2, 1)
+ self.mdiArea = QtWidgets.QMdiArea(self.centralwidget)
+ self.mdiArea.setObjectName("mdiArea")
+ self.gridLayout.addWidget(self.mdiArea, 2, 1, 2, 1)
+ MainWindow.setCentralWidget(self.centralwidget)
+ self.menubar = QtWidgets.QMenuBar(MainWindow)
+ self.menubar.setGeometry(QtCore.QRect(0, 0, 1275, 23))
+ self.menubar.setObjectName("menubar")
+ MainWindow.setMenuBar(self.menubar)
+ self.statusbar = QtWidgets.QStatusBar(MainWindow)
+ self.statusbar.setObjectName("statusbar")
+ MainWindow.setStatusBar(self.statusbar)
+ self.pushButton.clicked.connect(lambda: self.open1())
+ self.pushButton_2.clicked.connect(lambda: self.open2())
+ self.retranslateUi(MainWindow)
+ QtCore.QMetaObject.connectSlotsByName(MainWindow)
+
+ def open1(self):
+ MainWindow = QMainWindow()
+ ui = Ui_Form1()
+ ui.setupUi(MainWindow)
+ self.mdiArea.addSubWindow(MainWindow)
+ MainWindow.showMaximized()
+
+ def open2(self):
+ MainWindow = QMainWindow()
+ ui = Ui_MainWindow1()
+ ui.setupUi(MainWindow)
+ self.mdiArea.addSubWindow(MainWindow)
+ MainWindow.showMaximized()
+
+ def retranslateUi(self, MainWindow):
+ _translate = QtCore.QCoreApplication.translate
+ MainWindow.setWindowTitle(_translate("MainWindow", "无人机自动寻路系统"))
+ self.label.setText(_translate("MainWindow", "无人机自动寻路系统(主界面)"))
+ self.groupBox.setTitle(_translate("MainWindow", "菜单栏"))
+ self.pushButton.setText(_translate("MainWindow", "实时画面"))
+ self.pushButton_2.setText(_translate("MainWindow", "路径分析"))
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+ MainWindow = QMainWindow()
+ ui = Ui_MainWindow()
+ ui.setupUi(MainWindow)
+ MainWindow.show()
+ sys.exit(app.exec_())
\ No newline at end of file
diff --git a/src/qt/tello_UI.py b/src/qt/tello_UI.py
new file mode 100644
index 0000000..02977ce
--- /dev/null
+++ b/src/qt/tello_UI.py
@@ -0,0 +1,97 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'tello_UI.ui'
+#
+# Created by: PyQt5 UI code generator 5.15.4
+#
+# WARNING: Any manual changes made to this file will be lost when pyuic5 is
+# run again. Do not edit this file unless you know what you are doing.
+
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+
+class Ui_Form(object):
+ def setupUi(self, Form):
+ Form.setObjectName("Form")
+ Form.resize(1022, 618)
+ self.groupBox_4 = QtWidgets.QGroupBox(Form)
+ self.groupBox_4.setGeometry(QtCore.QRect(670, 567, 350, 50))
+ self.groupBox_4.setMaximumSize(QtCore.QSize(350, 50))
+ self.groupBox_4.setObjectName("groupBox_4")
+ self.lineEdit_3 = QtWidgets.QLineEdit(self.groupBox_4)
+ self.lineEdit_3.setGeometry(QtCore.QRect(10, 20, 331, 20))
+ self.lineEdit_3.setObjectName("lineEdit_3")
+ self.groupBox_2 = QtWidgets.QGroupBox(Form)
+ self.groupBox_2.setGeometry(QtCore.QRect(670, 156, 350, 405))
+ self.groupBox_2.setObjectName("groupBox_2")
+ self.pushButton = QtWidgets.QPushButton(self.groupBox_2)
+ self.pushButton.setGeometry(QtCore.QRect(150, 120, 71, 71))
+ self.pushButton.setText("")
+ icon = QtGui.QIcon()
+ icon.addPixmap(QtGui.QPixmap("tello_png/up.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.pushButton.setIcon(icon)
+ self.pushButton.setIconSize(QtCore.QSize(70, 100))
+ self.pushButton.setObjectName("pushButton")
+ self.pushButton_2 = QtWidgets.QPushButton(self.groupBox_2)
+ self.pushButton_2.setGeometry(QtCore.QRect(70, 200, 71, 71))
+ self.pushButton_2.setText("")
+ icon1 = QtGui.QIcon()
+ icon1.addPixmap(QtGui.QPixmap("tello_png/left.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.pushButton_2.setIcon(icon1)
+ self.pushButton_2.setIconSize(QtCore.QSize(70, 100))
+ self.pushButton_2.setObjectName("pushButton_2")
+ self.pushButton_4 = QtWidgets.QPushButton(self.groupBox_2)
+ self.pushButton_4.setGeometry(QtCore.QRect(230, 200, 71, 71))
+ self.pushButton_4.setText("")
+ icon2 = QtGui.QIcon()
+ icon2.addPixmap(QtGui.QPixmap("tello_png/right.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.pushButton_4.setIcon(icon2)
+ self.pushButton_4.setIconSize(QtCore.QSize(70, 100))
+ self.pushButton_4.setObjectName("pushButton_4")
+ self.pushButton_5 = QtWidgets.QPushButton(self.groupBox_2)
+ self.pushButton_5.setGeometry(QtCore.QRect(150, 200, 71, 71))
+ self.pushButton_5.setText("")
+ icon3 = QtGui.QIcon()
+ icon3.addPixmap(QtGui.QPixmap("tello_png/return.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.pushButton_5.setIcon(icon3)
+ self.pushButton_5.setIconSize(QtCore.QSize(70, 100))
+ self.pushButton_5.setObjectName("pushButton_5")
+ self.pushButton_3 = QtWidgets.QPushButton(self.groupBox_2)
+ self.pushButton_3.setGeometry(QtCore.QRect(70, 20, 231, 91))
+ icon4 = QtGui.QIcon()
+ icon4.addPixmap(QtGui.QPixmap("tello_png/qifei.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.pushButton_3.setIcon(icon4)
+ self.pushButton_3.setIconSize(QtCore.QSize(150, 150))
+ self.pushButton_3.setObjectName("pushButton_3")
+ self.pushButton_6 = QtWidgets.QPushButton(self.groupBox_2)
+ self.pushButton_6.setGeometry(QtCore.QRect(70, 290, 231, 91))
+ icon5 = QtGui.QIcon()
+ icon5.addPixmap(QtGui.QPixmap("tello_png/jiangluo.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.pushButton_6.setIcon(icon5)
+ self.pushButton_6.setIconSize(QtCore.QSize(150, 150))
+ self.pushButton_6.setObjectName("pushButton_6")
+ self.groupBox = QtWidgets.QGroupBox(Form)
+ self.groupBox.setGeometry(QtCore.QRect(670, 0, 350, 150))
+ self.groupBox.setMaximumSize(QtCore.QSize(16777215, 150))
+ self.groupBox.setObjectName("groupBox")
+ self.lineEdit = QtWidgets.QLineEdit(self.groupBox)
+ self.lineEdit.setGeometry(QtCore.QRect(20, 20, 311, 41))
+ self.lineEdit.setObjectName("lineEdit")
+ self.lineEdit_2 = QtWidgets.QLineEdit(self.groupBox)
+ self.lineEdit_2.setGeometry(QtCore.QRect(20, 70, 311, 41))
+ self.lineEdit_2.setObjectName("lineEdit_2")
+
+ self.retranslateUi(Form)
+ QtCore.QMetaObject.connectSlotsByName(Form)
+
+ def retranslateUi(self, Form):
+ _translate = QtCore.QCoreApplication.translate
+ Form.setWindowTitle(_translate("Form", "Form"))
+ self.groupBox_4.setTitle(_translate("Form", "连接状态"))
+ self.groupBox_2.setTitle(_translate("Form", "控制面板"))
+ self.pushButton_3.setText(_translate("Form", "起飞"))
+ self.pushButton_6.setText(_translate("Form", "降落"))
+ self.groupBox.setTitle(_translate("Form", "无人机状态"))
+ self.lineEdit.setText(_translate("Form", "剩余电量:"))
+ self.lineEdit_2.setText(_translate("Form", "WIFI强度:"))
diff --git a/src/qt/tello_png/jiangluo.png b/src/qt/tello_png/jiangluo.png
new file mode 100644
index 0000000000000000000000000000000000000000..22b198d3b0479ef457b1e9705f0a85a5f7f45c56
GIT binary patch
literal 62321
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