diff --git a/Drone/Client.py b/Drone/Client.py index 71e403f..8b1a7b5 100755 --- a/Drone/Client.py +++ b/Drone/Client.py @@ -1,99 +1,207 @@ +from __future__ import print_function +import sys import socket -import play_animation +import struct +import random import time -import ntplib -from threading import Thread -sock = socket.socket() -serv = '192.168.1.10' # Change to server ip -port = 35001 -sock.connect((serv, port)) -sock.send(bytes('left', 'utf-8')) -command = '' +import threading +import ConfigParser +from contextlib import closing + +#import rospy + +#import play_animation + +random.seed() + +NTP_PACKET_FORMAT = "!12I" +NTP_DELTA = 2208988800L # 1970-01-01 00:00:00 +NTP_QUERY = '\x1b' + 47 * '\0' -def receive(): - global command - try: +def get_ntp_time(host, port): + with closing(socket.socket(socket.AF_INET, socket.SOCK_DGRAM)) as s: + s.sendto(NTP_QUERY, (host, port)) + msg, address = s.recvfrom(1024) + unpacked = struct.unpack(NTP_PACKET_FORMAT, msg[0:struct.calcsize(NTP_PACKET_FORMAT)]) + return unpacked[10] + float(unpacked[11]) / 2**32 - NTP_DELTA + + +def reconnect(t=1): + print("Trying to connect to", host, ":", port, "...") + connected = False + global clientSocket + while not connected: + try: + clientSocket = socket.socket() + clientSocket.connect((host, port)) + connected = True + print("Connection successful") + except socket.error as e: + print("Waiting for connection:", e) + time.sleep(t) + + +def send_all(msg): + clientSocket.sendall(struct.pack('>I', len(msg)) + msg) + + +def recive_all(n): + data = b'' + while len(data) < n: + packet = clientSocket.recv(min(n - len(data), BUFFER_SIZE)) + if not packet: + return None + data += packet + return data + + +def recive_message(): + raw_msglen = recive_all(4) + if not raw_msglen: + return None + msglen = struct.unpack('>I', raw_msglen)[0] + msg = recive_all(msglen) + return msg + + +def form_command(command, args=()): + return " ".join([command, args]) + + +def parse_command(command_input): + args = command_input.split() + command = args.pop(0) + return command, args + + +def recive_file(filename): + print("Reciving file:", filename) + with open(filename, 'wb') as file: # TODO add directory while True: - data = str(sock.recv(1024)) - try: - if b'programm' in data: - anim = open('anim.csv', 'w') - data = data[data.index(b'programm') + 8:] - anim.write(data) - - while True: - data = str(sock.recv(1024)) - - if b'stop' in data: - anim.write(data[:data.index(b'stop')]) - break - else: - anim.write(data) - - else: - try: - sq = data.split('$$') - for i in range(len(sq) - 1): - print(sq[i]) - command = sq[i] - - except Exception as e: - print(e) - - except: - print('er') - sock.close() - except KeyboardInterrupt: - print("Shutting down") - - led.off() - sock.close() + data = recive_message() #clientSocket.recv(BUFFER_SIZE) + if data: + print(data) + if parse_command(data.decode("UTF-8"))[0] == "/endoffile": + print("File recived") + break + file.write(data) -def time_synch(): - c = ntplib.NTPClient() - response = c.request('ntp1.stratum2.ru') - return response.tx_time-time.time() +def write_to_config(section, option, value): + config.set(section, option, value) + with open(CONFIG_PATH, 'w') as file: + config.write(file) -def pl_anim(): - global command - play_animation.read_animation_file() - dtime = time_synch() - time.time() - ok = 0 - t_st=0 - while True: - - if 'begin_anim' in command: - t_st = int(command[command.index('('):]) - - if t_st == dtime+time.time: +def animation_player(running_event, stop_event): + print("Animation thread activated") + rate = rospy.Rate(1000 / 100) + play_animation.takeoff(TAKEOFF_HEIGHT) + for current_frame in play_animation.frame(): + running_event.wait() + if stop_event.is_set(): break - if 'synch' in command: - dtime=time_synch() - time.time() - print(dtime) - play_animation.takeoff() - for frame in play_animation.frame(): - if command != 'pause': - time.sleep(0.1) - play_animation.do_next_animation(frame) + play_animation.do_next_animation(current_frame) + rate.sleep() + else: + play_animation.land() + print("Animation ended") + print("Animation thread closed") -if __name__ == "__main__": - t_0 = Thread(target=receive) - t_0.daemon = True - t_0.start() - - t_1 = Thread(target=pl_anim) - t_1.daemon = True - t_1.start() - - - - +stop_animation_event = threading.Event() +running_animation_event = threading.Event() +animation_thread = threading.Thread(target=animation_player, args=(running_animation_event, stop_animation_event)) +def start_animation(): + play_animation.read_animation_file(animation_file) + print("Starting animation!") + resume_animation() + animation_thread.start() +def resume_animation(): + print("Resuming animation") + running_animation_event.set() + + +def pause_animation(): + print("Pausing animation") + running_animation_event.clear() + + +def stop_animation(): + stop_animation_event.set() + running_animation_event.clear() + print("Stopping animation") + animation_thread.join() + + +CONFIG_PATH = "client_config.ini" +config = ConfigParser.ConfigParser() +config.read(CONFIG_PATH) + + +port = int(config.get('SERVER', 'port')) +host = config.get('SERVER', 'host') +BUFFER_SIZE = int(config.get('SERVER', 'buffer_size')) +NTP_HOST = config.get('NTP', 'host') +NTP_PORT = int(config.get('NTP', 'port')) + +files_directory = config.get('FILETRANSFER', 'files_directory') +animation_file = config.get('COPTER', 'animation_file') + +COPTER_ID = config.get('COPTER', 'id') +if COPTER_ID == 'default': + COPTER_ID = 'copter' + str(random.randrange(9999)).zfill(4) + write_to_config('COPTER', 'id', COPTER_ID) + +TAKEOFF_HEIGHT = float(config.get('COPTER', 'takeoff_height')) + +print("Client started on copter:", COPTER_ID) +print("NTP time:", time.ctime(get_ntp_time(NTP_HOST, NTP_PORT))) +print("System time", time.ctime(time.time())) + +reconnect() + +print("Connected to server") + +try: + while True: + try: + message = recive_message() + if message: + message = message.decode("UTF-8") + command, args = parse_command(message) + print("Command from server:", command, args) + if command == "writefile": + recive_file(args[0]) + elif command == "starttime": + starttime = float(args[0]) + print("Starting on:", time.ctime(starttime)) + dt = starttime - get_ntp_time(NTP_HOST, NTP_PORT) + print("Until start:", dt) + rospy.Timer(rospy.Duration(dt), start_animation, oneshot=True) + elif command == 'request': + request_target = args[0] + print("Got request for:", request_target) + response = "" + if request_target == 'someshit': + response = "dont_have_any" + elif request_target == 'id': + response = COPTER_ID + send_all(bytes(form_command("response", response))) + print("Request responded with:", response) + + except socket.error: + print("Connection lost... reconnecting") + reconnect() + print("Re-connection successful") +except KeyboardInterrupt: + print("Shutdown on keyboard interrupt") +finally: + clientSocket.close() + diff --git a/Drone/client_config.ini b/Drone/client_config.ini new file mode 100644 index 0000000..71439a9 --- /dev/null +++ b/Drone/client_config.ini @@ -0,0 +1,17 @@ +[SERVER] +port = 25000 +host = 192.168.43.168 +buffer_size = 1024 + +[FILETRANSFER] +files_directory = files + +[NTP] +host = ntp1.stratum2.ru +port = 123 + +[COPTER] +id = copter6349 +takeoff_height = 1.75 +takeoff_timeout = 7 +animation_file = animation.csv diff --git a/Server/Server.py b/Server/Server.py index db7ed54..e23082f 100644 --- a/Server/Server.py +++ b/Server/Server.py @@ -1,388 +1,289 @@ -# -*- coding: utf-8 -*- . -"""Code by Alexandr Osherov 10 class, phone - +79251834732, email - allexandr2001@mail.ru """ -from PyQt5.QtWidgets import * -from PyQt5.QtGui import * -from PyQt5.QtCore import * -from mpl_toolkits.mplot3d import Axes3D -import matplotlib.pyplot as plt -import time -import socket +from tkinter import * +from tkinter import ttk +from tkinter import filedialog +import ttkwidgets + import os -import easygui +import sys +import glob +import time +import struct +import socket import threading -from threading import Thread -import math -import requests -import json -import main_gui -import gui_telem -import ntplib -ip = [1, 2] -sq_rad = 0 -sq_cet = 0 -cr_rad = 0 -cr_cet = 0 -copters = 1 -conn = [] -conn_2 = [] -afile = '' -data = b'' -addr = [] -addr_2 = [] -coord = [] -d_time = 0 -size_scene=[2,2,2] -sock = socket.socket() +import collections +import configparser -sock.bind(('', 35001)) # назначается адресс и порт связи для отпраки команд на коптеры -sock.listen(1) - -sock_2 = socket.socket() -sock_2.bind(('', 35002)) # назначается адресс и порт связи для приема данных с коптеров -sock_2.listen(1) +# All imports sorted in pyramid -class Dialog(QMainWindow, gui_telem.Ui_Dialog): - def __init__(self): - super().__init__() - self.setupUi(self) +def auto_connect(): + while True: + ServerSocket.listen(1) + c, addr = ServerSocket.accept() + print("Got connection from:", str(addr)) + #client_thread = threading.Thread(target=on_new_client, args=(c, addr)) + #client_thread.start() - def up(self): - self.voltage_2.setText('1234567') + if not any(client_addr == addr[0] for client_addr in Client.clients.keys()): + client = Client(addr[0]) + print("New client") + else: + print("Reconnected client") + Client.clients[addr[0]].connect(c, addr) -class Widget(QMainWindow, main_gui.Ui_MainWindow): - def __init__(self): - super().__init__() - self.setupUi(self) - self.start_animation_button.clicked.connect(self.start_animation) - self.stop_swarm_but.clicked.connect(self.stop_swarm) - self.show_3d_scene_button.clicked.connect(self.show_3d) - self.disarm_all_button.clicked.connect(self.disarm) - self.turn_off_led_button.clicked.connect(self.off_leds) - self.turn_on_led_button.clicked.connect(self.on_leds) - self.upload_animation_button.clicked.connect(self.upload_animation) - self.land_all_button.clicked.connect(self.land) - self.take_off_button.clicked.connect(self.take_off) - #self.number_animation_copters.clicked.connect(self.number_animation) synch_button - self.synch_button.clicked.connect(self.synch) - self.take_off_n_button.clicked.connect(self.take_off_n) - self.land_n_button.clicked.connect(self.land_n) - self.disarm_n_button.clicked.connect(self.disarm_n) - self.land_spinBox.valueChanged.connect(self.land_led) - self.disarm_spinBox.valueChanged.connect(self.disarm_led) - self.take_off_spinBox.valueChanged.connect(self.take_off_led) - self.safty_button.clicked.connect(self.safty) - self.connect_button.clicked.connect(self.connect) - self.swarm_size_spinBox.valueChanged.connect(self.number_copters) +NTP_DELTA = 2208988800 # 1970-01-01 00:00:00 +NTP_QUERY = b'\x1b' + bytes(47) - - def receiver(self): - global copters - global addr - while True: +def get_ntp_time(ntp_host, ntp_port): + with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s: + s.sendto(NTP_QUERY, (ntp_host, ntp_port)) + msg, _ = s.recvfrom(1024) + return int.from_bytes(msg[-8:], 'big') / 2 ** 32 - NTP_DELTA + + +def requires_connect(f): + def wrapper(*args, **kwargs): + if args[0].connected: + return f(*args, **kwargs) + else: + print("Function requires client to be connected!") + return wrapper + + +class Client: + clients = {} + + def __init__(self, ip): + self.socket = None + self.addr = None + + self._send_queue = collections.deque() + self._received_queue = collections.deque() + self._request_queue = collections.OrderedDict() + + self.copter_id = None + self.malfunction = False + + Client.clients[ip] = self + + self.connected = False + + def connect(self, client_socket, client_addr): + print("Client connected") + self._send_queue = collections.deque() # comment for resuming queue after reconnection + + self.socket = client_socket + self.addr = client_addr + + self.socket.setblocking(0) + self.connected = True + client_thread = threading.Thread(target=self._run, args=()) + client_thread.start() + if self.copter_id is None: + self.copter_id = self.get_response("id") + print("Got copter id:", self.copter_id) + drone_list.insert("", "end", self.addr[0], text=self.copter_id) + + def _send_all(self, msg): + self.socket.sendall(struct.pack('>I', len(msg)) + msg) + + def _receive_all(self, n): + data = b'' + while len(data) < n: + packet = self.socket.recv(min(n - len(data), BUFFER_SIZE)) + if not packet: + return None + data += packet + return data + + def _receive_message(self): + raw_msglen = self._receive_all(4) + if not raw_msglen: + return None + msglen = struct.unpack('>I', raw_msglen)[0] + msg = self._receive_all(msglen) + return msg + + def _run(self): + while self.connected: try: - for k in range(copters): - a = requests.get('http://' + addr[k][0] + ':8081/aruco_map') - tem = json.loads(a.text) - - coord[k] = str(tem['x']) + ',' + str(tem['y']) + ',' + str(tem['z']) + ',' + \ - str(tem['mode']) + ',' + str(tem['armed']) + ',' + str(tem['frame_id']) + str( - tem['voltage']) + ',' + \ - str(tem['yaw']) + ',' + str(tem['pitch']) + ',' + str(tem['roll']) + ',' + \ - str(tem['vx']) + ',' + str(tem['vy']) + ',' + str(tem['vz']) - - #time.sleep(0.05) - - - except Exception as e: - pass - - def sender(self, com, num): - global conn - global conn_2 - global copters - print(com) - print(num) - try: - if num == 'all': - for i in range(copters): - conn[i].send(com + b'$$') - print(com + b'$$') - elif int(num) > 0: - conn[int(num) - 1].send(com + b'$$') - except: - pass - - def message(self, mes): - pass - - def connect(self): - global copters - global conn - global conn_2 - global addr - global addr_2 - global coord - - addr_2 = [] - - conn = [] - conn_2 = [] - - self.message('Try connect') - for i in range(copters): - conn.append(0) - addr.append(0) - coord.append('0') - - t_0 = Thread(target=self.connect_init) - t_0.daemon = True - t_0.start() - - def connect_init(self): - self.state_label.setText("

