ControllWidget.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. import datetime
  2. import math
  3. import random
  4. import time
  5. from concurrent.futures import ThreadPoolExecutor, as_completed, wait
  6. from PyQt5.QtWidgets import QWidget, QFrame, QLabel, QLineEdit, QPushButton, QComboBox, QCheckBox
  7. from PyQt5.QtGui import QPixmap, QPainter, QResizeEvent, QCloseEvent, QPaintEvent, QFont
  8. from PyQt5.QtCore import QSize, QTimer, Qt
  9. import Count
  10. import message_pb2
  11. from RobotData import Robot
  12. import dijkstra.Map as mp
  13. from custom_define import ControllerStatus
  14. import MapGLWidget as viewer
  15. import dijkstra.Map as Map
  16. class ControlFrame(QFrame):
  17. threadPool_ = ThreadPoolExecutor(5)
  18. last_beg = "**"
  19. begId_ = "------"
  20. targetId_ = "------"
  21. def __init__(self, config):
  22. QFrame.__init__(self)
  23. self.street_nodes_ = config['street_nodes']
  24. self.space_nodes_ = config['space_nodes']
  25. self.label_ = config['label']
  26. [id, ip, port, user, pawd] = config['mqtt']
  27. subtopics = config['subTopics']
  28. cmdTopic = config['cmdTopic']
  29. robotColor = config['robotColor']
  30. self.all_nodes_ = []
  31. for node in self.street_nodes_:
  32. self.all_nodes_.append(node)
  33. for node in self.space_nodes_:
  34. self.all_nodes_.append(node)
  35. self.select_map = None
  36. self.default_wheel_base = 2.6
  37. rpc = config['rpc']
  38. self.robot_ = Robot(rpc, self.label_)
  39. self.robot_.connect(id, ip, port, user, pawd)
  40. self.robot_.SetSubDataTopic(subtopics, self.messageArrived)
  41. self.robot_.SetCmdTopic(cmdTopic)
  42. self.robot_.loop_start()
  43. self.robot_.SetColor(robotColor, robotColor)
  44. self.setGeometry(0, 0, 500, 500)
  45. self.InitUI()
  46. self.setFrameShape(self.StyledPanel)
  47. self.timer_ = QTimer()
  48. self.timer_.timeout.connect(self.Update)
  49. self.timer_.start(100)
  50. def messageArrived(self):
  51. pass
  52. # self.gl.update()
  53. def InitUI(self):
  54. self.basestatic = QLabel(self)
  55. self.basestatic.setText(self.label_)
  56. self.basestatic.setGeometry(20, 20, 80, 30)
  57. self.begstatic = QLabel(self)
  58. self.begstatic.setText(" 起点")
  59. self.begstatic.setGeometry(90, 5, 80, 30)
  60. self.begQc = QComboBox(self)
  61. self.begQc.setGeometry(160, 5, 80, 30)
  62. self.endstatic = QLabel(self)
  63. self.endstatic.setText("去马路点")
  64. self.endstatic.setGeometry(90, 50, 80, 30)
  65. self.endStreetQc = QComboBox(self)
  66. self.endStreetQc.setGeometry(160, 50, 80, 30)
  67. self.endstatic = QLabel(self)
  68. self.endstatic.setText("去车位点")
  69. self.endstatic.setGeometry(90, 95, 80, 30)
  70. self.endSpaceQc = QComboBox(self)
  71. self.endSpaceQc.setGeometry(160, 95, 80, 30)
  72. self.btnSend = QPushButton(self)
  73. self.btnSend.setGeometry(150, 140, 100, 40)
  74. self.btnSend.setText(" 开始")
  75. self.btnSend.clicked.connect(self.btnSendClick)
  76. self.btnCancel = QPushButton(self)
  77. self.btnCancel.setGeometry(150, 190, 100, 40)
  78. self.btnCancel.setText(" 取消")
  79. self.btnCancel.clicked.connect(self.btnCancelClick)
  80. self.begQc.addItems(self.all_nodes_)
  81. self.endStreetQc.addItems(self.street_nodes_)
  82. self.endStreetQc.addItem("------")
  83. self.endSpaceQc.addItem("------")
  84. self.endSpaceQc.addItems(self.space_nodes_)
  85. self.endStreetQc.activated.connect(self.endStreetQCChanged)
  86. self.endSpaceQc.activated.connect(self.endSpaceQCChanged)
  87. self.posestatic = QLabel(self)
  88. self.posestatic.setGeometry(260, 20, 100, 90)
  89. self.LedLabel = QLabel(self)
  90. self.LedLabel.setGeometry(80, 160, 50, 50)
  91. # 发送轴距
  92. self.wheelbasestatic = QLabel(self)
  93. self.wheelbasestatic.setText("轴距:")
  94. self.wheelbasestatic.setGeometry(260, 100, 40, 30)
  95. self.WheelBaseEdit = QLineEdit(self)
  96. self.WheelBaseEdit.setText(str(self.default_wheel_base))
  97. self.WheelBaseEdit.setGeometry(300, 100, 50, 30)
  98. self.btnModelCheck = QCheckBox("整体协调", self)
  99. self.btnModelCheck.setGeometry(360, 130, 100, 40)
  100. self.btnModelCheck.clicked.connect(self.MainAgvchangecb)
  101. self.btnClampCheck = QCheckBox("夹持", self)
  102. self.btnClampCheck.setGeometry(260, 160, 60, 40)
  103. self.btnClampCheck.clicked.connect(self.ClampClick)
  104. self.btnLifterCheck = QCheckBox("提升", self)
  105. self.btnLifterCheck.setGeometry(360, 160, 60, 40)
  106. self.btnLifterCheck.clicked.connect(self.LifterClick)
  107. self.btnAuto = QCheckBox(self)
  108. self.btnAuto.setText("自动测试")
  109. self.btnAuto.setGeometry(260, 195, 100, 40)
  110. self.btnAuto.stateChanged.connect(self.AutoCheck)
  111. self.btnAutoDirect = QCheckBox(self)
  112. self.btnAutoDirect.setText("自由方向")
  113. self.btnAutoDirect.setGeometry(260, 130, 100, 40)
  114. self.btnAutoDirect.setCheckState(Qt.Checked)
  115. self.btnAutoBegChanged = QCheckBox(self)
  116. self.btnAutoBegChanged.setText("起点自动")
  117. self.btnAutoBegChanged.setGeometry(260, 10, 100, 20)
  118. self.btnAutoBegChanged.setCheckState(Qt.Checked)
  119. self.select_map_Qc = QComboBox(self)
  120. self.select_map_Qc.setGeometry(360, 10, 100, 20)
  121. maps = ["Front", "Back", "Base"]
  122. self.select_map_Qc.addItems(maps)
  123. self.select_map_Qc.activated.connect(self.select_map_QcChanged)
  124. def Update(self):
  125. if self.robot_.timedRobotStatu_.timeout() == False:
  126. x = self.robot_.timedRobotStatu_.statu.x
  127. y = self.robot_.timedRobotStatu_.statu.y
  128. yaw = self.robot_.timedRobotStatu_.statu.theta
  129. self.posestatic.setText("x : %.3f\ny : %.3f\nΘ : %.2f°" % (x, y, yaw * 180 / math.pi))
  130. if self.btnAutoBegChanged.checkState() == Qt.Checked:
  131. [label, pt] = mp.MapManager().findNeastNode("Base", [x, y])
  132. self.begQc.setCurrentText(label)
  133. statu = "min-width: 32px; min-height: 32px;max-width:32px;\
  134. max-height: 32px;border-radius: 16px; border:1px solid black;background:green"
  135. if self.robot_.Connected() == False:
  136. statu = "min-width: 32px; min-height: 32px;max-width:32px;\
  137. max-height: 32px;border-radius: 16px; border:1px solid black;background:gray"
  138. # self.endQc.setEnabled(False)
  139. elif self.robot_.IsNavigating() == True:
  140. statu = "min-width: 32px; min-height: 32px;max-width:32px;\
  141. max-height: 32px;border-radius: 16px; border:1px solid black;background:yellow"
  142. self.endStreetQc.setEnabled(False)
  143. self.endSpaceQc.setEnabled(False)
  144. self.btnModelCheck.setEnabled(False)
  145. self.btnClampCheck.setEnabled(False)
  146. self.btnLifterCheck.setEnabled(False)
  147. else:
  148. self.endStreetQc.setEnabled(True)
  149. self.endSpaceQc.setEnabled(True)
  150. self.btnModelCheck.setEnabled(True)
  151. self.btnClampCheck.setEnabled(True)
  152. self.btnLifterCheck.setEnabled(True)
  153. self.LedLabel.setStyleSheet(statu)
  154. # self.wheelbasestatic.setVisible(self.robot_.IsMainAgv())
  155. # self.WheelBaseEdit.setVisible(self.robot_.IsMainAgv())
  156. self.btnModelCheck.setVisible(self.robot_.IsMainAgv())
  157. if self.robot_.IsMainModeStatu():
  158. self.btnModelCheck.setCheckState(Qt.Checked)
  159. else:
  160. self.btnModelCheck.setCheckState(Qt.Unchecked)
  161. if self.robot_.IsClampClosed():
  162. self.btnClampCheck.setCheckState(Qt.Checked)
  163. else:
  164. self.btnClampCheck.setCheckState(Qt.Unchecked)
  165. if self.robot_.IsLiferRose():
  166. self.btnLifterCheck.setCheckState(Qt.Checked)
  167. else:
  168. self.btnLifterCheck.setCheckState(Qt.Unchecked)
  169. if self.robot_.IsNavigating():
  170. self.begId_ = self.robot_.begId_
  171. self.targetId_ = self.robot_.targetId_
  172. djks_map = mp.MapManager()
  173. beg_node = djks_map.GetVertex("Base", self.begId_)
  174. end_node = djks_map.GetVertex("Base", self.targetId_)
  175. if beg_node is not None:
  176. self.begQc.setCurrentText(self.begId_)
  177. if end_node is not None:
  178. if isinstance(end_node, (mp.SpaceNode)):
  179. self.endStreetQc.setCurrentText("------")
  180. self.endSpaceQc.setCurrentText(self.targetId_)
  181. if isinstance(end_node, (mp.StreetNode)):
  182. self.endStreetQc.setCurrentText(self.targetId_)
  183. self.endSpaceQc.setCurrentText("------")
  184. # if self.robot_.IsMainModeStatu():
  185. # self.btnAutoDirect.setCheckState(Qt.Unchecked)
  186. def AutoCheck(self):
  187. if self.btnAuto.checkState() == Qt.Checked:
  188. self.robot_.autoTest_ = True
  189. else:
  190. self.robot_.autoTest_ = False
  191. def ClampClick(self):
  192. if self.robot_.IsClampClosed() == False:
  193. self.threadPool_.submit(self.robot_.ClampClose)
  194. else:
  195. self.threadPool_.submit(self.robot_.ClampOpen)
  196. def LifterClick(self):
  197. if self.robot_.IsLiferRose() == False:
  198. self.threadPool_.submit(self.robot_.LiferRise)
  199. else:
  200. self.threadPool_.submit(self.robot_.LiferDown)
  201. def MainAgvchangecb(self):
  202. if self.robot_.IsMainModeStatu() == False:
  203. leng = float(self.WheelBaseEdit.text())
  204. self.threadPool_.submit(self.robot_.SwitchMoveMode, 1, leng)
  205. self.robot_.L_ = leng
  206. else:
  207. self.threadPool_.submit(self.robot_.SwitchMoveMode, 0, 0)
  208. def endStreetQCChanged(self):
  209. id1 = self.begQc.currentText()
  210. id2 = self.endStreetQc.currentText()
  211. if not id1 == "------" and not id2 == "------":
  212. self.robot_.GeneratePath(id1, id2, self.select_map)
  213. self.begId_ = id1
  214. self.targetId_ = id2
  215. def endSpaceQCChanged(self):
  216. id1 = self.begQc.currentText()
  217. id2 = self.endSpaceQc.currentText()
  218. if not id1 == "------" and not id2 == "------":
  219. self.robot_.GeneratePath(id1, id2, self.select_map)
  220. self.begId_ = id1
  221. self.targetId_ = id2
  222. def btnSendClick(self):
  223. if self.btnAuto.checkState() == Qt.Checked:
  224. if self.robot_.IsMainModeStatu():
  225. self.threadPool_.submit(self.robot_.AutoTestNavClamp,
  226. self.begId_, self.targetId_)
  227. else:
  228. print("agv not in main statu")
  229. else:
  230. autoDirect = False
  231. if self.btnAutoDirect.checkState() == Qt.Checked:
  232. print("自由方向")
  233. autoDirect = True
  234. self.robot_.GeneratePath(self.begId_, self.targetId_, self.select_map)
  235. self.threadPool_.submit(self.robot_.Navigatting,
  236. self.begId_, self.targetId_, autoDirect, float(self.WheelBaseEdit.text()))
  237. def btnCancelClick(self):
  238. self.controller_status = ControllerStatus.eCancel
  239. self.threadPool_.submit(self.robot_.CancelNavTask)
  240. self.btnAuto.setCheckState(Qt.Unchecked)
  241. def select_map_QcChanged(self):
  242. self.select_map = self.select_map_Qc.currentText()
  243. print("changed selected map to" + self.select_map)
  244. class CountFrame(QFrame):
  245. def __init__(self):
  246. QFrame.__init__(self)
  247. self.default_wheel_base = 2.6
  248. self.InitUI()
  249. self.timer_ = QTimer()
  250. self.timer_.timeout.connect(self.UpdateUI)
  251. self.timer_.start(200)
  252. def InitUI(self):
  253. self.static1 = QLabel(self)
  254. self.static1.setText("重载导航次数 : /")
  255. self.static1.setGeometry(5, 5, 200, 30)
  256. self.static2 = QLabel(self)
  257. self.static2.setText("单车导航次数 : /")
  258. self.static2.setGeometry(5, 40, 200, 30)
  259. self.btnFrontCheck = QCheckBox("前车地图", self)
  260. self.btnFrontCheck.setGeometry(210, 5, 100, 30)
  261. self.btnFrontCheck.clicked.connect(self.FrontChecked)
  262. self.btnBackCheck = QCheckBox("后车地图", self)
  263. self.btnBackCheck.setGeometry(310, 5, 100, 30)
  264. self.btnBackCheck.clicked.connect(self.FrontChecked)
  265. self.btnMainCheck = QCheckBox("整车地图", self)
  266. self.btnMainCheck.setGeometry(210, 40, 100, 30)
  267. self.btnMainCheck.clicked.connect(self.FrontChecked)
  268. self.btnBaseCheck = QCheckBox("原始地图", self)
  269. self.btnBaseCheck.setGeometry(310, 40, 100, 30)
  270. self.btnBaseCheck.clicked.connect(self.FrontChecked)
  271. def FrontChecked(self):
  272. # wheelBase = self.default_wheel_base
  273. maps = []
  274. if self.btnFrontCheck.checkState() == Qt.Checked:
  275. maps.append("Front")
  276. if self.btnBackCheck.checkState() == Qt.Checked:
  277. maps.append("Back")
  278. if self.btnMainCheck.checkState() == Qt.Checked:
  279. maps.append("Main")
  280. if self.btnBaseCheck.checkState() == Qt.Checked:
  281. maps.append("Base")
  282. view = viewer.MapGLWidget()
  283. view.SetEnableMaps(maps)
  284. def UpdateUI(self):
  285. load_str = "重载导航次数 : %d" % (Count.TestCount().loadCount())
  286. single_str = "单车导航次数 : %d" % (Count.TestCount().singleCount())
  287. self.static1.setText(load_str)
  288. self.static2.setText(single_str)