Files

150 lines
5.5 KiB
Python

#!/usr/bin python3.5
"""
Main file used to launch the Rover Base Station
No other files should be used for launching this application.
"""
__author__ = "Corwin Perren"
__credits__ = [""]
__license__ = "GPL (GNU General Public License) 3.0"
__version__ = "0.1"
__maintainer__ = "Corwin Perren"
__email__ = "caperren@caperren.com"
__status__ = "Development"
#####################################
# Imports
#####################################
# Python native imports
import sys
from PyQt5 import QtWidgets, QtCore, QtGui, uic, QtWebEngine, QtQuick, QtQml
import signal
import logging
import time
# Custom Imports
from Framework.SettingsCore import Settings
from Framework.LoggingCore import Logger
from Interface.InterfaceCore import Interface
from Framework.XBOXControllerCore import XBOXController
from Framework.FreeSkyControllerCore import FreeSkyController
from Framework.MiniBoardIOCore import MiniboardIO
from Framework.MotionProcessorCore import MotionProcessor
from Framework.ReadUpdaterCore import ReadUpdater
from Framework.MapProcessorCore import MapProcessor
#####################################
# Global Variables
#####################################
UI_FILE_PATH = "Resources/new_ui_work_4-30-17/RoverBaseStation.ui"
#####################################
# Application Class Definition
#####################################
class ApplicationWindow(QtWidgets.QMainWindow):
connect_all_signals_to_slots_signal = QtCore.pyqtSignal()
start_all_threads = QtCore.pyqtSignal()
kill_threads_signal = QtCore.pyqtSignal()
def __init__(self, parent=None):
# noinspection PyArgumentList
super(ApplicationWindow, self).__init__(parent)
uic.loadUi(UI_FILE_PATH, self)
# ########## Class Variables ##########
self.num_threads_running = 0
self.threads = [] # type: [QtCore.QThread]
# ########## Instantiation of program classes ##########
# Settings class and version number set
self.settings_class = Settings(self)
self.settings = QtCore.QSettings()
self.settings.setValue("miscellaneous/version", __version__)
# Uncomment these lines to completely reset settings and quit, then re-comment and rerun program
# self.settings.clear()
# self.close()
# Set up the global logger instance
self.logger_class = Logger(console_output=True)
self.logger = logging.getLogger("RoverBaseStation")
# All interface elements
self.xbox_controller_class = XBOXController(self)
self.frsky_controller_class = FreeSkyController(self)
self.miniboard_class = MiniboardIO(self)
self.interface_class = Interface(self)
self.motion_processor_class = MotionProcessor(self)
self.read_updater = ReadUpdater(self)
self.map_processor = MapProcessor(self)
# ########## Add threads to list for easy access on program close ##########
self.threads.append(self.interface_class.live_logs_class)
self.threads.append(self.xbox_controller_class)
self.threads.append(self.frsky_controller_class)
self.threads.append(self.miniboard_class)
self.threads.append(self.motion_processor_class)
self.threads.append(self.read_updater)
self.threads.append(self.map_processor)
# ########## Setup signal/slot connections ##########
for thread in self.threads:
self.connect_all_signals_to_slots_signal.connect(thread.connect_signals_to_slots__slot)
self.connect_all_signals_to_slots_signal.emit()
# ########## Start all child threads ##########
for thread in self.threads:
self.start_all_threads.connect(thread.start)
self.start_all_threads.emit()
time.sleep(1)
# ########## Ensure all threads started properly ##########
for thread in self.threads:
if not thread.isRunning():
self.logger.error("Thread" + thread.__class__.__name__ + " failed to start! Exiting...")
for thread in self.threads:
thread.terminate()
self.close()
self.logger.info("All threads started successfully!")
def closeEvent(self, event):
# Tell all threads to die
self.kill_threads_signal.emit()
# Wait for all the threads to end properly
for thread in self.threads:
thread.wait()
# Print final log noting shutdown and shutdown the logger to flush to disk
self.logger.debug("########## Application Stopping ##########")
logging.shutdown()
# Accept the close event to properly close the program
event.accept()
#####################################
# Main Definition
#####################################
if __name__ == "__main__":
signal.signal(signal.SIGINT, signal.SIG_DFL) # This allows the keyboard interrupt kill to work properly
application = QtWidgets.QApplication(sys.argv) # Create the base qt gui application
app_window = ApplicationWindow() # Make a window in this application
app_window.setWindowTitle("Rover Base Station") # Sets the window title
# ##### Center the window on the screen #####
geometry = app_window.frameGeometry()
screen = QtWidgets.QApplication.desktop().screenNumber(QtWidgets.QApplication.desktop().cursor().pos())
centerPoint = QtWidgets.QApplication.desktop().screenGeometry(screen).center()
geometry.moveCenter(centerPoint)
app_window.move(geometry.topLeft())
app_window.show() # Show the window in the application
application.exec_() # Execute launching of the application