Wait

") - global copters - - global conn - global addr - global conn_2 - global addr_2 - - for i in range(copters): - conn[i], addr[i] = sock.accept() - print("connected_controllers:", addr[i]) - - self.disarm_spinBox.setMaximum(copters) - self.land_spinBox.setMaximum(copters) - self.take_off_spinBox.setMaximum(copters) - self.state_label.setText("

Connect

") - - t = Thread(target=self.receiver) - t.daemon = True - t.start() - - def safty(self): - self.message('safty check') - self.sender(b'f.safety_check(False)', 'all') - - def take_off(self): - self.message('take off') - self.sender(b'f.takeoff(z=2, speed=2,speed_takeoff=2 , timeout=2)', 'all') - - def take_off_n(self): - self.message('take off n') - self.sender(b'f.takeoff()', str(self.take_off_spinBox.value())) - - def land(self): - self.message('land') - self.sender(b'f.land(preland=False)', 'all') - - def land_n(self): - self.message('land n') - self.sender(b'f.land(preland=False)', str(self.land_spinBox.value())) - - def disarm(self): - self.sender(b'f.arming(False)', 'all') - - def disarm_n(self): - self.sender(b'f.arming(False)', str(self.disarm_spinBox.value())) - - def off_leds(self): - self.sender(b'led.off()', 'all') - - def land_led(self): - self.sender(b'led.off()', 'all') - self.sender(b'led.fill(255,0,0)', self.land_spinBox.value()) - # print(1) - - def disarm_led(self): - self.sender(b'led.off()', 'all') - self.sender(b'led.fill(0,255,0)', self.disarm_spinBox.value()) - - def take_off_led(self): - self.sender(b'led.off()', 'all') - self.sender(b'led.fill(0,0,255)', self.take_off_spinBox.value()) - - def on_leds(self): - self.sender(b'led.fill(0,0,255)', 'all') - - def number_copters(self): - global copters - copters = self.swarm_size_spinBox.value() - - def upload_animation(self): - global afile - afile = easygui.fileopenbox(filetypes=["*.csv"],multiple=True) # вызов окна проводника для выбора файла - - def start_animation(self): - global afile - global d_time - for counter, sub_file in enumerate(afile): - f = open(sub_file, 'r') - prog = f.read() - self.sender(b'programm' + bytes(prog, 'utf-8')+b'stop', str(counter)) - time.sleep(0.1) - for i in range(len(afile)): - self.sender(bytes('begin_anim('+str(time.time()+d_time+10)+')','utf-8', str(counter))) - - t1 = Thread(target=self.start_retime) - t1.daemon = True - t1.start() - - - def start_retime(self): - for i in range(11): - time.sleep(1) - self.time_to_start_label.setText("

