test.py 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  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 time
  37. import sys
  38. from PyQt5 import QtWidgets, QtGui
  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 RobotData as RD
  47. import message_pb2 as message
  48. import google.protobuf.json_format as jtf
  49. import uuid
  50. # ===============================================================================
  51. class MainWindow(QMainWindow):
  52. """docstring for Mainwindow"""
  53. djks_map_ = mp.DijikstraMap()
  54. ui_nodes = []
  55. def __init__(self, parent=None):
  56. super(MainWindow, self).__init__(parent)
  57. self.basic()
  58. self.LoadMap()
  59. self.Controller1 = ControllWidget.ControlFrame(["AGV1", self.ui_nodes])
  60. self.Controller2 = ControllWidget.ControlFrame(["AGV2", self.ui_nodes])
  61. splitter_main = self.split_()
  62. self.setCentralWidget(splitter_main)
  63. self.Controller1.robot_.connect("pyUI_r1", "127.0.0.1", 1883, "admin", "zx123456")
  64. dataTopics = {"agv1_child/agv_statu": message.AGVStatu.__name__,
  65. "agv1_child/nav_statu": message.NavStatu.__name__}
  66. self.Controller1.robot_.SetSubDataTopic(dataTopics, self.messageArrived)
  67. self.Controller1.robot_.SetCmdTopic("agv1_child/nav_cmd")
  68. self.Controller1.robot_.loop_start()
  69. self.Controller1.robot_.SetColor([0.7, 0.2, 0.3], [0.7, 0.2, 0.3])
  70. self.gl.SetRobot1Instance(self.Controller1.robot_)
  71. self.Controller2.robot_.connect("pyUI_r2", "127.0.0.1", 1883, "admin", "zx123456")
  72. dataTopics = {"agv1/agv_statu": message.AGVStatu.__name__,
  73. "agv1/nav_statu": message.NavStatu.__name__}
  74. self.Controller2.robot_.SetSubDataTopic(dataTopics, self.messageArrived)
  75. self.Controller2.robot_.SetCmdTopic("agv1/nav_cmd")
  76. self.Controller2.robot_.loop_start()
  77. self.Controller2.robot_.SetColor([0.4, 0.2, 0.8], [0.4, 0.2, 0.8])
  78. self.gl.SetRobot2Instance(self.Controller2.robot_)
  79. def LoadMap(self):
  80. self.gl = MapGLWidget() # 将opengl例子嵌入GUI
  81. map = self.load_map("./map.json")
  82. for node in map['street_nodes'].items():
  83. [id, point] = node
  84. street_node = mp.StreetNode(id, point[0], point[1])
  85. self.djks_map_.AddVertex(street_node)
  86. self.gl.AddNode([id, "street_node", point])
  87. self.ui_nodes.append(id)
  88. for node in map['space_nodes'].items():
  89. [id, point] = node
  90. [x, y, connectId] = point
  91. space_node = mp.SpaceNode(id, point[0], point[1], connectId)
  92. self.djks_map_.AddVertex(space_node)
  93. self.djks_map_.AddEdge(id, connectId)
  94. glNode = [id, "space_node", [x, y]]
  95. self.gl.AddNode(glNode)
  96. self.gl.AddRoad(["conn%s-%s" % (id, connectId), [id, connectId]])
  97. self.ui_nodes.append(id)
  98. for road in map['roads'].items():
  99. self.gl.AddRoad(road)
  100. [_, points] = road
  101. for pt1 in points:
  102. for pt2 in points:
  103. if not pt1 == pt2:
  104. self.djks_map_.AddEdge(pt1, pt2)
  105. def load_map(self, file):
  106. with open(file, 'r', encoding='utf-8') as fp:
  107. map = json.load(fp)
  108. return map
  109. def messageArrived(self):
  110. self.gl.update()
  111. # 窗口基础属性
  112. def basic(self):
  113. # 设置标题,大小,图标
  114. self.setWindowTitle("GT")
  115. self.resize(1100, 650)
  116. self.setWindowIcon(QIcon("./image/Gt.png"))
  117. # 居中显示
  118. screen = QDesktopWidget().geometry()
  119. self_size = self.geometry()
  120. self.move(int((screen.width() - self_size.width()) / 2), int((screen.height() - self_size.height()) / 2))
  121. def closeEvent(self, QCloseEvent):
  122. self.gl.close()
  123. # 基于布局的显示窗口
  124. def split_(self):
  125. total_layout = QtWidgets.QGridLayout()
  126. # 地图显示布局
  127. display_layout = QtWidgets.QGridLayout()
  128. display_layout.setObjectName("display_layout")
  129. display_layout.addWidget(self.gl)
  130. total_layout.addLayout(display_layout, 0, 1, 1, 1)
  131. # 操作控制布局
  132. control_layout = QtWidgets.QGridLayout()
  133. control_layout.setObjectName("control_layout")
  134. control_layout.addWidget(self.Controller1)
  135. control_layout.addWidget(self.Controller2)
  136. total_layout.addLayout(control_layout, 0, 0, 1, 1)
  137. # 总布局设置
  138. total_layout.setColumnStretch(0, 2)
  139. total_layout.setColumnStretch(1, 5)
  140. total_layout.setRowStretch(0, 1)
  141. # 将总布局加载到主窗口
  142. centerWidget = QtWidgets.QWidget()
  143. # font = QtGui.QFont()
  144. # font.setFamily("楷体")
  145. # font.setPointSize(15)
  146. # centerWidget.setFont(font)
  147. centerWidget.setLayout(total_layout)
  148. return centerWidget
  149. if __name__ == "__main__":
  150. app = QApplication(sys.argv)
  151. win = MainWindow()
  152. win.showMaximized()
  153. sys.exit(app.exec_())
  154. # ===============================================================================
  155. # Main
  156. # ===============================================================================
  157. '''app = QApplication(sys.argv)
  158. mainWindow = MapGLWidget()
  159. mainWindow.show()
  160. mainWindow.raise_() # Need this at least on OS X, otherwise the window ends up in background
  161. sys.exit(app.exec_())'''
  162. # ===============================================================================
  163. #
  164. # Local Variables:
  165. # mode: Python
  166. # indent-tabs-mode: nil
  167. # Park_End:
  168. #
  169. # ===============================================================================