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 @@
-
-
-
-
+
+