"+str(10-i)+"

") - '''if i==10: - k=0 - while True: - k+=1 - time.sleep(0.2r) - self.time_to_start_label.setText("

"+k*'.'+"

") - if k>3: - k=0'''# for ... animation - self.time_to_start_label.setText("

Take off

") - time.sleep(2) - self.time_to_start_label.setText("

") - - - - def stop_swarm(self): - pass - - def synch(self): - global d_time - self.sender(b'synch', 'all') - c = ntplib.NTPClient() - response = c.request('ntp1.stratum2.ru') - d_time = response.tx_time-time.time() - print(d_time) - - def show_3d(self): - global size_scene - global data - global copters - global coord - fig = plt.figure() - ax = fig.add_subplot(111, projection='3d') - updateDialog = Dialog() - updateDialog.show() - - while True: - s = str(self.console_textEdit.toPlainText()) - #print(s) - if '>' in s: - - print(s[:-2], s[s.index('>') - 1]) - self.console_textEdit.setText('') - if s[s.index('>') - 1] == '0': - self.sender(bytes(str(s[:s.index('>') - 1]), 'utf-8'), 'all') - #print(s[:s.index('>') - 1], 'all') + if self._send_queue: + msg = self._send_queue.popleft() + print("Send", msg, "to", self.addr) + self._send_all(msg) else: - self.sender(bytes(str(s[:s.index('>') - 1]), 'utf-8'), str(s[s.index('>') - 1])) - #print('sender', s[s.index('>') - 1]) - try: + msg = "ping" + #self._send_all(msg) - i = updateDialog.number_spinBox.value() - if i > 0: - i -= 1 - - coord_drone = [] - coord_drone = coord[i].split(',') - - updateDialog.z_2.setText("

" + coord_drone[ - 0] + "

") - updateDialog.x_2.setText("

" + coord_drone[ - 1] + "

") - updateDialog.y_2.setText("

" + coord_drone[ - 2] + "

") - updateDialog.mode_2.setText("

" + coord_drone[ - 3] + "

") - updateDialog.armed_2.setText("

" + coord_drone[ - 4] + "

") - updateDialog.frame_id_2.setText("

" + coord_drone[ - 5] + "

") - updateDialog.voltage_2.setText("

" + coord_drone[ - 6] + "

") - updateDialog.yaw2.setText("

" + coord_drone[ - 7] + "

") - updateDialog.pitch_2.setText("

" + coord_drone[ - 8] + "

") - updateDialog.roll_2.setText("

" + coord_drone[ - 9] + "

") - updateDialog.vx_2.setText("

" + coord_drone[ - 10] + "

") - updateDialog.vy_2.setText("

" + coord_drone[ - 11] + "

") - updateDialog.vz_2.setText("

" + coord_drone[ - 12] + "

