diff --git a/software/ros_packages/ground_station/src/Framework/MiscSystems/SSHConsoleCore.py b/software/ros_packages/ground_station/src/Framework/MiscSystems/SSHConsoleCore.py new file mode 100644 index 0000000..952f715 --- /dev/null +++ b/software/ros_packages/ground_station/src/Framework/MiscSystems/SSHConsoleCore.py @@ -0,0 +1,47 @@ +# coding=utf-8 +##################################### +# Imports +##################################### +# Python native imports +from PyQt5 import QtCore, QtWidgets +import logging +from time import time +import paramiko + +##################################### +# Global Variables +##################################### +ACCESS_POINT_IP = "192.168.1.20" # The channel only has to be set on the access point. The staion will adjust. +ACCESS_POINT_USER = "ubnt" +ACCESS_POINT_PASSWORD = "rover4lyfe^" # We don't care about this password, don't freak out. Wifi is open anyways... + + +##################################### +# UbiquitiRadioSettings Class Definition +##################################### +class SSHConsole(QtCore.QThread): + def __init__(self, shared_objects): + super(SSHConsole, self).__init__() + + # ########## Reference to class init variables ########## + self.shared_objects = shared_objects + self.left_screen = self.shared_objects["screens"]["left_screen"] + + self.ubiquiti_channel_spin_box = self.left_screen.ssh_console_widget # type: QtWidgets.QSpinBox + self.ubiquiti_channel_apply_button = self.left_screen.ubiquiti_channel_apply_button # type: QtWidgets.QPushButton + + # ########## Get the settings instance ########## + self.settings = QtCore.QSettings() + + # ########## Get the Pick And Plate instance of the logger ########## + self.logger = logging.getLogger("groundstation") + + # ########## Thread Flags ########## + self.run_thread_flag = True + + # ########## Class Variables ########## + + self.connect_signals_and_slots() + + def connect_signals_and_slots(self): + pass \ No newline at end of file diff --git a/software/ros_packages/ground_station/src/Framework/MiscSystems/__init__.py b/software/ros_packages/ground_station/src/Framework/MiscSystems/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/software/ros_packages/ground_station/src/Framework/StatusSystems/StatusCore.py b/software/ros_packages/ground_station/src/Framework/StatusSystems/StatusCore.py index 8f2a4a1..e572948 100644 --- a/software/ros_packages/ground_station/src/Framework/StatusSystems/StatusCore.py +++ b/software/ros_packages/ground_station/src/Framework/StatusSystems/StatusCore.py @@ -7,13 +7,14 @@ from PyQt5 import QtWidgets, QtCore, QtGui, uic from std_msgs.msg import Empty import PIL.Image from PIL.ImageQt import ImageQt +import time from std_msgs.msg import UInt16 + # import Timer REQUEST_UPDATE_TOPIC = "/rover_status/update_requested" - CAMERA_TOPIC_NAME = "/rover_status/camera_status" BOGIE_TOPIC_NAME = "/rover_status/bogie_status" FRSKY_TOPIC_NAME = "/rover_status/frsky_status" @@ -25,10 +26,14 @@ CO2_TOPIC_NAME = "/rover_control/tower/status/co2" COLOR_GREEN = "background-color: darkgreen; border: 1px solid black;" COLOR_ORANGE = "background-color: orange; border: 1px solid black;" +COLOR_YELLOW = "background-color: rgb(204,204,0); border: 1px solid black; color: black;" COLOR_RED = "background-color: darkred; border: 1px solid black;" GPS_BEST_CASE_ACCURACY = 3 +LOW_BATTERY_DIALOG_TIMEOUT = 120 +CRITICAL_BATTERY_DIALOG_TIMEOUT = 30 + class SensorCore(QtCore.QThread): # ########## create signals for slots ########## @@ -64,6 +69,9 @@ class SensorCore(QtCore.QThread): battery_voltage_update_ready__signal = QtCore.pyqtSignal(str) battery_voltage_stylesheet_change_ready__signal = QtCore.pyqtSignal(str) + show_battery_low__signal = QtCore.pyqtSignal() + show_battery_critical__signal = QtCore.pyqtSignal() + def __init__(self, shared_objects): super(SensorCore, self).__init__() @@ -108,7 +116,7 @@ class SensorCore(QtCore.QThread): self.co2_status = rospy.Subscriber(CO2_TOPIC_NAME, UInt16, self.__co2_callback) self.camera_msg = CameraStatuses() - self.bogie_msg = None # BogieStatuses() + self.bogie_msg = None # BogieStatuses() self.FrSky_msg = FrSkyStatus() self.GPS_msg = GPSInfo() self.jetson_msg = JetsonInfo() @@ -122,6 +130,28 @@ class SensorCore(QtCore.QThread): self.osurc_logo_pixmap = QtGui.QPixmap.fromImage(ImageQt(self.osurc_logo_pil)) self.osurc_logo_label.setPixmap(self.osurc_logo_pixmap) # Init should be in main thread, should be fine + self.low_battery_warning_dialog = QtWidgets.QMessageBox() + self.low_battery_warning_dialog.setIcon(QtWidgets.QMessageBox.Warning) + self.low_battery_warning_dialog.setText("\n\n\n\nRover battery low!\nReturn and charge soon to avoid battery damage!\n\n\n\n") + self.low_battery_warning_dialog.setWindowTitle("Low Battery") + self.low_battery_warning_dialog.setStandardButtons(QtWidgets.QMessageBox.Ok) + self.low_battery_warning_dialog.setWindowFlags( + QtCore.Qt.WindowStaysOnTopHint | QtCore.Qt.X11BypassWindowManagerHint | QtCore.Qt.WindowTitleHint | QtCore.Qt.WindowCloseButtonHint) + self.low_battery_warning_dialog.setStyleSheet(COLOR_YELLOW) + + self.critical_battery_warning_dialog = QtWidgets.QMessageBox() + self.critical_battery_warning_dialog.setIcon(QtWidgets.QMessageBox.Critical) + self.critical_battery_warning_dialog.setText( + "\n\n\n\nRover battery critical!\nPower down immediately or battery damage will occur!\n\n\n\n") + self.critical_battery_warning_dialog.setWindowTitle("Critical Battery") + self.critical_battery_warning_dialog.setStandardButtons(QtWidgets.QMessageBox.Ok) + self.critical_battery_warning_dialog.setWindowFlags( + QtCore.Qt.WindowStaysOnTopHint | QtCore.Qt.X11BypassWindowManagerHint | QtCore.Qt.WindowTitleHint | QtCore.Qt.WindowCloseButtonHint) + self.critical_battery_warning_dialog.setStyleSheet(COLOR_RED) + + self.low_battery_warning_last_shown = 0 + self.critical_battery_warning_last_shown = 0 + def __camera_callback(self, data): self.camera_msg.camera_zed = data.camera_zed self.camera_msg.camera_undercarriage = data.camera_undercarriage @@ -217,7 +247,8 @@ class SensorCore(QtCore.QThread): self.gps_heading_valid_update_ready__signal.emit("GPS Heading Valid\nFalse") self.gps_num_satellites_update_ready__signal.emit("GPS Satellites\n%s" % data.num_satellites) - self.gps_accuracy_update_ready__signal.emit("GPS Accuracy\n%2.2f m" % (data.horizontal_dilution * GPS_BEST_CASE_ACCURACY)) + self.gps_accuracy_update_ready__signal.emit( + "GPS Accuracy\n%2.2f m" % (data.horizontal_dilution * GPS_BEST_CASE_ACCURACY)) def __misc_callback(self, data): self.misc_msg.arm_connection_status = data.arm_connection_status @@ -231,9 +262,20 @@ class SensorCore(QtCore.QThread): if voltage >= 21: self.battery_voltage_stylesheet_change_ready__signal.emit(COLOR_GREEN) + elif voltage >= 19: + self.battery_voltage_stylesheet_change_ready__signal.emit(COLOR_YELLOW) + + if (time.time() - self.low_battery_warning_last_shown) > LOW_BATTERY_DIALOG_TIMEOUT: + self.show_battery_low__signal.emit() + self.low_battery_warning_last_shown = time.time() + else: self.battery_voltage_stylesheet_change_ready__signal.emit(COLOR_RED) + if (time.time() - self.critical_battery_warning_last_shown) > CRITICAL_BATTERY_DIALOG_TIMEOUT: + self.show_battery_critical__signal.emit() + self.critical_battery_warning_last_shown = time.time() + self.battery_voltage_update_ready__signal.emit("Battery Voltage\n" + str(voltage) + " V") def __co2_callback(self, data): @@ -249,7 +291,7 @@ class SensorCore(QtCore.QThread): def run(self): while self.run_thread_flag: - self.update_requester.publish(Empty()) + # self.update_requester.publish(Empty()) self.__display_time() self.msleep(1000) @@ -279,6 +321,9 @@ class SensorCore(QtCore.QThread): self.battery_voltage_update_ready__signal.connect(self.battery.setText) self.battery_voltage_stylesheet_change_ready__signal.connect(self.battery.setStyleSheet) + self.show_battery_low__signal.connect(self.low_battery_warning_dialog.show) + self.show_battery_critical__signal.connect(self.critical_battery_warning_dialog.show) + def setup_signals(self, start_signal, signals_and_slots_signal, kill_signal): start_signal.connect(self.start) signals_and_slots_signal.connect(self.connect_signals_and_slots) diff --git a/software/ros_packages/ground_station/src/Resources/Ui/left_screen.ui b/software/ros_packages/ground_station/src/Resources/Ui/left_screen.ui index 5efcd23..6360c49 100644 --- a/software/ros_packages/ground_station/src/Resources/Ui/left_screen.ui +++ b/software/ros_packages/ground_station/src/Resources/Ui/left_screen.ui @@ -1396,6 +1396,11 @@ N/A SSH Console + + + + + diff --git a/software/ros_packages/rover_main/launch/rover/control.launch b/software/ros_packages/rover_main/launch/rover/control.launch index 1a4ca14..74761a2 100644 --- a/software/ros_packages/rover_main/launch/rover/control.launch +++ b/software/ros_packages/rover_main/launch/rover/control.launch @@ -9,10 +9,8 @@ - - - - + +