|
import sys |
|
from dataclasses import dataclass |
|
|
|
from PyQt5.QtCore import * |
|
from PyQt5.QtWidgets import * |
|
import keyboard |
|
|
|
import DroneController |
|
|
|
|
|
@dataclass |
|
class Vehicle(): |
|
acc = 1 |
|
vehicle_type = 'drone' |
|
|
|
veh = Vehicle() |
|
|
|
|
|
app = QApplication(sys.argv) |
|
|
|
class AirDroneClientWindow(QWidget): |
|
button_takeoff = QPushButton() |
|
button_land = QPushButton() |
|
button_up = QPushButton() |
|
button_down = QPushButton() |
|
|
|
button_f = QPushButton() |
|
button_b = QPushButton() |
|
button_l = QPushButton() |
|
button_r = QPushButton() |
|
|
|
button_weather = QPushButton() |
|
button_task = QPushButton() |
|
button_algorithm = QPushButton() |
|
button_formation = QPushButton() |
|
button_keyboard = QPushButton() |
|
|
|
weather_selection = QComboBox() |
|
|
|
label_gps_alt = QLabel() |
|
label_gps_lat = QLabel() |
|
label_gps_lon = QLabel() |
|
label_rot_w = QLabel() |
|
label_rot_y = QLabel() |
|
label_rot_z = QLabel() |
|
label_speed = QLabel() |
|
label_angle_speed = QLabel() |
|
|
|
refreshinfo = QTimer() |
|
|
|
def initUI(self): |
|
self.resize(500, 400) |
|
self.setWindowTitle("U21Data-2 Client") |
|
|
|
|
|
|
|
self.setObjectName("AirDroneClientWindow") |
|
|
|
|
|
self.setStyleSheet(self.styleSheet()) |
|
|
|
|
|
main_layout = QVBoxLayout() |
|
|
|
|
|
start_group = QGroupBox("Start Point") |
|
start_layout = QHBoxLayout() |
|
|
|
self.start_combo = QComboBox() |
|
self.start_combo.setEditable(True) |
|
self.start_combo.lineEdit().setReadOnly(True) |
|
self.start_combo.lineEdit().setAlignment(Qt.AlignCenter) |
|
self.start_combo.addItems(["9.8, -279, -22", "213, -429, 19","-315, -444, 12", "-335, 282, 19", "-152, 236, 66", "-430, -91, 13"]) |
|
self.start_combo.setCurrentIndex(-1) |
|
self.start_combo.lineEdit().setPlaceholderText("StartPoint") |
|
|
|
|
|
self.weather_selection = QComboBox() |
|
self.weather_selection.setEditable(True) |
|
self.weather_selection.lineEdit().setReadOnly(True) |
|
self.weather_selection.lineEdit().setAlignment(Qt.AlignCenter) |
|
self.weather_selection.addItems(["Clear", "Rain", "Snow", "Fog", "Overcast","Sand"]) |
|
self.weather_selection.setCurrentIndex(-1) |
|
self.weather_selection.lineEdit().setPlaceholderText("Weather") |
|
|
|
for widget in [self.start_combo, self.weather_selection]: |
|
widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) |
|
|
|
start_layout.addWidget(self.start_combo) |
|
start_layout.addWidget(self.weather_selection) |
|
start_group.setLayout(start_layout) |
|
|
|
|
|
func_group = QGroupBox("Functions") |
|
func_layout = QHBoxLayout() |
|
|
|
self.button_keyboard = QComboBox() |
|
self.button_keyboard.setEditable(True) |
|
self.button_keyboard.lineEdit().setReadOnly(True) |
|
self.button_keyboard.lineEdit().setAlignment(Qt.AlignCenter) |
|
self.button_keyboard.addItems(["Yes", "No"]) |
|
self.button_keyboard.setCurrentIndex(-1) |
|
self.button_keyboard.lineEdit().setPlaceholderText("Task") |
|
|
|
|
|
|
|
|
|
self.task_combo = QComboBox() |
|
self.task_combo.setEditable(True) |
|
self.task_combo.lineEdit().setReadOnly(True) |
|
self.task_combo.lineEdit().setAlignment(Qt.AlignCenter) |
|
self.task_combo.addItems(["Task 1", "Task 2", "Task 3"]) |
|
self.task_combo.setCurrentIndex(-1) |
|
self.task_combo.lineEdit().setPlaceholderText("Task") |
|
|
|
|
|
|
|
self.algorithm_combo = QComboBox() |
|
self.algorithm_combo.setEditable(True) |
|
self.algorithm_combo.lineEdit().setReadOnly(True) |
|
self.algorithm_combo.lineEdit().setAlignment(Qt.AlignCenter) |
|
self.algorithm_combo.addItems(["Algorithm 1", "Algorithm 2", "Algorithm 3"]) |
|
self.algorithm_combo.setCurrentIndex(-1) |
|
self.algorithm_combo.lineEdit().setPlaceholderText("Algorithm") |
|
|
|
|
|
self.formation_combo = QComboBox() |
|
self.formation_combo.setEditable(True) |
|
self.formation_combo.lineEdit().setReadOnly(True) |
|
self.formation_combo.lineEdit().setAlignment(Qt.AlignCenter) |
|
self.formation_combo.addItems(["Line Formation", "V Formation", "Square Formation", "Circle Formation"]) |
|
self.formation_combo.setCurrentIndex(-1) |
|
self.formation_combo.lineEdit().setPlaceholderText("Formation") |
|
|
|
|
|
for widget in [self.task_combo, self.algorithm_combo, |
|
self.formation_combo, self.button_keyboard]: |
|
widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) |
|
|
|
|
|
func_layout.addWidget(self.task_combo) |
|
func_layout.addWidget(self.algorithm_combo) |
|
func_layout.addWidget(self.formation_combo) |
|
func_layout.addWidget(self.button_keyboard) |
|
func_group.setLayout(func_layout) |
|
|
|
|
|
flight_group = QGroupBox("Flight Controls") |
|
flight_layout = QVBoxLayout() |
|
|
|
|
|
top_row_layout = QHBoxLayout() |
|
self.button_takeoff = QPushButton("Takeoff") |
|
self.button_land = QPushButton("Land") |
|
self.button_up = QPushButton("Up") |
|
self.button_down = QPushButton("Down") |
|
|
|
|
|
for button in [self.button_takeoff, self.button_land, |
|
self.button_up, self.button_down]: |
|
button.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) |
|
|
|
top_row_layout.addWidget(self.button_takeoff) |
|
top_row_layout.addWidget(self.button_land) |
|
top_row_layout.addWidget(self.button_up) |
|
top_row_layout.addWidget(self.button_down) |
|
top_row_layout.setSpacing(5) |
|
|
|
|
|
move_layout = QGridLayout() |
|
self.button_f = QPushButton("Move Forward") |
|
self.button_b = QPushButton("Move Backward") |
|
self.button_l = QPushButton("Move Left") |
|
self.button_r = QPushButton("Move Right") |
|
move_layout.addWidget(self.button_f, 0, 1) |
|
move_layout.addWidget(self.button_b, 2, 1) |
|
move_layout.addWidget(self.button_l, 1, 0) |
|
move_layout.addWidget(self.button_r, 1, 2) |
|
|
|
flight_layout.addLayout(top_row_layout) |
|
flight_layout.addLayout(move_layout) |
|
flight_group.setLayout(flight_layout) |
|
|
|
|
|
log_group = QGroupBox("Log") |
|
log_layout = QVBoxLayout() |
|
self.label_gps_alt = QLabel("GPS Altitude: ") |
|
self.label_gps_lat = QLabel("GPS Latitude: ") |
|
self.label_gps_lon = QLabel("GPS Longitude: ") |
|
self.label_rot_w = QLabel("Rotation w: ") |
|
self.label_rot_y = QLabel("Rotation y: ") |
|
self.label_rot_z = QLabel("Rotation z: ") |
|
self.label_speed = QLabel("Linear Speed: ") |
|
self.label_angle_speed = QLabel("Angle Speed: ") |
|
|
|
log_layout.addWidget(self.label_gps_alt) |
|
log_layout.addWidget(self.label_gps_lat) |
|
log_layout.addWidget(self.label_gps_lon) |
|
log_layout.addWidget(self.label_rot_w) |
|
log_layout.addWidget(self.label_rot_y) |
|
log_layout.addWidget(self.label_rot_z) |
|
log_layout.addWidget(self.label_speed) |
|
log_layout.addWidget(self.label_angle_speed) |
|
log_group.setLayout(log_layout) |
|
|
|
|
|
main_layout.addWidget(start_group) |
|
main_layout.addWidget(func_group) |
|
main_layout.addWidget(flight_group) |
|
main_layout.addWidget(log_group) |
|
|
|
self.setLayout(main_layout) |
|
|
|
|
|
self.button_takeoff.clicked.connect(DroneController.dronecontrol.TakeOff) |
|
self.button_land.clicked.connect(DroneController.dronecontrol.Landed) |
|
self.button_up.clicked.connect(self.up) |
|
self.button_down.clicked.connect(self.down) |
|
self.button_f.pressed.connect(self.forward) |
|
self.button_b.pressed.connect(self.backward) |
|
self.button_l.pressed.connect(self.left) |
|
self.button_r.pressed.connect(self.right) |
|
self.button_f.released.connect(self.stop) |
|
self.button_b.released.connect(self.stop) |
|
self.button_l.released.connect(self.stop) |
|
self.button_r.released.connect(self.stop) |
|
self.button_keyboard.currentIndexChanged.connect(self.EnableKeyboard) |
|
self.weather_selection.currentIndexChanged.connect(self.change_weather) |
|
self.algorithm_combo.currentIndexChanged.connect(self.on_algorithm_changed) |
|
self.formation_combo.currentIndexChanged.connect(self.on_formation_changed) |
|
self.task_combo.currentIndexChanged.connect(self.on_task_changed) |
|
self.start_combo.currentIndexChanged.connect(self.on_start_changed) |
|
|
|
|
|
self.refreshinfo.start(1000) |
|
self.refreshinfo.timeout.connect(self.setInfo) |
|
|
|
self.show() |
|
|
|
def setInfo(self): |
|
self.label_gps_alt.setText("GPS Altitude: " + str(DroneController.dronecontrol.GetState().gps_pos_altitude)) |
|
self.label_gps_lat.setText("GPS Latitude: " + str(DroneController.dronecontrol.GetState().gps_pos_latitude)) |
|
self.label_gps_lon.setText("GPS Longitude: " + str(DroneController.dronecontrol.GetState().gps_pos_longitude)) |
|
|
|
self.label_rot_w.setText("Rotation w: " + str(DroneController.dronecontrol.GetState().ori_x)) |
|
self.label_rot_y.setText("Rotation y: " + str(DroneController.dronecontrol.GetState().ori_y)) |
|
self.label_rot_z.setText("Rotation z: " + str(DroneController.dronecontrol.GetState().ori_z)) |
|
|
|
self.label_speed.setText("Linear Speed: " + str(DroneController.dronecontrol.GetState().linear_speed)) |
|
self.label_angle_speed.setText("Angle Speed: " + str(DroneController.dronecontrol.GetState().a_v_x)) |
|
|
|
|
|
def forward(self): |
|
DroneController.dronecontrol.DroneMoveByTime(veh.acc, 0, 0) |
|
|
|
def backward(self): |
|
DroneController.dronecontrol.DroneMoveByTime(-veh.acc, 0, 0) |
|
|
|
def left(self): |
|
DroneController.dronecontrol.DroneMoveByTime(0, -veh.acc, 0) |
|
|
|
def right(self): |
|
DroneController.dronecontrol.DroneMoveByTime(0, veh.acc, 0) |
|
|
|
def stop(self): |
|
pass |
|
|
|
def up(self): |
|
DroneController.dronecontrol.DroneMoveByTime(0, 0, -veh.acc) |
|
|
|
def down(self): |
|
DroneController.dronecontrol.DroneMoveByTime(0, 0, veh.acc) |
|
|
|
def change_weather(self, index): |
|
if index >= 0: |
|
weather = self.weather_selection.currentText() |
|
if weather == "Snow": |
|
DroneController.dronecontrol.SnowTeleport() |
|
elif weather == "Rain": |
|
DroneController.dronecontrol.RainTeleport() |
|
elif weather == "Fog": |
|
DroneController.dronecontrol.FogTeleport() |
|
elif weather == "Overcast": |
|
DroneController.dronecontrol.OvercastTeleport() |
|
elif weather == "Clear": |
|
DroneController.dronecontrol.ClearTeleport() |
|
elif weather == "Sand": |
|
DroneController.dronecontrol.SandTeleport() |
|
|
|
def on_algorithm_changed(self, index): |
|
"""Algorithm下拉框选择变化时的处理""" |
|
if index >= 0: |
|
selected_algorithm = self.algorithm_combo.currentText() |
|
print(f"Selected Algorithm: {selected_algorithm}") |
|
|
|
|
|
def on_formation_changed(self, index): |
|
"""Formation下拉框选择变化时的处理""" |
|
if index >= 0: |
|
selected_formation = self.formation_combo.currentText() |
|
print(f"Selected Formation: {selected_formation}") |
|
|
|
|
|
def on_task_changed(self, index): |
|
"""Task下拉框选择变化时的处理""" |
|
if index >= 0: |
|
selected_task = self.task_combo.currentText() |
|
print(f"Selected Task: {selected_task}") |
|
|
|
|
|
def on_start_changed(self, index): |
|
if index >= 0: |
|
pos = self.start_combo.currentText() |
|
if pos == "9.8, -279, -22": |
|
DroneController.dronecontrol.SnowTeleport() |
|
elif pos == "213, -429, 19": |
|
DroneController.dronecontrol.OvercastTeleport() |
|
elif pos == "-315, -444, 12": |
|
DroneController.dronecontrol.RainTeleport() |
|
elif pos == "-335, 282, 19": |
|
DroneController.dronecontrol.SandTeleport() |
|
elif pos == "-152, 236, 66": |
|
DroneController.dronecontrol.ClearTeleport() |
|
elif pos == "-430, -91, 13": |
|
DroneController.dronecontrol.FogTeleport() |
|
else: |
|
print(self.start_combo.currentIndex()) |
|
|
|
def EnableKeyboard(self): |
|
keyboard.hook(DroneController.dronecontrol.KeyboardControl) |
|
keyboard.wait() |
|
|
|
window = AirDroneClientWindow() |
|
window.initUI() |
|
window.setInfo() |
|
sys.exit(app.exec()) |