") - except Exception as e: - # print(e) - pass - try: - - n = 0 - # set size of scene - - ax.set_xlim(0, size_scene[0]) - ax.set_ylim(0, size_scene[1]) - ax.set_zlim(0, size_scene[2]) - - ax.set_xlabel('x') - ax.set_ylabel('y') - ax.set_zlabel('z') - - plt.pause(0.01) - - ax.clear() - try: - for i in coord: - co = (0, 0, 0) - n += 1 - - if self.land_spinBox.value() == n: - co = (1, 0, 0) - if self.take_off_spinBox.value() == n: - co = (1, 0, 0) - if self.disarm_spinBox.value() == n: - co = (1, 0, 0) - - ax.scatter(float(i.split(',')[0]), float(i.split(',')[1]), float(i.split(',')[2]), s=50, c=co, - marker='.') - ax.text(float(i.split(',')[0]), float(i.split(',')[1]), float(i.split(',')[2]), str(n), size=10, - zorder=1, color=(0, 0, 0)) - - except Exception as e: - #print(e) + try: # check if data in buffer + check = self.socket.recv(BUFFER_SIZE, socket.MSG_PEEK) + if check: + received = self._receive_message() + if received: + received = received.decode("UTF-8") + print("Recived", received, "from", self.addr) + command, args = Client.parse_command(received) + if command == "response": + for key, value in self._request_queue.items(): + if not value: + self._request_queue[key] = args[0] + print("Request successfully closed") + break + else: + self._received_queue.appendleft(received) + except socket.error: pass - ax.set_xlim(0, size_scene[0]) - ax.set_ylim(0, size_scene[1]) - ax.set_zlim(0, size_scene[2]) - - - ax.set_xlabel('x') - ax.set_ylabel('y') - ax.set_zlabel('z') - - plt.draw() - except KeyboardInterrupt: - print('stop') + except socket.error as e: + print("Client error, disconnected", e) + self.connected = False + self.socket.close() break + # time.sleep(0.05) - plt.show() + @staticmethod + def form_command(command: str, args=()): # Change for different protocol + return " ".join([command, *args]) + + @staticmethod + def parse_command(command_input): + args = command_input.split() + command = args.pop(0) + return command, args + + @requires_connect + def send(self, *messages): + for message in messages: + self._send_queue.append(bytes(message, "UTF-8")) + + @staticmethod + def broadcast(message, force_all=False): + for client in Client.clients.values(): + if (not client.malfunction) or force_all: + client.send(message) + + @requires_connect + def send_file(self, filepath, dest_filename): + print("Sending file ", dest_filename) + self.send(Client.form_command("writefile", (dest_filename,))) + file = open(filepath, 'rb') + chunk = file.read(BUFFER_SIZE) + while chunk: + self._send_queue.append(chunk) + chunk = file.read(BUFFER_SIZE) + file.close() + self.send(Client.form_command("/endoffile")) + print("File sent") + + @requires_connect + def get_response(self, requested_value): + self._request_queue[requested_value] = "" + self.send(Client.form_command("request", (requested_value, ))) + + while not self._request_queue[requested_value]: + pass + + return self._request_queue.pop(requested_value) - -app = QApplication([]) -w = Widget() -w.show() - -app.exec() +# UI functions +def stop_swarm(): + Client.broadcast("stop") # для тестирования +def send_animations(): + path = filedialog.askdirectory(title="Animation directory") + if path: + print("Selected directory:", path) + files = [file for file in glob.glob(path+'/*.csv')] + names = [os.path.basename(file).split(".")[0] for file in files] + print(files) + for file, name in zip(files, names): + for copter in Client.clients.values(): + if name == copter.copter_id: + copter.send_file(file, "animation.csv") # TODO config + else: + print("Filename not matches with any drone connected") + #dr = next(iter(Client.clients.values())) # костыль для тестирования + #ANS = dr.get_response("someshit") + #print(ANS) + + +def send_starttime(dt=60): + timenow = time.time() + print('Now:', time.ctime(timenow), "+ dt =", dt) + Client.broadcast(Client.form_command("starttime", (str(timenow+dt), ))) + + +# UI build here +root = Tk() +root.wm_title("Drone swarm operation server") +root.style = ttk.Style() +root.style.theme_use("vista") + +leftFrame = Frame(root) +leftFrame.grid(row=0, column=0, padx=10, pady=10) +rightFrame = Frame(root) +rightFrame.grid(row=0, column=1, padx=10, pady=10) + +drone_list = ttkwidgets.CheckboxTreeview(leftFrame, columns=("addr", "connected")) +#drone_list["columns"] = ("addr") +#drone_list.column("name") #width=100 +#drone_list.column("addr") +drone_list.heading("#0", text="Drone name") +drone_list.heading("#1", text="Connection adress") +drone_list.heading("#2", text="Connection status") +drone_list.pack() + +button_frame = Frame(leftFrame, borderwidth=1, relief="solid") +button_frame.pack(fill=BOTH, expand=True) + +stop_all_btn = ttk.Button(button_frame, text="Stop swarm", command=stop_swarm) +stop_all_btn.pack(side=RIGHT, padx=5, pady=5) + +send_animation_btn = ttk.Button(button_frame, text="Send animations", command=send_animations) +send_animation_btn.pack(side=RIGHT, padx=5, pady=5) + +send_starttime_btn = ttk.Button(button_frame, text="Start animation after...", command=send_starttime) +send_starttime_btn.pack(side=RIGHT, padx=5, pady=5) + + +def gui_update(): + time.sleep(0.1) + + +# reading config +config = configparser.ConfigParser() +config.read("server_config.ini") + +port = int(config['SERVER']['port']) +BUFFER_SIZE = int(config['SERVER']['buffer_size']) +NTP_HOST = config['NTP']['host'] +NTP_PORT = int(config['NTP']['port']) + + +ServerSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # socket.socket() # +ServerSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) +host = socket.gethostname() +ip = socket.gethostbyname_ex(host)[-1] + +print('Server started on', host, ip, ":", port) +#print('Now:', time.ctime(get_ntp_time(NTP_HOST, NTP_PORT))) +print('Waiting for clients...') +ServerSocket.bind((ip[-1], port)) + +autoconnect_thread = threading.Thread(target=auto_connect) +autoconnect_thread.daemon = True +autoconnect_thread.start() + + +if __name__ == '__main__': + try: + mainloop() + except KeyboardInterrupt: + print("Stopping server by keyboard interrupt") + finally: + ServerSocket.close() + print("Server shutdown") diff --git a/Server/back_1_rc.py b/Server/back_1_rc.py deleted file mode 100644 index e23970e..0000000 --- a/Server/back_1_rc.py +++ /dev/null @@ -1,73 +0,0 @@ -# -*- coding: utf-8 -*- - -# Resource object code -# -# Created by: The Resource Compiler for PyQt5 (Qt v5.11.2) -# -# WARNING! All changes made in this file will be lost! - -from PyQt5 import QtCore - -qt_resource_data = b"\ -\x00\x00\x01\x01\ -\x00\ -\x00\x11\x27\x78\x9c\xeb\x0c\xf0\x73\xe7\xe5\x92\xe2\x62\x60\x60\ -\xe0\xf5\xf4\x70\x09\x62\x60\x60\x05\x32\x99\x2e\x70\x30\x01\x29\ -\x07\x79\x2f\x46\x20\xc5\x58\x1c\xe4\xee\xc4\xb0\xee\x9c\xcc\x4b\ -\x20\x87\x25\xdd\xd1\xd7\x91\x81\x61\x63\x3f\xf7\x9f\x44\x90\x52\ -\xce\x02\x8f\xc8\x62\x06\x06\xbe\xc3\x20\xcc\x78\x3c\x7f\x45\x0a\ -\x03\x83\xc0\x1e\x4f\x17\xc7\x90\x8a\xb8\xb7\xd7\x37\x0a\x1e\x32\ -\x60\x60\x71\x74\xe4\xcf\x73\xef\xf4\x2a\x4f\x2c\x5a\xd4\xc2\xa4\ -\xf0\xa0\x6c\xf2\x7c\xfd\x87\x71\xdf\x6b\xf9\x19\x7e\x74\xee\xfd\ -\x3e\xe7\xf3\x1c\xff\xec\xb5\xaf\x77\x9d\x63\x64\xf8\xd1\xf4\x3d\ -\x12\x68\xe4\x8f\x6c\x26\x09\x06\x86\x06\x16\x46\x1e\xa0\x13\x9a\ -\x18\xd8\x18\x18\x14\x1c\x19\x98\x19\x18\x26\x28\x34\x00\x9d\xe3\ -\x21\x70\x00\xa8\x46\x85\x23\x01\x48\x0a\xb1\x18\x80\x9c\x30\xaa\ -\x7c\x54\xf9\xa8\xf2\x51\xe5\xa3\xca\x47\x95\x8f\x2a\x1f\x55\x3e\ -\xaa\x7c\x54\xf9\xa8\xf2\x51\xe5\xa3\xca\x47\x95\x8f\x2a\x1f\x55\ -\x4e\xbc\x72\x96\x9e\x8f\x0c\x2f\xa5\x79\x56\x38\x34\x3f\xa9\x06\ -\x72\x19\x3c\x5d\xfd\x5c\xd6\x39\x25\x34\x01\x00\xe9\xcb\xf7\x1d\ -\ -" - -qt_resource_name = b"\ -\x00\x04\ -\x00\x06\x87\x9b\ -\x00\x62\ -\x00\x61\x00\x63\x00\x6b\ -\x00\x08\ -\x07\x9e\x5a\x47\ -\x00\x62\ -\x00\x61\x00\x63\x00\x6b\x00\x2e\x00\x70\x00\x6e\x00\x67\ -" - -qt_resource_struct_v1 = b"\ -\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ -\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\ -\x00\x00\x00\x0e\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\ -" - -qt_resource_struct_v2 = b"\ -\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ -\x00\x00\x00\x00\x00\x00\x00\x00\ -\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\ -\x00\x00\x00\x00\x00\x00\x00\x00\ -\x00\x00\x00\x0e\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\ -\x00\x00\x01\x64\x8d\x7d\xe9\xe9\ -" - -qt_version = [int(v) for v in QtCore.qVersion().split('.')] -if qt_version < [5, 8, 0]: - rcc_version = 1 - qt_resource_struct = qt_resource_struct_v1 -else: - rcc_version = 2 - qt_resource_struct = qt_resource_struct_v2 - -def qInitResources(): - QtCore.qRegisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data) - -def qCleanupResources(): - QtCore.qUnregisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data) - -qInitResources() diff --git a/Server/gui/back.png b/Server/gui/back.png deleted file mode 100755 index 0a306ec..0000000 Binary files a/Server/gui/back.png and /dev/null differ diff --git a/Server/gui/back_1.qrc b/Server/gui/back_1.qrc deleted file mode 100755 index cbabc36..0000000 --- a/Server/gui/back_1.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - back.png - - diff --git a/Server/gui/gui.ui b/Server/gui/gui.ui deleted file mode 100755 index 1d1ea3d..0000000 --- a/Server/gui/gui.ui +++ /dev/null @@ -1,477 +0,0 @@ - - - MainWindow - - - - 0 - 0 - 1280 - 720 - - - - - 1280 - 720 - - - - - 1280 - 720 - - - - Drone Swarm - - - - - - 760 - 70 - 100 - 40 - - - - Take off all - - - - - - 890 - 70 - 91 - 40 - - - - Land all - - - - - - 1010 - 70 - 101 - 40 - - - - background-color: red - - - - Disarm all - - - - - - 760 - 150 - 100 - 40 - - - - Take off n - - - - - - 890 - 150 - 91 - 40 - - - - - - - Land n - - - - - - 1010 - 150 - 101 - 40 - - - - background-color: red - - - - Disarm n - - - - - - 790 - 120 - 50 - 22 - - - - - - - 910 - 120 - 50 - 22 - - - - - - - 1040 - 120 - 50 - 22 - - - - - - - 840 - 20 - 200 - 20 - - - - <html><head/><body><p><span style=" font-size:12pt; color:#c8c8c8;">Control console</span></p></body></html> - - - Qt::AlignCenter - - - - - - 1140 - 60 - 100 - 61 - - - - - - - Turn on Leds - - - - - - 1140 - 140 - 100 - 61 - - - - Turn off Leds - - - - - - 220 - 510 - 141 - 51 - - - - - - - Stop swarm - - - - - - 620 - 60 - 111 - 40 - - - - - - - Connect - - - - - - 260 - 80 - 50 - 20 - - - - - - - 240 - 50 - 100 - 20 - - - - <html><head/><body><p><span style=" font-size:9pt;">Swarm Size</span></p></body></html> - - - Qt::AlignCenter - - - - - - 840 - 260 - 200 - 20 - - - - <html><head/><body><p><span style=" font-size:12pt; color:#c8c8c8;">Send command</span></p></body></html> - - - Qt::AlignCenter - - - - - - 640 - 290 - 591 - 271 - - - - background-color: rgb(1, 36, 86) - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Noto Sans'; font-size:9pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:7.8pt; color:#ffffff;">...</span></p></body></html> - - - - - - 220 - 300 - 141 - 51 - - - - - - - Show 3d scene - - - - - - 220 - 370 - 141 - 51 - - - - - - - Upload animation - - - - - - 220 - 160 - 131 - 41 - - - - color: red - - - - - <html><head/><body><p><span style=" font-size:12pt;">Disconnect</span></p></body></html> - - - Qt::AlignCenter - - - - - - 230 - 140 - 111 - 20 - - - - Statement swarm - - - Qt::AlignCenter - - - - - - 220 - 440 - 141 - 51 - - - - - - - Start animation - - - - - - 0 - -1 - 1280 - 701 - - - - <html><head/><body><p><img src=":/back/back.png"/></p></body></html> - - - - - - 620 - 110 - 111 - 40 - - - - - - - Safty check - - - - - - 620 - 160 - 111 - 40 - - - - - - - Synchronize - - - - - - 220 - 200 - 141 - 51 - - - - color:rgb(30, 30, 30) - - - <html><head/><body><p align="center"><span style=" font-size:16pt;"/></p></body></html> - - - back_label - take_off_button - land_all_button - disarm_all_button - take_off_n_button - land_n_button - disarm_n_button - take_off_spinBox - land_spinBox - disarm_spinBox - control_console_label - turn_on_led_button - turn_off_led_button - stop_swarm_but - connect_button - swarm_size_spinBox - swarm_size_label - send_command_label - console_textEdit - show_3d_scene_button - upload_animation_button - state_label - statement_swarm_label - start_animation_button - safty_button - synch_button - time_to_start_label - - - - - 0 - 0 - 1280 - 23 - - - - - - - - - - diff --git a/Server/gui/telem.qrc b/Server/gui/telem.qrc deleted file mode 100755 index 5a64fa3..0000000 --- a/Server/gui/telem.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - telem_bakground.png - - diff --git a/Server/gui/telem_bakground.png b/Server/gui/telem_bakground.png deleted file mode 100755 index 31e7852..0000000 Binary files a/Server/gui/telem_bakground.png and /dev/null differ diff --git a/Server/gui/telemetry.ui b/Server/gui/telemetry.ui deleted file mode 100755 index 496691c..0000000 --- a/Server/gui/telemetry.ui +++ /dev/null @@ -1,536 +0,0 @@ - - - Dialog - - - - 0 - 0 - 550 - 240 - - - - - 550 - 240 - - - - - 550 - 240 - - - - Telemetry - - - - - 80 - 20 - 91 - 20 - - - - - 11 - - - - Copter - - - Qt::AlignCenter - - - - - - 10 - 10 - 93 - 41 - - - - Go - - - - - - 160 - 20 - 42 - 22 - - - - - - - 10 - 100 - 21 - 16 - - - - <html><head/><body><p><span style=" color:#c8c8c8;">x=</span></p></body></html> - - - Qt::AlignCenter - - - - - - 10 - 150 - 21 - 16 - - - - <html><head/><body><p><span style=" color:#c8c8c8;">y=</span></p></body></html> - - - Qt::AlignCenter - - - - - - 10 - 200 - 21 - 16 - - - - <html><head/><body><p><span style=" color:#c8c8c8;">z=</span></p></body></html> - - - Qt::AlignCenter - - - - - - 40 - 200 - 51 - 16 - - - - <html><head/><body><p><span style=" color:#c8c8c8;">0.000</span></p></body></html> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - 40 - 100 - 51 - 16 - - - - <html><head/><body><p><span style=" color:#c8c8c8;">0.000</span></p></body></html> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - 40 - 150 - 51 - 16 - - - - <html><head/><body><p><span style=" color:#c8c8c8;">0.000</span></p></body></html> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - 470 - 130 - 71 - 16 - - - - <html><head/><body><p><span style=" color:#c8c8c8;">MANUALE</span></p></body></html> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - 470 - 100 - 71 - 16 - - - - <html><head/><body><p><span style=" color:#c8c8c8;">False</span></p></body></html> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - 400 - 170 - 61 - 16 - - - - <html><head/><body><p><span style=" color:#c8c8c8;">farme id=</span><br/></p></body></html> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - 400 - 100 - 51 - 16 - - - - <html><head/><body><p><span style=" color:#c8c8c8;">armed=</span></p></body></html> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - 470 - 170 - 71 - 16 - - - - <html><head/><body><p><span style=" color:#c8c8c8;">aruco_map</span></p></body></html> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - 400 - 130 - 51 - 16 - - - - <html><head/><body><p><span style=" color:#c8c8c8;">mode=</span></p></body></html> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - 470 - 200 - 71 - 16 - - - - <html><head/><body><p><span style=" color:#c8c8c8;">0.000</span></p></body></html> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - 400 - 200 - 51 - 16 - - - - <html><head/><body><p><span style=" color:#c8c8c8;">voltage=</span></p></body></html> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - 190 - 200 - 61 - 16 - - - - <html><head/><body><p><span style=" color:#c8c8c8;">0.000</span></p></body></html> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - 140 - 100 - 31 - 16 - - - - <html><head/><body><p><span style=" color:#c8c8c8;">yaw=</span></p></body></html> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - 140 - 150 - 41 - 16 - - - - <html><head/><body><p><span style=" color:#c8c8c8;">pitch=</span></p></body></html> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - 140 - 200 - 31 - 16 - - - - <html><head/><body><p><span style=" color:#c8c8c8;">roll=</span></p></body></html> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - 190 - 150 - 61 - 16 - - - - <html><head/><body><p><span style=" color:#c8c8c8;">0.000</span></p></body></html> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - 190 - 100 - 61 - 16 - - - - <html><head/><body><p><span style=" color:#c8c8c8;">0.000</span></p></body></html> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - 270 - 150 - 31 - 16 - - - - <html><head/><body><p><span style=" color:#c8c8c8;">vy=</span></p></body></html> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - 320 - 100 - 61 - 16 - - - - <html><head/><body><p><span style=" color:#c8c8c8;">0.000</span></p></body></html> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - 270 - 200 - 31 - 16 - - - - <html><head/><body><p><span style=" color:#c8c8c8;">vz=</span></p></body></html> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - 320 - 150 - 61 - 16 - - - - <html><head/><body><p><span style=" color:#c8c8c8;">0.000</span></p></body></html> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - 320 - 200 - 61 - 16 - - - - <html><head/><body><p><span style=" color:#c8c8c8;">0.000</span></p></body></html> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - 270 - 100 - 31 - 16 - - - - <html><head/><body><p><span style=" color:#c8c8c8;">vx=</span></p></body></html> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - 0 - 0 - 551 - 241 - - - - <html><head/><body><p><img src=":/telem/telem_bakground.png"/></p></body></html> - - - back - copter_text - go_pushButton - number_spinBox - x_1 - y_1 - z_1 - z_2 - x_2 - y_2 - mode_2 - armed_2 - frame_id_1 - armed_1 - frame_id_2 - mode_1 - voltage_2 - voltage_1 - roll_2 - yaw_1 - pitch_1 - roll_1 - pitch_2 - yaw2 - vy_1 - vx_2 - vz_1 - vy_2 - vz_2 - vx_1 - - - - - - diff --git a/Server/gui_telem.py b/Server/gui_telem.py deleted file mode 100644 index a38ded1..0000000 --- a/Server/gui_telem.py +++ /dev/null @@ -1,214 +0,0 @@ -# -*- coding: utf-8 -*- - -# Form implementation generated from reading ui file 'telemetry.ui' -# -# Created by: PyQt5 UI code generator 5.11.3 -# -# WARNING! All changes made in this file will be lost! - -from PyQt5 import QtCore, QtGui, QtWidgets - -class Ui_Dialog(object): - def setupUi(self, Dialog): - Dialog.setObjectName("Dialog") - Dialog.resize(550, 240) - Dialog.setMinimumSize(QtCore.QSize(550, 240)) - Dialog.setMaximumSize(QtCore.QSize(550, 240)) - self.copter_text = QtWidgets.QLabel(Dialog) - self.copter_text.setGeometry(QtCore.QRect(80, 20, 91, 20)) - font = QtGui.QFont() - font.setPointSize(11) - self.copter_text.setFont(font) - self.copter_text.setAlignment(QtCore.Qt.AlignCenter) - self.copter_text.setObjectName("copter_text") - self.go_pushButton = QtWidgets.QPushButton(Dialog) - self.go_pushButton.setGeometry(QtCore.QRect(10, 10, 93, 41)) - self.go_pushButton.setObjectName("go_pushButton") - self.number_spinBox = QtWidgets.QSpinBox(Dialog) - self.number_spinBox.setGeometry(QtCore.QRect(160, 20, 42, 22)) - self.number_spinBox.setObjectName("number_spinBox") - self.x_1 = QtWidgets.QLabel(Dialog) - self.x_1.setGeometry(QtCore.QRect(10, 100, 21, 16)) - self.x_1.setAlignment(QtCore.Qt.AlignCenter) - self.x_1.setObjectName("x_1") - self.y_1 = QtWidgets.QLabel(Dialog) - self.y_1.setGeometry(QtCore.QRect(10, 150, 21, 16)) - self.y_1.setAlignment(QtCore.Qt.AlignCenter) - self.y_1.setObjectName("y_1") - self.z_1 = QtWidgets.QLabel(Dialog) - self.z_1.setGeometry(QtCore.QRect(10, 200, 21, 16)) - self.z_1.setAlignment(QtCore.Qt.AlignCenter) - self.z_1.setObjectName("z_1") - self.z_2 = QtWidgets.QLabel(Dialog) - self.z_2.setGeometry(QtCore.QRect(40, 200, 51, 16)) - self.z_2.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.z_2.setObjectName("z_2") - self.x_2 = QtWidgets.QLabel(Dialog) - self.x_2.setGeometry(QtCore.QRect(40, 100, 51, 16)) - self.x_2.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.x_2.setObjectName("x_2") - self.y_2 = QtWidgets.QLabel(Dialog) - self.y_2.setGeometry(QtCore.QRect(40, 150, 51, 16)) - self.y_2.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.y_2.setObjectName("y_2") - self.mode_2 = QtWidgets.QLabel(Dialog) - self.mode_2.setGeometry(QtCore.QRect(470, 130, 71, 16)) - self.mode_2.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.mode_2.setObjectName("mode_2") - self.armed_2 = QtWidgets.QLabel(Dialog) - self.armed_2.setGeometry(QtCore.QRect(470, 100, 71, 16)) - self.armed_2.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.armed_2.setObjectName("armed_2") - self.frame_id_1 = QtWidgets.QLabel(Dialog) - self.frame_id_1.setGeometry(QtCore.QRect(400, 170, 61, 16)) - self.frame_id_1.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.frame_id_1.setObjectName("frame_id_1") - self.armed_1 = QtWidgets.QLabel(Dialog) - self.armed_1.setGeometry(QtCore.QRect(400, 100, 51, 16)) - self.armed_1.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.armed_1.setObjectName("armed_1") - self.frame_id_2 = QtWidgets.QLabel(Dialog) - self.frame_id_2.setGeometry(QtCore.QRect(470, 170, 71, 16)) - self.frame_id_2.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.frame_id_2.setObjectName("frame_id_2") - self.mode_1 = QtWidgets.QLabel(Dialog) - self.mode_1.setGeometry(QtCore.QRect(400, 130, 51, 16)) - self.mode_1.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.mode_1.setObjectName("mode_1") - self.voltage_2 = QtWidgets.QLabel(Dialog) - self.voltage_2.setGeometry(QtCore.QRect(470, 200, 71, 16)) - self.voltage_2.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.voltage_2.setObjectName("voltage_2") - self.voltage_1 = QtWidgets.QLabel(Dialog) - self.voltage_1.setGeometry(QtCore.QRect(400, 200, 51, 16)) - self.voltage_1.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.voltage_1.setObjectName("voltage_1") - self.roll_2 = QtWidgets.QLabel(Dialog) - self.roll_2.setGeometry(QtCore.QRect(190, 200, 61, 16)) - self.roll_2.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.roll_2.setObjectName("roll_2") - self.yaw_1 = QtWidgets.QLabel(Dialog) - self.yaw_1.setGeometry(QtCore.QRect(140, 100, 31, 16)) - self.yaw_1.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.yaw_1.setObjectName("yaw_1") - self.pitch_1 = QtWidgets.QLabel(Dialog) - self.pitch_1.setGeometry(QtCore.QRect(140, 150, 41, 16)) - self.pitch_1.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.pitch_1.setObjectName("pitch_1") - self.roll_1 = QtWidgets.QLabel(Dialog) - self.roll_1.setGeometry(QtCore.QRect(140, 200, 31, 16)) - self.roll_1.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.roll_1.setObjectName("roll_1") - self.pitch_2 = QtWidgets.QLabel(Dialog) - self.pitch_2.setGeometry(QtCore.QRect(190, 150, 61, 16)) - self.pitch_2.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.pitch_2.setObjectName("pitch_2") - self.yaw2 = QtWidgets.QLabel(Dialog) - self.yaw2.setGeometry(QtCore.QRect(190, 100, 61, 16)) - self.yaw2.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.yaw2.setObjectName("yaw2") - self.vy_1 = QtWidgets.QLabel(Dialog) - self.vy_1.setGeometry(QtCore.QRect(270, 150, 31, 16)) - self.vy_1.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.vy_1.setObjectName("vy_1") - self.vx_2 = QtWidgets.QLabel(Dialog) - self.vx_2.setGeometry(QtCore.QRect(320, 100, 61, 16)) - self.vx_2.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.vx_2.setObjectName("vx_2") - self.vz_1 = QtWidgets.QLabel(Dialog) - self.vz_1.setGeometry(QtCore.QRect(270, 200, 31, 16)) - self.vz_1.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.vz_1.setObjectName("vz_1") - self.vy_2 = QtWidgets.QLabel(Dialog) - self.vy_2.setGeometry(QtCore.QRect(320, 150, 61, 16)) - self.vy_2.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.vy_2.setObjectName("vy_2") - self.vz_2 = QtWidgets.QLabel(Dialog) - self.vz_2.setGeometry(QtCore.QRect(320, 200, 61, 16)) - self.vz_2.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.vz_2.setObjectName("vz_2") - self.vx_1 = QtWidgets.QLabel(Dialog) - self.vx_1.setGeometry(QtCore.QRect(270, 100, 31, 16)) - self.vx_1.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.vx_1.setObjectName("vx_1") - self.back = QtWidgets.QLabel(Dialog) - self.back.setGeometry(QtCore.QRect(0, 0, 551, 241)) - self.back.setObjectName("back") - self.back.raise_() - self.copter_text.raise_() - self.go_pushButton.raise_() - self.number_spinBox.raise_() - self.x_1.raise_() - self.y_1.raise_() - self.z_1.raise_() - self.z_2.raise_() - self.x_2.raise_() - self.y_2.raise_() - self.mode_2.raise_() - self.armed_2.raise_() - self.frame_id_1.raise_() - self.armed_1.raise_() - self.frame_id_2.raise_() - self.mode_1.raise_() - self.voltage_2.raise_() - self.voltage_1.raise_() - self.roll_2.raise_() - self.yaw_1.raise_() - self.pitch_1.raise_() - self.roll_1.raise_() - self.pitch_2.raise_() - self.yaw2.raise_() - self.vy_1.raise_() - self.vx_2.raise_() - self.vz_1.raise_() - self.vy_2.raise_() - self.vz_2.raise_() - self.vx_1.raise_() - - self.retranslateUi(Dialog) - QtCore.QMetaObject.connectSlotsByName(Dialog) - - def retranslateUi(self, Dialog): - _translate = QtCore.QCoreApplication.translate - Dialog.setWindowTitle(_translate("Dialog", "Telemetry")) - self.copter_text.setText(_translate("Dialog", "Copter")) - self.go_pushButton.setText(_translate("Dialog", "Go")) - self.x_1.setText(_translate("Dialog", "

