Working on adding bash console to a widget. Added low battery and critical battery warnings as we almost killed a rover battery from undervoltagegit statusgit statusgit status

This commit is contained in:
2018-07-28 21:58:08 -07:00
parent aa6f3f2d6f
commit ae8cffeb6e
5 changed files with 103 additions and 8 deletions

View File

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

View File

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

View File

@@ -1396,6 +1396,11 @@ N/A</string>
<attribute name="title">
<string>SSH Console</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="QWidget" name="ssh_console_widget" native="true"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">

View File

@@ -9,10 +9,8 @@
<param name="port" value="/dev/rover/ttyREAR"/>
<param name="drive_control_topic" value="drive_control/rear"/>
<param name="drive_control_status_topic" value="drive_status/rear"/>
<param name="first_motor_id" value="1"/>
<param name="second_motor_id" value="2"/>
<param name="invert_first_motor" value="True"/>
<param name="invert_second_motor" value="True"/>
<param name="first_motor_id" value="2"/>
<param name="second_motor_id" value="1"/>
</node>
<node name="left_bogie" pkg="rover_control" type="drive_control.py" respawn="true" output="screen">