test.py 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # ===============================================================================
  4. #
  5. # test.py
  6. #
  7. # Test program for the simple GL Viewer.
  8. #
  9. # Copyright (c) 2011, Arne Schmitz <arne.schmitz@gmx.net>
  10. # All rights reserved.
  11. #
  12. # Redistribution and use in source and binary forms, with or without
  13. # modification, are permitted provided that the following conditions are met:
  14. # * Redistributions of source code must retain the above copyright
  15. # notice, this list of conditions and the following disclaimer.
  16. # * Redistributions in binary form must reproduce the above copyright
  17. # notice, this list of conditions and the following disclaimer in the
  18. # documentation and/or other materials provided with the distribution.
  19. # * Neither the name of the <organization> nor the
  20. # names of its contributors may be used to endorse or promote products
  21. # derived from this software without specific prior written permission.
  22. #
  23. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  24. # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  25. # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  26. # DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  27. # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  28. # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  29. # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  30. # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  31. # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  32. # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33. #
  34. # ===============================================================================
  35. import math
  36. import threading
  37. import time
  38. import sys
  39. from PyQt5.QtGui import *
  40. from PyQt5.QtWidgets import *
  41. from PyQt5.QtCore import *
  42. from MapGLWidget import MapGLWidget
  43. import json
  44. import dijkstra.Map as mp
  45. import ControllWidget
  46. import JointContrallerWidget
  47. import ManualOperationWidget
  48. import RobotData as RD
  49. import message_pb2 as message
  50. import google.protobuf.json_format as jtf
  51. import google.protobuf.text_format as tf
  52. from concurrent.futures import ThreadPoolExecutor
  53. import uuid
  54. from mytool.txt_helper.txt_operation import TXTOperation
  55. from custom_define import RobotName
  56. from mytool.RabbitMq_helper import async_communication as rabitmq
  57. import concurrent.futures
  58. # ===============================================================================
  59. class MainWindow(QMainWindow):
  60. """docstring for Mainwindow"""
  61. mapManager = mp.MapManager()
  62. ui_nodes = {}
  63. ui_nodes["street_nodes"] = []
  64. ui_nodes["space_nodes"] = []
  65. def __init__(self, parent=None):
  66. super(MainWindow, self).__init__(parent)
  67. self.basic()
  68. self.count_frame_ = ControllWidget.CountFrame()
  69. self.loadJsonMap("./map.json")
  70. self.isLocalTest = False
  71. self.isAutoDispatchOnline = True
  72. rpc_1 = "192.168.0.70:9090"
  73. mqtt_1 = ["pyui1", "192.168.0.70", 1883, "admin", "zx123456"]
  74. rpc_2 = "192.168.0.71:9090"
  75. mqtt_2 = ["pyui2", "192.168.0.71", 1883, "admin", "zx123456"]
  76. if self.isLocalTest:
  77. rpc_1 = "127.0.0.1:9090"
  78. mqtt_1 = ["pyui-main", "127.0.0.1", 1883, "admin", "zx123456"]
  79. rpc_2 = "127.0.0.1:9091"
  80. mqtt_2 = ["pyui-child", "127.0.0.1", 1883, "admin", "zx123456"]
  81. config1 = {"label": RobotName.strAGVMain,
  82. "rpc": rpc_1,
  83. "street_nodes": self.ui_nodes["street_nodes"],
  84. "space_nodes": self.ui_nodes["space_nodes"],
  85. "mqtt": mqtt_1,
  86. "subTopics": {"agv_main/agv_statu": message.RobotStatu.__name__,
  87. "agv_main/nav_statu": message.NavStatu.__name__},
  88. "cmdTopic": "agv_main/nav_cmd",
  89. "robotColor": [0.7, 0.2, 0.3]}
  90. config2 = {"label": RobotName.strAGV2,
  91. "rpc": rpc_2,
  92. # "rpc": "127.0.0.1:9091",
  93. "street_nodes": self.ui_nodes["street_nodes"],
  94. "space_nodes": self.ui_nodes["space_nodes"],
  95. "mqtt": mqtt_2,
  96. "subTopics": {"agv_child/agv_statu": message.RobotStatu.__name__,
  97. "agv_child/nav_statu": message.NavStatu.__name__},
  98. "cmdTopic": "agv_child/nav_cmd",
  99. "robotColor": [0.4, 0.2, 0.8]}
  100. self.Controller1 = ControllWidget.ControlFrame(config1)
  101. self.Controller2 = ControllWidget.ControlFrame(config2)
  102. robot_dict = {self.Controller1.robot_.name_: self.Controller1.robot_,
  103. self.Controller2.robot_.name_: self.Controller2.robot_}
  104. self.ManualOperationWidget = ManualOperationWidget.ManualOperationWidget(robot_dict)
  105. splitter_main = self.split_()
  106. self.setCentralWidget(splitter_main)
  107. self.gl.SetRobot1Instance(self.Controller1.robot_)
  108. self.gl.SetRobot2Instance(self.Controller2.robot_)
  109. self.timer_ = QTimer()
  110. self.timer_.timeout.connect(self.Update)
  111. self.timer_.start(100)
  112. # 启动RabbitMQ
  113. self.g_rabbitmq = None
  114. if self.isAutoDispatchOnline:
  115. self.g_rabbitmq = rabitmq.RabbitAsyncCommunicator("192.168.0.201", 5672, "zx", "123456")
  116. calbbacks = [["agv_park_command_request_queue", self.recv_park_request],
  117. ["agv_pick_command_request_queue", self.recv_pick_request]]
  118. self.g_rabbitmq.Init(calbbacks, None)
  119. self.g_rabbitmq.setDaemon(True) # 守护线程随主线程结束
  120. self.g_rabbitmq.start()
  121. def recv_park_request(self, msg):
  122. print("Recv_park_request------------------\n", msg)
  123. park_table = message.park_table()
  124. try:
  125. tf.Parse(msg, park_table)
  126. except Exception as e:
  127. print("Parse error\n")
  128. if self.isAutoDispatchOnline:
  129. self.AutoParkTask(park_table)
  130. def recv_pick_request(self, msg):
  131. print("Recv_pick_request------------------\n", msg)
  132. pick_table = message.pick_table()
  133. try:
  134. tf.Parse(msg, pick_table)
  135. except Exception as e:
  136. print("Parse error\n")
  137. if self.isAutoDispatchOnline:
  138. self.AutoPickTask(pick_table)
  139. def ReLoadMap(self, mapName, file):
  140. self.mapManager.Reset(mapName)
  141. map = self.readJson(file)
  142. flag = "C_"
  143. if mapName == "Front":
  144. flag = "F_"
  145. elif mapName == "Back":
  146. flag = "B_"
  147. elif mapName == "Main":
  148. flag = "C_"
  149. else:
  150. print(" map name is error:%s" % (mapName))
  151. return
  152. for node in map['street_nodes'].items():
  153. [id, point] = node
  154. street_node = mp.StreetNode(id, point[0], point[1])
  155. if street_node.id_.find(flag) >= 0:
  156. if street_node.id_.find("OutLink") >= 0:
  157. continue
  158. self.mapManager.AddVertex(mapName, street_node)
  159. for node in map['space_nodes'].items():
  160. [id, point] = node
  161. [x, y, yaw] = point
  162. space_node = mp.SpaceNode(id, point[0], point[1], yaw)
  163. self.mapManager.AddVertex(mapName, space_node)
  164. for road in map['roads'].items():
  165. [roadName, points] = road
  166. for pt1 in points:
  167. for pt2 in points:
  168. if not pt1 == pt2:
  169. if pt1.find("OutLink") >= 0 or pt2.find("OutLink") >= 0:
  170. continue
  171. if roadName.find(flag) >= 0:
  172. self.mapManager.AddEdge(mapName, pt1, pt2)
  173. def loadJsonMap(self, file):
  174. self.gl = MapGLWidget() # 将opengl例子嵌入GUI
  175. map = self.readJson(file)
  176. for node in map['street_nodes'].items():
  177. [id, point] = node
  178. street_node = mp.StreetNode(id, point[0], point[1])
  179. self.mapManager.AddVertex("Base", street_node)
  180. if street_node.id_.find("F_") >= 0:
  181. self.mapManager.AddVertex("Front", street_node)
  182. if street_node.id_.find("B_") >= 0:
  183. self.mapManager.AddVertex("Back", street_node)
  184. if street_node.id_.find("C_") >= 0:
  185. self.mapManager.AddVertex("Main", street_node)
  186. self.ui_nodes["street_nodes"].append(id)
  187. for node in map['space_nodes'].items():
  188. [id, point] = node
  189. [x, y, yaw] = point
  190. space_node = mp.SpaceNode(id, point[0], point[1], yaw)
  191. self.mapManager.AddVertex("Base", space_node)
  192. self.mapManager.AddVertex("Front", space_node)
  193. self.mapManager.AddVertex("Back", space_node)
  194. self.mapManager.AddVertex("Main", space_node)
  195. self.ui_nodes["space_nodes"].append(id)
  196. for road in map['roads'].items():
  197. [roadName, points] = road
  198. for pt1 in points:
  199. for pt2 in points:
  200. if not pt1 == pt2:
  201. self.mapManager.AddEdge("Base", pt1, pt2)
  202. if pt1.find("OutLink") >= 0 or pt2.find("OutLink") >= 0:
  203. continue
  204. if roadName.find("F_") >= 0:
  205. self.mapManager.AddEdge("Front", pt1, pt2)
  206. if roadName.find("B_") >= 0:
  207. self.mapManager.AddEdge("Back", pt1, pt2)
  208. if roadName.find("C_") >= 0:
  209. self.mapManager.AddEdge("Main", pt1, pt2)
  210. self.gl.SetMaps(self.mapManager.maps)
  211. def updateMap_park(self, entrance_id, pose, mapName): # 0:前车轨迹,1:后车轨迹,2:添加整车轨迹
  212. self.ReLoadMap(mapName, "./map.json")
  213. trans_x, trans_y, trans_a = pose
  214. # 加车位点
  215. self.mapManager.maps[mapName].AddVertex(mp.SpaceNode("S1101", trans_x, trans_y, trans_a))
  216. entrance_street_nodes = self.ComputeStreetNode(entrance_id, trans_x, trans_y, trans_a)
  217. print("entrance_space pose: ", self.mapManager.maps[mapName].graph_.points[entrance_id])
  218. street_name = "F_InputLink"
  219. if mapName == "Front":
  220. street_name = "F_InputLink"
  221. self.mapManager.maps[mapName].AddVertex(mp.StreetNode(street_name, entrance_street_nodes[0][0],
  222. entrance_street_nodes[0][1])) # 更新库位点对应马路点
  223. if mapName == "Main":
  224. street_name = "C_InputLink"
  225. self.mapManager.maps[mapName].AddVertex(mp.StreetNode(street_name, entrance_street_nodes[1][0],
  226. entrance_street_nodes[1][1])) # 更新库位点对应马路点
  227. if mapName == "Back":
  228. street_name = "B_InputLink"
  229. self.mapManager.maps[mapName].AddVertex(mp.StreetNode(street_name, entrance_street_nodes[2][0],
  230. entrance_street_nodes[2][1])) # 更新库位点对应马路点
  231. # 加临时边
  232. for node_id, value in self.mapManager.VertexDict(mapName).items():
  233. if node_id.find("Input") >= 0:
  234. self.mapManager.maps[mapName].AddEdge(street_name, node_id)
  235. self.mapManager.AddVertex(mapName, mp.SpaceNode(entrance_id, trans_x, trans_y, trans_a)) # 更新库位点
  236. self.mapManager.maps[mapName].AddEdge(entrance_id, street_name)
  237. print(mapName + " Map entrance_street pose ", self.mapManager.maps[mapName].graph_.points[street_name])
  238. self.gl.SetMap(mapName, self.mapManager.maps[mapName])
  239. def asyncExecute(self, tasks):
  240. results = [feature.result() for feature in concurrent.futures.as_completed(tasks)]
  241. print("==========================\n")
  242. print(results)
  243. print("==========================\n")
  244. ret = True
  245. for result in results:
  246. ret = ret and result
  247. return ret
  248. def GetMainFrontBackAGV(self):
  249. controlMain = self.Controller1
  250. nagtive = False
  251. if controlMain.robot_.timedRobotStatu_.statu.theta < 0:
  252. nagtive = True
  253. control1 = None
  254. control2 = None
  255. if nagtive == False:
  256. control1 = self.Controller1
  257. control2 = self.Controller2
  258. else:
  259. control2 = self.Controller1
  260. control1 = self.Controller2
  261. return [controlMain, control1, control2]
  262. def AutoParkTask(self, park_table: message.park_table = None):
  263. print("AutoParkTask:---------------------\n")
  264. [controlMain, control1, control2] = self.GetMainFrontBackAGV()
  265. mainMap, frontMap, backMap = ["Main", "Front", "Back"]
  266. entrance_id = "S" + str(park_table.terminal_id) # "S1101"
  267. entrance_x, entrance_y, entrance_theta = [park_table.entrance_measure_info.measure_info_to_plc_forward.cx,
  268. park_table.entrance_measure_info.measure_info_to_plc_forward.cy,
  269. (
  270. 90 + park_table.entrance_measure_info.measure_info_to_plc_forward.theta) / 180 * math.pi]
  271. # 变换到地图坐标系
  272. # [dx, dy, da] = [-0.223411843181, -0.643030941486, 178.9478 / 180 * math.pi]
  273. # trans_x = -0.99983137 * entrance_x - 0.01836309 * entrance_y + dx
  274. # trans_y = 0.01836309 * entrance_x - 0.99983137 * entrance_y + dy
  275. [dx, dy, da] = [-0.234040126204, -0.647539079189, 178.9302736990612 / 180 * math.pi]
  276. trans_x = -0.999825716019 * entrance_x - 0.018668506294 * entrance_y + dx
  277. trans_y = 0.018668506294 * entrance_x - 0.999825716019 * entrance_y + dy
  278. trans_a = entrance_theta + da - math.pi
  279. while trans_a < 0:
  280. trans_a += math.pi
  281. print("entrance:", entrance_id, trans_x, trans_y, trans_a / math.pi * 180)
  282. target_id = "S" + str(park_table.allocated_space_info.table_id) # "S147"
  283. print("target:", target_id)
  284. # 轴距
  285. wheel_base = park_table.entrance_measure_info.measure_info_to_plc_forward.wheelbase
  286. control1.WheelBaseEdit.setText(str(wheel_base))
  287. control2.WheelBaseEdit.setText(str(wheel_base))
  288. trans_x += wheel_base / 2 * math.cos(trans_a)
  289. trans_y += wheel_base / 2 * math.sin(trans_a)
  290. threadPool = ThreadPoolExecutor(2)
  291. features = [threadPool.submit(control1.robot_.SwitchMoveMode, 0, wheel_base),
  292. threadPool.submit(control2.robot_.SwitchMoveMode, 0, wheel_base)]
  293. if self.asyncExecute(features) == False:
  294. print(" Park Failed ")
  295. return False
  296. # # 双单车入库-----------------------------------------------------
  297. self.ReLoadMap(frontMap, "./map.json")
  298. self.updateMap_park(entrance_id, [trans_x, trans_y, trans_a], frontMap)
  299. cur_pose1 = control1.robot_.timedRobotStatu_.statu
  300. [label, pt] = self.mapManager.findNeastNode(frontMap, [cur_pose1.x, cur_pose1.y])
  301. control1.robot_.GeneratePath(label, entrance_id, frontMap)
  302. print("Main: begin:%s target:%s wheelBase:%f" % (label, entrance_id, wheel_base))
  303. # 后车 ------------------------------------------------------
  304. self.ReLoadMap(backMap, "./map.json")
  305. self.updateMap_park(entrance_id, [trans_x, trans_y, trans_a], backMap)
  306. cur_pose2 = control2.robot_.timedRobotStatu_.statu
  307. [label, pt] = self.mapManager.findNeastNode(backMap, [cur_pose2.x, cur_pose2.y])
  308. control2.robot_.GeneratePath(label, entrance_id, backMap)
  309. print("Child: begin:%s target:%s wheelBase:%f" % (label, entrance_id, wheel_base))
  310. autoDirect = True
  311. threadPool = ThreadPoolExecutor(2)
  312. features = [threadPool.submit(control1.robot_.Navigatting, label, entrance_id, autoDirect, wheel_base),
  313. threadPool.submit(control2.robot_.Navigatting, label, entrance_id, autoDirect, wheel_base)]
  314. if self.asyncExecute(features) == False:
  315. print(" Park Failed ")
  316. return False
  317. print(" input entrance completed!!!!")
  318. controlMain.robot_.SwitchMoveMode(1, wheel_base)
  319. controlMain.robot_.ClampClose()
  320. # 整车入库---------------------------------
  321. map_name = "Front"
  322. if controlMain.robot_.timedRobotStatu_.statu.theta < 0:
  323. map_name = "Back"
  324. self.ReLoadMap(map_name, "./map.json")
  325. self.updateMap_park(entrance_id, [trans_x, trans_y, trans_a], map_name)
  326. controlMain.robot_.GeneratePath(entrance_id, target_id, map_name)
  327. print("begin:%s target:%s wheelBase:%f" % (entrance_id, target_id, wheel_base))
  328. controlMain.robot_.Navigatting(entrance_id, target_id, autoDirect, wheel_base)
  329. print("-------------------------")
  330. # 整车松夹池------------------------------------
  331. threadPool = ThreadPoolExecutor(1)
  332. threadPool.submit(controlMain.robot_.ClampOpen)
  333. threadPool.shutdown(wait=True)
  334. threadPool = ThreadPoolExecutor(1)
  335. threadPool.submit(controlMain.robot_.SwitchMoveMode, 0, wheel_base)
  336. threadPool.shutdown(wait=True)
  337. # 双单车出库
  338. self.ReLoadMap(frontMap, "./map.json")
  339. controlMain, control1, control2 = self.GetMainFrontBackAGV()
  340. control1.robot_.GeneratePath(target_id, "F_Input_R147", frontMap)
  341. self.ReLoadMap(backMap, "./map.json")
  342. control2.robot_.GeneratePath(target_id, "B_Input_R147", backMap)
  343. threadPool = ThreadPoolExecutor(2)
  344. threadPool.submit(control1.robot_.Navigatting,
  345. target_id, "F_Input_R147", autoDirect, wheel_base)
  346. threadPool.submit(control2.robot_.Navigatting,
  347. target_id, "B_Input_R147", autoDirect, wheel_base)
  348. threadPool.shutdown(wait=True)
  349. # 反馈
  350. self.g_rabbitmq.publish("command_ex", "agv_park_command_response_port",
  351. tf.MessageToString(park_table, as_utf8=True))
  352. print("Publish_park_response------------------\n", park_table)
  353. return True
  354. def updateMap_pick(self, export_id, mapName): # 0:前车轨迹,1:后车轨迹,2:添加整车轨迹
  355. self.ReLoadMap(mapName, "./map.json")
  356. # export_id = "S1101"
  357. # 添加出口车位点
  358. export_x = self.mapManager.maps["Base"].graph_.points["S1100"][0]
  359. export_y = self.mapManager.maps["Base"].graph_.points["S1100"][1]
  360. self.mapManager.AddVertex(mapName, mp.SpaceNode(export_id, export_x, export_y, 90))
  361. # 更新库位点对应马路点
  362. flag = "F_"
  363. if mapName == "Front":
  364. export_y = self.mapManager.maps["Base"].graph_.points["F_OutLink"][1]
  365. node = mp.StreetNode("F_exportLink", export_x, export_y)
  366. elif mapName == "Back":
  367. flag = "B_"
  368. export_y = self.mapManager.maps["Base"].graph_.points["B_OutLink"][1]
  369. node = mp.StreetNode("B_exportLink", export_x, export_y)
  370. elif mapName == "Main":
  371. flag = "C_"
  372. export_y = self.mapManager.maps["Base"].graph_.points["C_OutLink"][1]
  373. node = mp.StreetNode("C_exportLink", export_x, export_y)
  374. self.mapManager.AddVertex(mapName, node) # 更新库位点对应马路点
  375. self.mapManager.AddEdge(mapName, export_id, node.id_)
  376. for streetID, value in self.mapManager.VertexDict(mapName).items():
  377. if streetID.find(flag) >= 0:
  378. self.mapManager.AddEdge(mapName, node.id_, streetID)
  379. print("Add edge :%s-%s ", node.id_, streetID)
  380. def AutoPickTask(self, pick_table: message.pick_table = None):
  381. print("AutoPickTask:---------------------\n")
  382. controlMain, control1, control2 = self.GetMainFrontBackAGV()
  383. mainMap, frontMap, backMap = ["Main", "Front", "Back"]
  384. space_id = "S" + str(pick_table.actually_space_info.table_id) # "S147"
  385. export_id = "S" + str(pick_table.terminal_id) # "S1101"
  386. print(space_id, export_id)
  387. # 轴距
  388. wheel_base = pick_table.actually_measure_info.measure_info_to_plc_forward.wheelbase
  389. control1.WheelBaseEdit.setText(str(wheel_base))
  390. control2.WheelBaseEdit.setText(str(wheel_base))
  391. # 双单车入库
  392. threadPool = ThreadPoolExecutor(2)
  393. threadPool.submit(control1.robot_.SwitchMoveMode, 0, wheel_base)
  394. threadPool.submit(control2.robot_.SwitchMoveMode, 0, wheel_base)
  395. threadPool.shutdown(wait=True)
  396. self.ReLoadMap(frontMap, "./map.json")
  397. self.updateMap_pick(export_id, frontMap)
  398. cur_pose1 = control1.robot_.timedRobotStatu_.statu
  399. [label, pt] = self.mapManager.findNeastNode(frontMap, [cur_pose1.x, cur_pose1.y])
  400. control1.robot_.GeneratePath(label, space_id, frontMap)
  401. print("Main: begin:%s target:%s wheelBase:%f" % (label, space_id, wheel_base))
  402. self.ReLoadMap(backMap, "./map.json")
  403. self.updateMap_pick(export_id, backMap)
  404. cur_pose2 = control2.robot_.timedRobotStatu_.statu
  405. [label, pt] = self.mapManager.findNeastNode(backMap, [cur_pose2.x, cur_pose2.y])
  406. control2.robot_.GeneratePath(label, space_id, backMap)
  407. print("Child: begin:%s target:%s wheelBase:%f" % (label, space_id, wheel_base))
  408. autoDirect = True
  409. threadPool = ThreadPoolExecutor(2)
  410. threadPool.submit(control1.robot_.Navigatting,
  411. label, space_id, autoDirect, wheel_base)
  412. threadPool.submit(control2.robot_.Navigatting,
  413. label, space_id, autoDirect, wheel_base)
  414. threadPool.shutdown(wait=True)
  415. # 整车夹持------------------------------------
  416. print(" input space completed!!!!")
  417. threadPool = ThreadPoolExecutor(1)
  418. threadPool.submit(controlMain.robot_.SwitchMoveMode, 1, wheel_base)
  419. threadPool.shutdown(wait=True)
  420. threadPool = ThreadPoolExecutor(1)
  421. threadPool.submit(controlMain.robot_.ClampClose)
  422. threadPool.shutdown(wait=True)
  423. # 整车到出口---------------------------------
  424. map_name = "Front"
  425. if controlMain.robot_.timedRobotStatu_.statu.theta < 0:
  426. map_name = "Back"
  427. self.ReLoadMap(map_name, "./map.json")
  428. self.updateMap_pick(export_id, map_name)
  429. controlMain.robot_.GeneratePath(space_id, export_id, map_name)
  430. print("Total: begin:%s target:%s wheelBase:%f" % (space_id, export_id, wheel_base))
  431. threadPool = ThreadPoolExecutor(1)
  432. threadPool.submit(controlMain.robot_.Navigatting,
  433. space_id, export_id, True, wheel_base)
  434. threadPool.shutdown(wait=True)
  435. # 整车松夹池------------------------------------
  436. threadPool = ThreadPoolExecutor(1)
  437. threadPool.submit(controlMain.robot_.ClampOpen)
  438. threadPool.shutdown(wait=True)
  439. threadPool = ThreadPoolExecutor(1)
  440. threadPool.submit(controlMain.robot_.SwitchMoveMode, 0, wheel_base)
  441. threadPool.shutdown(wait=True)
  442. # 双单车出库
  443. controlMain, control1, control2 = self.GetMainFrontBackAGV()
  444. self.ReLoadMap(frontMap, "./map.json")
  445. self.updateMap_pick(export_id, frontMap)
  446. control1.robot_.GeneratePath(export_id, "F_exportLink", frontMap)
  447. self.ReLoadMap(backMap, "./map.json")
  448. self.updateMap_pick(export_id, backMap)
  449. control2.robot_.GeneratePath(export_id, "B_exportLink", backMap)
  450. threadPool = ThreadPoolExecutor(2)
  451. threadPool.submit(control1.robot_.Navigatting,
  452. export_id, "F_exportLink", True, wheel_base)
  453. threadPool.submit(control2.robot_.Navigatting,
  454. export_id, "B_exportLink", True, wheel_base)
  455. threadPool.shutdown(wait=True)
  456. # 反馈
  457. self.g_rabbitmq.publish("command_ex", "agv_pick_command_response_port",
  458. tf.MessageToString(pick_table, as_utf8=True))
  459. print("Publish_park_response------------------\n", pick_table)
  460. return True
  461. def ComputeStreetNode(self, s_id, s_x, s_y, s_theta):
  462. """
  463. """
  464. n_x, n_y = 0, 0
  465. if s_id == "S1101":
  466. n_y = self.mapManager.maps["Base"].graph_.points["C_OutLink"][1]
  467. k = math.tan(s_theta)
  468. n_x = (n_y - s_y) / k + s_x # 弧度
  469. n_yF = self.mapManager.maps["Base"].graph_.points["F_OutLink"][1]
  470. n_xF = (n_yF - s_y) / k + s_x # 弧度
  471. n_yB = self.mapManager.maps["Base"].graph_.points["B_OutLink"][1]
  472. n_xB = (n_yB - s_y) / k + s_x # 弧度
  473. # print(n_x, n_y)
  474. return [[n_xF, n_yF], [n_x, n_y], [n_xB, n_yB]]
  475. def readJson(self, file):
  476. with open(file, 'r', encoding='utf-8') as fp:
  477. map = json.load(fp)
  478. return map
  479. def Update(self):
  480. self.gl.update()
  481. if self.isAutoDispatchOnline:
  482. # self.Controller1.setEnabled(False)
  483. # self.Controller2.setEnabled(False)
  484. pass
  485. else:
  486. self.Controller1.setVisible(True)
  487. self.Controller2.setVisible(True)
  488. # 窗口基础属性
  489. def basic(self):
  490. # 设置标题,大小,图标
  491. self.setWindowTitle("GT")
  492. self.resize(1100, 650)
  493. self.setWindowIcon(QIcon("./image/Gt.png"))
  494. # 居中显示
  495. screen = QDesktopWidget().geometry()
  496. self_size = self.geometry()
  497. self.move(int((screen.width() - self_size.width()) / 2), int((screen.height() - self_size.height()) / 2))
  498. def closeEvent(self, QCloseEvent):
  499. self.gl.close()
  500. print("close...")
  501. # 分割窗口
  502. def split_(self):
  503. splitter_main = QSplitter(Qt.Horizontal)
  504. splitter = QSplitter(Qt.Vertical)
  505. splitter.addWidget(self.count_frame_)
  506. splitter.addWidget(self.Controller1)
  507. splitter.addWidget(self.Controller2)
  508. splitter.addWidget(self.ManualOperationWidget)
  509. splitter.setStretchFactor(0, 1)
  510. splitter.setStretchFactor(1, 3)
  511. splitter.setStretchFactor(2, 3)
  512. splitter.setStretchFactor(3, 1)
  513. splitter_main.addWidget(splitter)
  514. splitter_main.addWidget(self.gl)
  515. splitter_main.setStretchFactor(0, 1)
  516. splitter_main.setStretchFactor(2, 4)
  517. return splitter_main
  518. if __name__ == "__main__":
  519. app = QApplication(sys.argv)
  520. win = MainWindow()
  521. win.show()
  522. sys.exit(app.exec_())
  523. # ===============================================================================
  524. #
  525. # Local Variables:
  526. # mode: Python
  527. # indent-tabs-mode: nil
  528. # End:
  529. #
  530. # ===============================================================================