x=

")) - self.y_1.setText(_translate("Dialog", "

y=

")) - self.z_1.setText(_translate("Dialog", "

z=

")) - self.z_2.setText(_translate("Dialog", "

0.000

")) - self.x_2.setText(_translate("Dialog", "

0.000

")) - self.y_2.setText(_translate("Dialog", "

0.000

")) - self.mode_2.setText(_translate("Dialog", "

MANUALE

")) - self.armed_2.setText(_translate("Dialog", "

False

")) - self.frame_id_1.setText(_translate("Dialog", "

farme id=

")) - self.armed_1.setText(_translate("Dialog", "

armed=

")) - self.frame_id_2.setText(_translate("Dialog", "

aruco_map

")) - self.mode_1.setText(_translate("Dialog", "

mode=

")) - self.voltage_2.setText(_translate("Dialog", "

0.000

")) - self.voltage_1.setText(_translate("Dialog", "

voltage=

")) - self.roll_2.setText(_translate("Dialog", "

0.000

")) - self.yaw_1.setText(_translate("Dialog", "

yaw=

")) - self.pitch_1.setText(_translate("Dialog", "

pitch=

")) - self.roll_1.setText(_translate("Dialog", "

roll=

")) - self.pitch_2.setText(_translate("Dialog", "

0.000

