#!/usr/bin/env python # -*- coding: utf-8 -*- # =============================================================================== # # test.py # # Test program for the simple GL Viewer. # # Copyright (c) 2011, Arne Schmitz # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # =============================================================================== import asyncio import math import threading import time import sys from PyQt5.QtGui import * from PyQt5.QtWidgets import * from PyQt5.QtCore import * from MapGLWidget import MapGLWidget import json import dijkstra.Map as mp import ControllWidget import JointContrallerWidget import ManualOperationWidget import RobotData as RD import message_pb2 as message import google.protobuf.json_format as jtf import google.protobuf.text_format as tf from concurrent.futures import ThreadPoolExecutor import uuid from mytool.txt_helper.txt_operation import TXTOperation from custom_define import RobotName from mytool.RabbitMq_helper import async_communication as rabitmq import concurrent.futures import TaskTable from queue import Queue # =============================================================================== class MainWindow(QMainWindow): """docstring for Mainwindow""" mapManager = mp.MapManager() ui_nodes = {} ui_nodes["street_nodes"] = [] ui_nodes["space_nodes"] = [] taskTable = TaskTable.TaskTable() def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.basic() self.showMaximized() self.count_frame_ = ControllWidget.CountFrame() self.isLocalTest = False self.isAutoDispatchOnline = True self.Cancel_ = False task_thread = threading.Thread(target=self.execTask) task_thread.start() self.mapManager.LoadJson("./map.json") for node_id in self.mapManager.VertexDict("Base"): if node_id.find("S_") >= 0: self.ui_nodes["space_nodes"].append(node_id) if node_id.find("R_") >= 0: self.ui_nodes["street_nodes"].append(node_id) rpc_1 = "192.168.0.70:9090" mqtt_1 = ["pyui1", "192.168.0.70", 1883, "admin", "zx123456"] rpc_2 = "192.168.0.71:9090" mqtt_2 = ["pyui2", "192.168.0.71", 1883, "admin", "zx123456"] if self.isLocalTest: rpc_1 = "127.0.0.1:9090" mqtt_1 = ["pyui-main", "127.0.0.1", 1883, "admin", "zx123456"] rpc_2 = "127.0.0.1:9091" mqtt_2 = ["pyui-child", "127.0.0.1", 1883, "admin", "zx123456"] config1 = {"label": RobotName.strAGVMain, "rpc": rpc_1, "street_nodes": self.ui_nodes["street_nodes"], "space_nodes": self.ui_nodes["space_nodes"], "mqtt": mqtt_1, "subTopics": {"agv_main/agv_statu": message.RobotStatu.__name__, "agv_main/nav_statu": message.NavStatu.__name__}, "cmdTopic": "agv_main/nav_cmd", "robotColor": [0.7, 0.2, 0.3]} config2 = {"label": RobotName.strAGV2, "rpc": rpc_2, # "rpc": "127.0.0.1:9091", "street_nodes": self.ui_nodes["street_nodes"], "space_nodes": self.ui_nodes["space_nodes"], "mqtt": mqtt_2, "subTopics": {"agv_child/agv_statu": message.RobotStatu.__name__, "agv_child/nav_statu": message.NavStatu.__name__}, "cmdTopic": "agv_child/nav_cmd", "robotColor": [0.4, 0.2, 0.8]} self.gl = MapGLWidget() # 将opengl例子嵌入GUI self.Controller1 = ControllWidget.ControlFrame(config1) self.Controller2 = ControllWidget.ControlFrame(config2) robot_dict = {self.Controller1.robot_.name_: self.Controller1.robot_, self.Controller2.robot_.name_: self.Controller2.robot_} self.ManualOperationWidget = ManualOperationWidget.ManualOperationWidget(robot_dict) splitter_main = self.split_() self.setCentralWidget(splitter_main) self.gl.SetRobot1Instance(self.Controller1.robot_) self.gl.SetRobot2Instance(self.Controller2.robot_) self.gl.SetMaps(self.mapManager.maps) self.timer_ = QTimer() self.timer_.timeout.connect(self.Update) self.timer_.start(100) # 启动RabbitMQ self.g_rabbitmq = None if self.isAutoDispatchOnline: self.g_rabbitmq = rabitmq.RabbitAsyncCommunicator("192.168.0.201", 5672, "zx", "123456") calbbacks = [["agv_park_command_request_queue", self.recv_park_request], ["agv_pick_command_request_queue", self.recv_pick_request]] self.g_rabbitmq.Init(calbbacks, None) self.g_rabbitmq.setDaemon(True) # 守护线程随主线程结束 self.g_rabbitmq.start() def execTask(self): while self.Cancel_ == False: task = self.taskTable.GetTask() if task != None: if isinstance(task, (message.park_table)): print(" exec park task :%s" % (task.primary_key)) ret = self.AutoParkTask(task) self.taskTable.UpdateResult(task.primary_key, ret) if isinstance(task, (message.pick_table)): print(" exec pick task :%s" % (task.primary_key)) ret = self.AutoPickTask(task) self.taskTable.UpdateResult(task.primary_key, ret) time.sleep(0.5) async def recv_park_request(self, msg): print("Recv_park_request------------------\n", msg) park_table = message.park_table() try: tf.Parse(msg, park_table) except Exception as e: print("Parse error\n") return False if self.isAutoDispatchOnline: return await self.PushParkTask(park_table) return False async def recv_pick_request(self, msg): print("Recv_pick_request------------------\n", msg) pick_table = message.pick_table() try: tf.Parse(msg, pick_table) except Exception as e: print("Parse error\n") return False if self.isAutoDispatchOnline: return await self.PushPickTask(pick_table) return False def updateMap_park(self, entrance_id, pose, wheelbase): # 0:前车轨迹,1:后车轨迹,2:添加整车轨迹 # 修改Front地图 self.mapManager.ResetMap("Front", 0, wheelbase / 2) [trans_x, trans_y, trans_a] = pose self.mapManager.maps["Front"].ResetVertexValue(mp.SpaceNode(entrance_id, trans_x, trans_y, trans_a)) [f_id, f_x, f_y] = self.ComputeStreetNode("Front", entrance_id, trans_x, trans_y, trans_a) # 修改Back地图 self.mapManager.ResetMap("Back", 0, -wheelbase / 2) [trans_x, trans_y, trans_a] = pose self.mapManager.maps["Back"].ResetVertexValue(mp.SpaceNode(entrance_id, trans_x, trans_y, trans_a)) [b_id, b_x, b_y] = self.ComputeStreetNode("Back", entrance_id, trans_x, trans_y, trans_a) # 修正两个地图巷道点 fff = False # 是否是整车空载进 出入口 if fff == True: f_x = (f_x + b_x) / 2 b_x = (f_x + b_x) / 2 self.mapManager.maps["Front"].ResetVertexValue(mp.StreetNode(f_id, f_x, f_y)) self.mapManager.maps["Back"].ResetVertexValue(mp.StreetNode(b_id, b_x, b_y)) def asyncExecute(self, tasks): results = [feature.result() for feature in concurrent.futures.as_completed(tasks)] print("==========================\n") print(results) print("==========================\n") ret = True for result in results: ret = ret and result return ret def GetMainFrontBackAGV(self): controlMain = self.Controller1 nagtive = False if controlMain.robot_.timedRobotStatu_.statu.theta < 0: nagtive = True control1 = None control2 = None if nagtive == False: control1 = self.Controller1 control2 = self.Controller2 else: control2 = self.Controller1 control1 = self.Controller2 return [controlMain, control1, control2] async def PushParkTask(self, park_table: message.park_table = None): pushed = False while pushed == False and self.Cancel_ == False: pushed = self.taskTable.PushTask(park_table.primary_key, park_table) await asyncio.sleep(0.3) if pushed != True or self.Cancel_ != False: return False ret = None while pushed and self.Cancel_ == False: ret = self.taskTable.GetResult(park_table.primary_key) if ret == None: await asyncio.sleep(1) else: break return (ret != None) async def PushPickTask(self, pick_table: message.pick_table = None): pushed = False while pushed == False and self.Cancel_ == False: pushed = self.taskTable.PushTask(pick_table.primary_key, pick_table) await asyncio.sleep(0.3) if pushed != True or self.Cancel_ != False: return False ret = None while pushed and self.Cancel_ == False: ret = self.taskTable.GetResult(pick_table.primary_key) if ret == None: await asyncio.sleep(1) else: break return (ret != None) def AutoParkTask(self, park_table: message.park_table = None): beg_time = time.time() print(beg_time, "AutoParkTask:---------------------\n") task_flag = 1 # 存车 [controlMain, control1, control2] = self.GetMainFrontBackAGV() mainMap, frontMap, backMap = ["Base", "Front", "Back"] entrance_id = "S_" + str(park_table.terminal_id) # "S1101" entrance_x, entrance_y, entrance_theta = [park_table.entrance_measure_info.measure_info_to_plc_forward.cx, park_table.entrance_measure_info.measure_info_to_plc_forward.cy, ( 90 + park_table.entrance_measure_info.measure_info_to_plc_forward.theta) / 180 * math.pi] # 变换到地图坐标系 # [dx, dy, da] = [-0.184040126204, -0.647539079189, 178.9302736990612 / 180 * math.pi] # trans_x = -0.999825716019 * entrance_x - 0.018668506294 * entrance_y + dx # trans_y = 0.018668506294 * entrance_x - 0.999825716019 * entrance_y + dy [dx, dy, da] = [-0.184040126204, -0.647539079189, 178.86625855601127 / 180 * math.pi] trans_x = -0.9998042333928334 * entrance_x - 0.01978622980177775 * entrance_y + dx trans_y = 0.01978622980177775 * entrance_x - 0.9998042333928334 * entrance_y + dy trans_a = entrance_theta + da - math.pi while trans_a < 0: trans_a += math.pi print("entrance:", entrance_id, trans_x, trans_y, trans_a / math.pi * 180) target_id = "S_" + str(park_table.allocated_space_info.table_id) # "S147" print("target:", target_id) # 轴距 wheel_base = park_table.entrance_measure_info.measure_info_to_plc_forward.wheelbase control1.WheelBaseEdit.setText(str(wheel_base)) control2.WheelBaseEdit.setText(str(wheel_base)) trans_x += wheel_base / 2 * math.cos(trans_a) trans_y += wheel_base / 2 * math.sin(trans_a) # # 双单车入库----------------------------------------------------- # if (controlMain.robot_.SwitchMoveMode(0, wheel_base) == False): # return False # autoDirect = True # self.updateMap_park(entrance_id, [trans_x, trans_y, trans_a], wheel_base) # # cur_pose1 = control1.robot_.timedRobotStatu_.statu # [label, pt] = self.mapManager.findNeastNode(frontMap, [cur_pose1.x, cur_pose1.y]) # control1.robot_.GeneratePath(label, entrance_id, frontMap) # print("Front: begin:%s target:%s wheelBase:%f" % (label, entrance_id, wheel_base)) # # cur_pose2 = control2.robot_.timedRobotStatu_.statu # [label, pt] = self.mapManager.findNeastNode(backMap, [cur_pose2.x, cur_pose2.y]) # control2.robot_.GeneratePath(label, entrance_id, backMap) # print("Back: begin:%s target:%s wheelBase:%f" % (label, entrance_id, wheel_base)) # # threadPool = ThreadPoolExecutor(2) # features = [ # threadPool.submit(control1.robot_.Navigatting, label, entrance_id, autoDirect, wheel_base, task_flag), # threadPool.submit(control2.robot_.Navigatting, label, entrance_id, autoDirect, wheel_base, task_flag) # ] # if self.asyncExecute(features) == False: # print(" Park Failed ") # return False # # ------------------------------------------ # # 双单车驶至入口前巷道点 self.updateMap_park(entrance_id, [trans_x, trans_y, trans_a], wheel_base) entrance_streetNode = entrance_id.replace("S_", "R_") if (controlMain.robot_.SwitchMoveMode(0, wheel_base) == False): return False cur_pose1 = control1.robot_.timedRobotStatu_.statu [label, pt] = self.mapManager.findNeastNode(frontMap, [cur_pose1.x, cur_pose1.y]) control1.robot_.GeneratePath(label, entrance_streetNode, frontMap) print("Front: begin:%s target:%s wheelBase:%f" % (label, entrance_streetNode, wheel_base)) cur_pose2 = control2.robot_.timedRobotStatu_.statu [label, pt] = self.mapManager.findNeastNode(backMap, [cur_pose2.x, cur_pose2.y]) control2.robot_.GeneratePath(label, entrance_streetNode, backMap) print("Back: begin:%s target:%s wheelBase:%f" % (label, entrance_streetNode, wheel_base)) autoDirect = True threadPool = ThreadPoolExecutor(2) features = [ threadPool.submit(control1.robot_.Navigatting, label, entrance_id, autoDirect, wheel_base, task_flag), threadPool.submit(control2.robot_.Navigatting, label, entrance_id, autoDirect, wheel_base, task_flag) ] if self.asyncExecute(features) == False: print(" Park Failed ") return False # 整车驶进入口--------------------------------- if (controlMain.robot_.SwitchMoveMode(1, wheel_base) == False): return False map_name = "Front" if controlMain.robot_.timedRobotStatu_.statu.theta < 0: map_name = "Back" controlMain.robot_.GeneratePath(entrance_streetNode, entrance_id, map_name) if controlMain.robot_.Navigatting(entrance_streetNode, entrance_id, True, wheel_base, task_flag) == False: return False # --------------------------------- print(" input entrance completed!!!!") # 整车夹持 if (controlMain.robot_.SwitchMoveMode(1, wheel_base) == False): return False controlMain.robot_.ClampClose() # 整车去车位--------------------------------- # map_name = "Front" # if controlMain.robot_.timedRobotStatu_.statu.theta < 0: # map_name = "Back" # controlMain.robot_.GeneratePath(entrance_id, target_id, map_name) # print("begin:%s target:%s wheelBase:%f" % (entrance_id, target_id, wheel_base)) # controlMain.robot_.Navigatting(entrance_id, target_id, autoDirect, wheel_base, task_flag) # 整车驶离入口到入口航道点 entrance_streetNode = entrance_id.replace("S_", "R_") map_name = "Front" if controlMain.robot_.timedRobotStatu_.statu.theta < 0: map_name = "Back" controlMain.robot_.GeneratePath(entrance_id, entrance_streetNode, map_name) print("begin:%s target:%s wheelBase:%f" % (entrance_id, entrance_streetNode, wheel_base)) controlMain.robot_.Navigatting(entrance_id, entrance_streetNode, autoDirect, wheel_base, task_flag) # 整车从入口航道点到车位 map_name = "Front" if controlMain.robot_.timedRobotStatu_.statu.theta < 0: map_name = "Back" controlMain.robot_.GeneratePath(entrance_streetNode, target_id, map_name) print("begin:%s target:%s wheelBase:%f" % (entrance_streetNode, target_id, wheel_base)) controlMain.robot_.Navigatting(entrance_streetNode, target_id, autoDirect, wheel_base, task_flag) print("-------------------------") # 整车松夹持------------------------------------ if controlMain.robot_.ClampOpen() == False: return False map_name = "Front" if controlMain.robot_.timedRobotStatu_.statu.theta < 0: map_name = "Back" # 整车出库--------------------------------- # 限定轴距2.6m temp_wheel_base = self.mapManager.default_wheel_base self.updateMap_park(entrance_id, [trans_x, trans_y, trans_a], temp_wheel_base) if (controlMain.robot_.SwitchMoveMode(1, temp_wheel_base) == False): return False entrance_streetNode = target_id.replace("S_", "R_") controlMain.robot_.GeneratePath(target_id, entrance_streetNode, map_name) if controlMain.robot_.Navigatting(target_id, entrance_streetNode, True, temp_wheel_base, task_flag) == False: return False # # if (controlMain.robot_.SwitchMoveMode(0, wheel_base) == False): # return False # # # 双单车出库 # controlMain, control1, control2 = self.GetMainFrontBackAGV() # end_street = target_id.replace("S_", "R_") # control1.robot_.GeneratePath(target_id, end_street, frontMap) # control2.robot_.GeneratePath(target_id, end_street, backMap) # # threadPool = ThreadPoolExecutor(2) # threadPool.submit(control1.robot_.Navigatting, # target_id, end_street, autoDirect, wheel_base, task_flag) # threadPool.submit(control2.robot_.Navigatting, # target_id, end_street, autoDirect, wheel_base, task_flag) # threadPool.shutdown(wait=True) # 反馈 self.g_rabbitmq.publish("command_ex", "agv_park_command_response_port", tf.MessageToString(park_table, as_utf8=True)) end_time = time.time() print(end_time, "Park time=", end_time - beg_time, "Publish_park_response------------------\n", park_table) return True def updateMap_pick(self, wheelBase): # 轴距 self.mapManager.ResetMap("Front", 0, wheelBase / 2) self.mapManager.ResetMap("Back", 0, -wheelBase / 2) def AutoPickTask(self, pick_table: message.pick_table = None): beg_time = time.time() print(beg_time,"AutoPickTask:---------------------\n") task_flag = 2 # 取车 controlMain, control1, control2 = self.GetMainFrontBackAGV() mainMap, frontMap, backMap = ["Main", "Front", "Back"] space_id = "S_" + str(pick_table.actually_space_info.table_id) # "S147" export_id = "S_" + str(pick_table.terminal_id) # "S1101" print(space_id, export_id) # 轴距 wheel_base = pick_table.actually_measure_info.measure_info_to_plc_forward.wheelbase control1.WheelBaseEdit.setText(str(wheel_base)) control2.WheelBaseEdit.setText(str(wheel_base)) # # 双单车入库 ------------------------- # self.updateMap_pick(wheel_base) # if (controlMain.robot_.SwitchMoveMode(0, wheel_base) == False): # return False # cur_pose1 = control1.robot_.timedRobotStatu_.statu # [label, pt] = self.mapManager.findNeastNode(frontMap, [cur_pose1.x, cur_pose1.y]) # control1.robot_.GeneratePath(label, space_id, frontMap) # print("Front: begin:%s target:%s wheelBase:%f" % (label, space_id, wheel_base)) # # cur_pose2 = control2.robot_.timedRobotStatu_.statu # [label, pt] = self.mapManager.findNeastNode(backMap, [cur_pose2.x, cur_pose2.y]) # control2.robot_.GeneratePath(label, space_id, backMap) # print("Back: begin:%s target:%s wheelBase:%f" % (label, space_id, wheel_base)) # # autoDirect = True # threadPool = ThreadPoolExecutor(2) # features = [threadPool.submit(control1.robot_.Navigatting, label, space_id, autoDirect, wheel_base, task_flag), # threadPool.submit(control2.robot_.Navigatting, label, space_id, autoDirect, wheel_base, task_flag)] # if self.asyncExecute(features) == False: # print(" Pick Failed ") # return False # ------------------------------------------ # # 双单车驶至车位前巷道点 self.updateMap_pick(wheel_base) space_streetNode = space_id.replace("S_", "R_") if (controlMain.robot_.SwitchMoveMode(0, wheel_base) == False): return False cur_pose1 = control1.robot_.timedRobotStatu_.statu [label, pt] = self.mapManager.findNeastNode(frontMap, [cur_pose1.x, cur_pose1.y]) control1.robot_.GeneratePath(label, space_streetNode, frontMap) print("Front: begin:%s target:%s wheelBase:%f" % (label, space_streetNode, wheel_base)) cur_pose2 = control2.robot_.timedRobotStatu_.statu [label, pt] = self.mapManager.findNeastNode(backMap, [cur_pose2.x, cur_pose2.y]) control2.robot_.GeneratePath(label, space_streetNode, backMap) print("Back: begin:%s target:%s wheelBase:%f" % (label, space_streetNode, wheel_base)) autoDirect = True threadPool = ThreadPoolExecutor(2) features = [ threadPool.submit(control1.robot_.Navigatting, label, space_streetNode, autoDirect, wheel_base, task_flag), threadPool.submit(control2.robot_.Navigatting, label, space_streetNode, autoDirect, wheel_base, task_flag) ] if self.asyncExecute(features) == False: print(" Pick Failed ") return False # 整车驶进车位--------------------------------- if (controlMain.robot_.SwitchMoveMode(1, wheel_base) == False): return False map_name = "Front" if controlMain.robot_.timedRobotStatu_.statu.theta < 0: map_name = "Back" controlMain.robot_.GeneratePath(space_streetNode, space_id, map_name) if controlMain.robot_.Navigatting(space_streetNode, space_id, True, wheel_base, task_flag) == False: return False # --------------------------------- # 整车夹持------------------------------------ print(" input space completed!!!!") if (controlMain.robot_.SwitchMoveMode(1, wheel_base) == False): return False if controlMain.robot_.ClampClose() == False: return False # 整车到出口--------------------------------- map_name = "Front" if controlMain.robot_.timedRobotStatu_.statu.theta < 0: map_name = "Back" controlMain.robot_.GeneratePath(space_id, export_id, map_name) print("Total: begin:%s target:%s wheelBase:%f" % (space_id, export_id, wheel_base)) if controlMain.robot_.Navigatting(space_id, export_id, True, wheel_base, task_flag) == False: return False # 整车松夹池------------------------------------ if controlMain.robot_.ClampOpen() == False: return False # 整车回巷道------------------------------------ temp_wheel_base = self.mapManager.default_wheel_base self.updateMap_pick(temp_wheel_base) if (controlMain.robot_.SwitchMoveMode(1, temp_wheel_base) == False): return False map_name = "Front" if controlMain.robot_.timedRobotStatu_.statu.theta < 0: map_name = "Back" space_streetNode = export_id.replace("S_", "R_") controlMain.robot_.GeneratePath(export_id, space_streetNode, map_name) if controlMain.robot_.Navigatting(export_id, space_streetNode, True, temp_wheel_base, task_flag) == False: return False # 双单车出库 # controlMain, control1, control2 = self.GetMainFrontBackAGV() # self.ReLoadMap(frontMap, "./map.json") # self.updateMap_pick(export_id, frontMap) # control1.robot_.GeneratePath(export_id, "F_exportLink", frontMap) # # self.ReLoadMap(backMap, "./map.json") # self.updateMap_pick(export_id, backMap) # control2.robot_.GeneratePath(export_id, "B_exportLink", backMap) # # threadPool = ThreadPoolExecutor(2) # features=[ # threadPool.submit(control1.robot_.Navigatting,export_id, "F_exportLink", True, wheel_base, task_flag), # threadPool.submit(control2.robot_.Navigatting,export_id, "B_exportLink", True, wheel_base, task_flag) # ] # if self.asyncExecute(features) == False: # print(" Pick Failed ") # return False print(" over publish...") # 反馈 self.g_rabbitmq.publish("command_ex", "agv_pick_command_response_port", tf.MessageToString(pick_table, as_utf8=True)) end_time = time.time() print(end_time, "Pick time=", end_time - beg_time, "Publish_pick_response------------------\n", pick_table) return True def ComputeStreetNode(self, mapName, s_id, s_x, s_y, s_theta): """ """ id, n_x, n_y = "", 0, 0 if s_id == "S_1101": id = "R_1101" n_y = self.mapManager.maps[mapName].graph_.points[id][1] k = math.tan(s_theta) n_x = (n_y - s_y) / k + s_x # 弧度 print(id, n_x, n_y) return [id, n_x, n_y] def readJson(self, file): with open(file, 'r', encoding='utf-8') as fp: map = json.load(fp) return map def Update(self): self.gl.update() if self.isAutoDispatchOnline: # self.Controller1.setEnabled(False) # self.Controller2.setEnabled(False) pass else: self.Controller1.setVisible(True) self.Controller2.setVisible(True) # 窗口基础属性 def basic(self): # 设置标题,大小,图标 self.setWindowTitle("GT") self.resize(1100, 650) self.setWindowIcon(QIcon("./image/Gt.png")) # 居中显示 screen = QDesktopWidget().geometry() self_size = self.geometry() self.move(int((screen.width() - self_size.width()) / 2), int((screen.height() - self_size.height()) / 2)) def closeEvent(self, QCloseEvent): self.Cancel_ = True self.gl.close() print("close...") # 分割窗口 def split_(self): splitter_main = QSplitter(Qt.Horizontal) splitter = QSplitter(Qt.Vertical) splitter.addWidget(self.count_frame_) splitter.addWidget(self.Controller1) splitter.addWidget(self.Controller2) splitter.addWidget(self.ManualOperationWidget) splitter.setStretchFactor(0, 1) splitter.setStretchFactor(1, 3) splitter.setStretchFactor(2, 3) splitter.setStretchFactor(3, 1) splitter_main.addWidget(splitter) splitter_main.addWidget(self.gl) splitter_main.setStretchFactor(0, 1) splitter_main.setStretchFactor(1, 10) return splitter_main if __name__ == "__main__": app = QApplication(sys.argv) win = MainWindow() win.show() sys.exit(app.exec_()) # =============================================================================== # # Local Variables: # mode: Python # indent-tabs-mode: nil # End: # # ===============================================================================