")) - self.yaw2.setText(_translate("Dialog", "

0.000

")) - self.vy_1.setText(_translate("Dialog", "

vy=

")) - self.vx_2.setText(_translate("Dialog", "

0.000

")) - self.vz_1.setText(_translate("Dialog", "

vz=

")) - self.vy_2.setText(_translate("Dialog", "

0.000

")) - self.vz_2.setText(_translate("Dialog", "

0.000

")) - self.vx_1.setText(_translate("Dialog", "

vx=

")) - self.back.setText(_translate("Dialog", "

")) - -import telem_rc - -if __name__ == "__main__": - import sys - app = QtWidgets.QApplication(sys.argv) - Dialog = QtWidgets.QDialog() - ui = Ui_Dialog() - ui.setupUi(Dialog) - Dialog.show() - sys.exit(app.exec_()) - diff --git a/Server/main_gui.py b/Server/main_gui.py deleted file mode 100644 index 75fc44b..0000000 --- a/Server/main_gui.py +++ /dev/null @@ -1,203 +0,0 @@ -# -*- coding: utf-8 -*- - -# Form implementation generated from reading ui file 'gui.ui' -# -# Created by: PyQt5 UI code generator 5.11.3 -# -# WARNING! All changes made in this file will be lost! - -from PyQt5 import QtCore, QtGui, QtWidgets - -class Ui_MainWindow(object): - def setupUi(self, MainWindow): - MainWindow.setObjectName("MainWindow") - MainWindow.resize(1280, 720) - MainWindow.setMinimumSize(QtCore.QSize(1280, 720)) - MainWindow.setMaximumSize(QtCore.QSize(1280, 720)) - self.centralwidget = QtWidgets.QWidget(MainWindow) - self.centralwidget.setObjectName("centralwidget") - self.take_off_button = QtWidgets.QPushButton(self.centralwidget) - self.take_off_button.setGeometry(QtCore.QRect(760, 70, 100, 40)) - self.take_off_button.setObjectName("take_off_button") - self.land_all_button = QtWidgets.QPushButton(self.centralwidget) - self.land_all_button.setGeometry(QtCore.QRect(890, 70, 91, 40)) - self.land_all_button.setObjectName("land_all_button") - self.disarm_all_button = QtWidgets.QPushButton(self.centralwidget) - self.disarm_all_button.setGeometry(QtCore.QRect(1010, 70, 101, 40)) - self.disarm_all_button.setStyleSheet("background-color: red\n" -"") - self.disarm_all_button.setObjectName("disarm_all_button") - self.take_off_n_button = QtWidgets.QPushButton(self.centralwidget) - self.take_off_n_button.setGeometry(QtCore.QRect(760, 150, 100, 40)) - self.take_off_n_button.setObjectName("take_off_n_button") - self.land_n_button = QtWidgets.QPushButton(self.centralwidget) - self.land_n_button.setGeometry(QtCore.QRect(890, 150, 91, 40)) - self.land_n_button.setStyleSheet("") - self.land_n_button.setObjectName("land_n_button") - self.disarm_n_button = QtWidgets.QPushButton(self.centralwidget) - self.disarm_n_button.setGeometry(QtCore.QRect(1010, 150, 101, 40)) - self.disarm_n_button.setStyleSheet("background-color: red\n" -"") - self.disarm_n_button.setObjectName("disarm_n_button") - self.take_off_spinBox = QtWidgets.QSpinBox(self.centralwidget) - self.take_off_spinBox.setGeometry(QtCore.QRect(790, 120, 50, 22)) - self.take_off_spinBox.setObjectName("take_off_spinBox") - self.land_spinBox = QtWidgets.QSpinBox(self.centralwidget) - self.land_spinBox.setGeometry(QtCore.QRect(910, 120, 50, 22)) - self.land_spinBox.setObjectName("land_spinBox") - self.disarm_spinBox = QtWidgets.QSpinBox(self.centralwidget) - self.disarm_spinBox.setGeometry(QtCore.QRect(1040, 120, 50, 22)) - self.disarm_spinBox.setObjectName("disarm_spinBox") - self.control_console_label = QtWidgets.QLabel(self.centralwidget) - self.control_console_label.setGeometry(QtCore.QRect(840, 20, 200, 20)) - self.control_console_label.setAlignment(QtCore.Qt.AlignCenter) - self.control_console_label.setObjectName("control_console_label") - self.turn_on_led_button = QtWidgets.QPushButton(self.centralwidget) - self.turn_on_led_button.setGeometry(QtCore.QRect(1140, 60, 100, 61)) - self.turn_on_led_button.setStyleSheet("") - self.turn_on_led_button.setObjectName("turn_on_led_button") - self.turn_off_led_button = QtWidgets.QPushButton(self.centralwidget) - self.turn_off_led_button.setGeometry(QtCore.QRect(1140, 140, 100, 61)) - self.turn_off_led_button.setObjectName("turn_off_led_button") - self.stop_swarm_but = QtWidgets.QPushButton(self.centralwidget) - self.stop_swarm_but.setGeometry(QtCore.QRect(220, 510, 141, 51)) - self.stop_swarm_but.setStyleSheet("") - self.stop_swarm_but.setObjectName("stop_swarm_but") - self.connect_button = QtWidgets.QPushButton(self.centralwidget) - self.connect_button.setGeometry(QtCore.QRect(620, 60, 111, 40)) - self.connect_button.setStyleSheet("") - self.connect_button.setObjectName("connect_button") - self.swarm_size_spinBox = QtWidgets.QSpinBox(self.centralwidget) - self.swarm_size_spinBox.setGeometry(QtCore.QRect(260, 80, 50, 20)) - self.swarm_size_spinBox.setObjectName("swarm_size_spinBox") - self.swarm_size_label = QtWidgets.QLabel(self.centralwidget) - self.swarm_size_label.setGeometry(QtCore.QRect(240, 50, 100, 20)) - self.swarm_size_label.setAlignment(QtCore.Qt.AlignCenter) - self.swarm_size_label.setObjectName("swarm_size_label") - self.send_command_label = QtWidgets.QLabel(self.centralwidget) - self.send_command_label.setGeometry(QtCore.QRect(840, 260, 200, 20)) - self.send_command_label.setAlignment(QtCore.Qt.AlignCenter) - self.send_command_label.setObjectName("send_command_label") - self.console_textEdit = QtWidgets.QTextEdit(self.centralwidget) - self.console_textEdit.setGeometry(QtCore.QRect(640, 290, 591, 271)) - self.console_textEdit.setStyleSheet("background-color: rgb(1, 36, 86)") - self.console_textEdit.setObjectName("console_textEdit") - self.show_3d_scene_button = QtWidgets.QPushButton(self.centralwidget) - self.show_3d_scene_button.setGeometry(QtCore.QRect(220, 300, 141, 51)) - self.show_3d_scene_button.setStyleSheet("") - self.show_3d_scene_button.setObjectName("show_3d_scene_button") - self.upload_animation_button = QtWidgets.QPushButton(self.centralwidget) - self.upload_animation_button.setGeometry(QtCore.QRect(220, 370, 141, 51)) - self.upload_animation_button.setStyleSheet("") - self.upload_animation_button.setObjectName("upload_animation_button") - self.state_label = QtWidgets.QLabel(self.centralwidget) - self.state_label.setGeometry(QtCore.QRect(220, 160, 131, 41)) - self.state_label.setStyleSheet("color: red\n" -"\n" -"") - self.state_label.setAlignment(QtCore.Qt.AlignCenter) - self.state_label.setObjectName("state_label") - self.statement_swarm_label = QtWidgets.QLabel(self.centralwidget) - self.statement_swarm_label.setGeometry(QtCore.QRect(230, 140, 111, 20)) - self.statement_swarm_label.setAlignment(QtCore.Qt.AlignCenter) - self.statement_swarm_label.setObjectName("statement_swarm_label") - self.start_animation_button = QtWidgets.QPushButton(self.centralwidget) - self.start_animation_button.setGeometry(QtCore.QRect(220, 440, 141, 51)) - self.start_animation_button.setStyleSheet("") - self.start_animation_button.setObjectName("start_animation_button") - self.back_label = QtWidgets.QLabel(self.centralwidget) - self.back_label.setGeometry(QtCore.QRect(0, -1, 1280, 701)) - self.back_label.setObjectName("back_label") - self.safty_button = QtWidgets.QPushButton(self.centralwidget) - self.safty_button.setGeometry(QtCore.QRect(620, 110, 111, 40)) - self.safty_button.setStyleSheet("") - self.safty_button.setObjectName("safty_button") - self.synch_button = QtWidgets.QPushButton(self.centralwidget) - self.synch_button.setGeometry(QtCore.QRect(620, 160, 111, 40)) - self.synch_button.setStyleSheet("") - self.synch_button.setObjectName("synch_button") - self.time_to_start_label = QtWidgets.QLabel(self.centralwidget) - self.time_to_start_label.setGeometry(QtCore.QRect(220, 200, 141, 51)) - self.time_to_start_label.setStyleSheet("color:rgb(30, 30, 30)") - self.time_to_start_label.setObjectName("time_to_start_label") - self.back_label.raise_() - self.take_off_button.raise_() - self.land_all_button.raise_() - self.disarm_all_button.raise_() - self.take_off_n_button.raise_() - self.land_n_button.raise_() - self.disarm_n_button.raise_() - self.take_off_spinBox.raise_() - self.land_spinBox.raise_() - self.disarm_spinBox.raise_() - self.control_console_label.raise_() - self.turn_on_led_button.raise_() - self.turn_off_led_button.raise_() - self.stop_swarm_but.raise_() - self.connect_button.raise_() - self.swarm_size_spinBox.raise_() - self.swarm_size_label.raise_() - self.send_command_label.raise_() - self.console_textEdit.raise_() - self.show_3d_scene_button.raise_() - self.upload_animation_button.raise_() - self.state_label.raise_() - self.statement_swarm_label.raise_() - self.start_animation_button.raise_() - self.safty_button.raise_() - self.synch_button.raise_() - self.time_to_start_label.raise_() - MainWindow.setCentralWidget(self.centralwidget) - self.menubar = QtWidgets.QMenuBar(MainWindow) - self.menubar.setGeometry(QtCore.QRect(0, 0, 1280, 23)) - self.menubar.setObjectName("menubar") - MainWindow.setMenuBar(self.menubar) - self.statusbar = QtWidgets.QStatusBar(MainWindow) - self.statusbar.setObjectName("statusbar") - MainWindow.setStatusBar(self.statusbar) - - self.retranslateUi(MainWindow) - QtCore.QMetaObject.connectSlotsByName(MainWindow) - - def retranslateUi(self, MainWindow): - _translate = QtCore.QCoreApplication.translate - MainWindow.setWindowTitle(_translate("MainWindow", "Drone Swarm")) - self.take_off_button.setText(_translate("MainWindow", "Take off all")) - self.land_all_button.setText(_translate("MainWindow", "Land all")) - self.disarm_all_button.setText(_translate("MainWindow", "Disarm all")) - self.take_off_n_button.setText(_translate("MainWindow", "Take off n")) - self.land_n_button.setText(_translate("MainWindow", "Land n")) - self.disarm_n_button.setText(_translate("MainWindow", "Disarm n")) - self.control_console_label.setText(_translate("MainWindow", "

Control console

")) - self.turn_on_led_button.setText(_translate("MainWindow", "Turn on Leds")) - self.turn_off_led_button.setText(_translate("MainWindow", "Turn off Leds")) - self.stop_swarm_but.setText(_translate("MainWindow", "Stop swarm")) - self.connect_button.setText(_translate("MainWindow", "Connect")) - self.swarm_size_label.setText(_translate("MainWindow", "

Swarm Size

")) - self.send_command_label.setText(_translate("MainWindow", "

Send command

")) - self.console_textEdit.setHtml(_translate("MainWindow", "\n" -"\n" -"

...

")) - self.show_3d_scene_button.setText(_translate("MainWindow", "Show 3d scene")) - self.upload_animation_button.setText(_translate("MainWindow", "Upload animation")) - self.state_label.setText(_translate("MainWindow", "

Disconnect

")) - self.statement_swarm_label.setText(_translate("MainWindow", "Statement swarm")) - self.start_animation_button.setText(_translate("MainWindow", "Start animation")) - self.back_label.setText(_translate("MainWindow", "

")) - self.safty_button.setText(_translate("MainWindow", "Safty check")) - self.synch_button.setText(_translate("MainWindow", "Synchronize")) - self.time_to_start_label.setText(_translate("MainWindow", "

")) - -import back_1_rc - -if __name__ == "__main__": - import sys - app = QtWidgets.QApplication(sys.argv) - MainWindow = QtWidgets.QMainWindow() - ui = Ui_MainWindow() - ui.setupUi(MainWindow) - MainWindow.show() - sys.exit(app.exec_()) - diff --git a/Server/server_config.ini b/Server/server_config.ini new file mode 100644 index 0000000..061617e --- /dev/null +++ b/Server/server_config.ini @@ -0,0 +1,11 @@ +[SERVER] +port = 25000 +buffer_size = 1024 + +[NTP] +host = ntp1.stratum2.ru +port = 123 +#pool.ntp.org + +[FILETRANSFER] +animation = animation.csv \ No newline at end of file diff --git a/Server/telem_rc.py b/Server/telem_rc.py deleted file mode 100644 index 1cc6cff..0000000 --- a/Server/telem_rc.py +++ /dev/null @@ -1,72 +0,0 @@ -# -*- coding: utf-8 -*- - -# Resource object code -# -# Created by: The Resource Compiler for PyQt5 (Qt v5.11.2) -# -# WARNING! All changes made in this file will be lost! - -from PyQt5 import QtCore - -qt_resource_data = b"\ -\x00\x00\x00\xe4\ -\x00\ -\x00\x04\x03\x78\x9c\xeb\x0c\xf0\x73\xe7\xe5\x92\xe2\x62\x60\x60\ -\xe0\xf5\xf4\x70\x09\x62\x60\x60\x52\x03\xb2\x3f\x70\x30\x01\xc9\ -\xdd\x21\x16\x20\x09\xc6\xe2\x20\x77\x27\x86\x75\xe7\x64\x5e\x02\ -\x39\x2c\xe9\x8e\xbe\x8e\x0c\x0c\x1b\xfb\xb9\xff\x24\xb2\x02\xf9\ -\x9c\x05\x1e\x91\xc5\x0c\x0c\x7c\x87\x41\x98\xf1\x78\xfe\x8a\x14\ -\x06\x06\xe6\x19\x9e\x2e\x8e\x21\x15\x71\x6f\x6f\x6d\x14\x3c\xac\ -\x20\xc0\xe0\xf8\x44\x4b\x73\xa2\x5d\xc6\x99\xc6\x2b\x4c\xe9\x67\ -\x2b\xcc\x1f\x3e\xfe\xff\x40\x68\xdd\xde\xef\x0c\x0d\x9f\xed\xce\ -\x73\x33\xb4\x7b\xf2\x31\x08\x9e\x64\x54\x50\xb2\x64\x70\x51\x61\ -\x6f\xe8\x78\xc2\x20\x30\x51\x86\x41\x69\x12\xb3\x83\x4b\x11\x43\ -\x87\xc7\xa0\x96\x64\x00\x81\x07\x7b\xd7\x59\x3e\x37\x2e\xba\x17\ -\xf5\x5a\x6e\xcd\x5f\xde\x39\x8f\xdb\x75\xfe\xdb\xff\xb4\x63\x18\ -\x1c\x2e\x1c\x95\x1c\x95\x84\x4a\x1e\x91\x88\x2f\xac\xe3\xd3\xe2\ -\x4e\x09\x0d\x01\x25\x5b\x4f\x57\x3f\x97\x75\x4e\x09\x4d\x00\xf2\ -\xc3\x05\x01\ -" - -qt_resource_name = b"\ -\x00\x05\ -\x00\x7a\xc2\xbd\ -\x00\x74\ -\x00\x65\x00\x6c\x00\x65\x00\x6d\ -\x00\x13\ -\x08\x4f\x8b\x27\ -\x00\x74\ -\x00\x65\x00\x6c\x00\x65\x00\x6d\x00\x5f\x00\x62\x00\x61\x00\x6b\x00\x67\x00\x72\x00\x6f\x00\x75\x00\x6e\x00\x64\x00\x2e\x00\x70\ -\x00\x6e\x00\x67\ -" - -qt_resource_struct_v1 = b"\ -\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ -\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\ -\x00\x00\x00\x10\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\ -" - -qt_resource_struct_v2 = b"\ -\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ -\x00\x00\x00\x00\x00\x00\x00\x00\ -\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\ -\x00\x00\x00\x00\x00\x00\x00\x00\ -\x00\x00\x00\x10\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\ -\x00\x00\x01\x64\xac\x7c\x9c\xca\ -" - -qt_version = [int(v) for v in QtCore.qVersion().split('.')] -if qt_version < [5, 8, 0]: - rcc_version = 1 - qt_resource_struct = qt_resource_struct_v1 -else: - rcc_version = 2 - qt_resource_struct = qt_resource_struct_v2 - -def qInitResources(): - QtCore.qRegisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data) - -def qCleanupResources(): - QtCore.qUnregisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data) - -qInitResources()