diff --git a/software/reference/design_reference/UI Design/compass.svg b/software/reference/design_reference/UI Design/compass.svg new file mode 100644 index 0000000..f6acb65 --- /dev/null +++ b/software/reference/design_reference/UI Design/compass.svg @@ -0,0 +1,1639 @@ + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3060 + 000 180 + + 340 160 + + 320 140 + + 300 120 + + 280 100 + + 260 080 + + 240 060 + + 220 040 + + 200 020 + + NE + SW + + + NW + SE + + + N + S + + + + W + E + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/software/ros_packages/ground_station/src/Framework/NavigationSystems/SpeedAndHeadingIndication.py b/software/ros_packages/ground_station/src/Framework/NavigationSystems/SpeedAndHeadingIndication.py index 2305d09..f5d4d5a 100644 --- a/software/ros_packages/ground_station/src/Framework/NavigationSystems/SpeedAndHeadingIndication.py +++ b/software/ros_packages/ground_station/src/Framework/NavigationSystems/SpeedAndHeadingIndication.py @@ -1,3 +1,4 @@ +# coding=utf-8 ##################################### # Imports ##################################### @@ -11,7 +12,9 @@ from PIL.ImageQt import ImageQt ##################################### # Global Variables ##################################### -THREAD_HERTZ = 10 +THREAD_HERTZ = 20 + +ROTATION_SPEED_MODIFIER = 1 ##################################### @@ -19,6 +22,7 @@ THREAD_HERTZ = 10 ##################################### class SpeedAndHeadingIndication(QtCore.QThread): show_compass_image__signal = QtCore.pyqtSignal() + heading_text_update_ready__signal = QtCore.pyqtSignal(str) def __init__(self, shared_objects): super(SpeedAndHeadingIndication, self).__init__() @@ -26,7 +30,11 @@ class SpeedAndHeadingIndication(QtCore.QThread): # ########## Reference to class init variables ########## self.shared_objects = shared_objects self.right_screen = self.shared_objects["screens"]["right_screen"] + self.heading_compass_label = self.right_screen.heading_compass_label # type: QtWidgets.QLabel + self.heading_text_label = self.right_screen.current_heading_label # type: QtWidgets.QLabel + self.next_goal_label = self.right_screen.next_goal_label # type: QtWidgets.QLabel + self.current_speed_label = self.right_screen.current_speed_label # type: QtWidgets.QLabel # ########## Get the settings instance ########## self.settings = QtCore.QSettings() @@ -40,34 +48,78 @@ class SpeedAndHeadingIndication(QtCore.QThread): # ########## Class Variables ########## self.wait_time = 1.0 / THREAD_HERTZ - self.main_compass_image = PIL.Image.open("Resources/Images/compass.png").resize((300, 300)) + self.main_compass_image = PIL.Image.open("Resources/Images/compass.png").resize((300, 300), PIL.Image.ANTIALIAS) self.compass_pixmap = None - self.current_rotation = 0 + self.current_heading = 0 + self.current_heading_changed = True + + self.shown_heading = (self.current_heading + 1) % 360 + self.current_heading_shown_rotation_angle = 0 + self.rotation_direction = 1 # compass_image = PIL.Image.open("Resources/Images/compass.png").resize((300, 300)).rotate(45) # PIL.Image # self.shared_objects["screens"]["right_screen"].heading_compass_label.setPixmap(QtGui.QPixmap.fromImage(ImageQt(compass_image))) def run(self): + self.on_heading_changed__slot(self.current_heading) + while self.run_thread_flag: - start_time = time() - self.current_rotation += 1 - new_compass_image = self.main_compass_image.rotate(self.current_rotation) + if self.current_heading_changed: + self.update_heading_movement() + self.current_heading_changed = False - self.compass_pixmap = QtGui.QPixmap.fromImage(ImageQt(new_compass_image)) - self.show_compass_image__signal.emit() + self.rotate_compass_if_needed() time_diff = time() - start_time self.msleep(max(int(self.wait_time - time_diff), 0)) + def rotate_compass_if_needed(self): + if int(self.shown_heading) != self.current_heading: + self.shown_heading += self.rotation_direction * ROTATION_SPEED_MODIFIER + self.shown_heading %= 360 + + self.current_heading_shown_rotation_angle = int(self.shown_heading) + + new_compass_image = self.main_compass_image.rotate(self.current_heading_shown_rotation_angle, resample=PIL.Image.BICUBIC) + + self.compass_pixmap = QtGui.QPixmap.fromImage(ImageQt(new_compass_image)) + self.show_compass_image__signal.emit() + + def update_heading_movement(self): + current_minus_shown = (self.current_heading - self.shown_heading) % 360 + + if current_minus_shown >= 180: + self.rotation_direction = -1 + else: + self.rotation_direction = 1 + + def on_heading_changed__slot(self, new_heading): + self.current_heading = new_heading + self.heading_text_update_ready__signal.emit(str(new_heading) + "°") + self.current_heading_changed = True + + def __on_heading_clicked__slot(self, event): + new_heading = self.current_heading + if event.button() == QtCore.Qt.LeftButton: + new_heading = (self.current_heading + 10) % 360 + elif event.button() == QtCore.Qt.RightButton: + new_heading = (self.current_heading - 10) % 360 + + self.on_heading_changed__slot(new_heading) + self.heading_text_update_ready__signal.emit(str(new_heading) + "°") + def on_new_compass_image_ready__slot(self): self.heading_compass_label.setPixmap(self.compass_pixmap) def connect_signals_and_slots(self): self.show_compass_image__signal.connect(self.on_new_compass_image_ready__slot) + self.heading_text_update_ready__signal.connect(self.heading_text_label.setText) + + self.heading_compass_label.mousePressEvent = self.__on_heading_clicked__slot def setup_signals(self, start_signal, signals_and_slots_signal, kill_signal): start_signal.connect(self.start) diff --git a/software/ros_packages/ground_station/src/Framework/VideoSystems/RoverVideoCoordinator.py b/software/ros_packages/ground_station/src/Framework/VideoSystems/RoverVideoCoordinator.py index b091b2d..54d8f8c 100644 --- a/software/ros_packages/ground_station/src/Framework/VideoSystems/RoverVideoCoordinator.py +++ b/software/ros_packages/ground_station/src/Framework/VideoSystems/RoverVideoCoordinator.py @@ -4,6 +4,7 @@ # Python native imports from PyQt5 import QtCore, QtWidgets import logging +from time import time import rospy @@ -21,6 +22,11 @@ PRIMARY_LABEL_MAX = (640, 360) SECONDARY_LABEL_MAX = (640, 360) TERTIARY_LABEL_MAX = (640, 360) +GUI_SELECTION_CHANGE_TIMEOUT = 3 # Seconds + +STYLESHEET_SELECTED = "border: 2px solid orange; background-color:black;" +STYLESHEET_UNSELECTED = "background-color:black;" + ##################################### # RoverVideoCoordinator Class Definition @@ -89,7 +95,8 @@ class RoverVideoCoordinator(QtCore.QThread): } self.current_label_for_joystick_adjust = 0 - self.gui_selection_update_needed = True + self.gui_selection_changed = True + self.last_gui_selection_changed_time = time() self.set_max_resolutions_flag = True @@ -131,19 +138,27 @@ class RoverVideoCoordinator(QtCore.QThread): self.camera_threads[camera_name].toggle_video_display() def __update_gui_element_selection(self): - if self.gui_selection_update_needed: - self.update_element_stylesheet__signal.emit() + if (time() - self.last_gui_selection_changed_time) > GUI_SELECTION_CHANGE_TIMEOUT \ + and self.gui_selection_changed: + + elements_to_reset = range(len(self.index_to_label_element)) + + for index in elements_to_reset: + self.index_to_label_element[index].setStyleSheet(STYLESHEET_UNSELECTED) + + self.gui_selection_changed = False def __on_gui_element_stylesheet_update__slot(self): elements_to_reset = range(len(self.index_to_label_element)) elements_to_reset.remove(self.current_label_for_joystick_adjust) for index in elements_to_reset: - self.index_to_label_element[index].setStyleSheet("background-color:black;") + self.index_to_label_element[index].setStyleSheet(STYLESHEET_UNSELECTED) - self.index_to_label_element[self.current_label_for_joystick_adjust].setStyleSheet("border: 2px solid orange;") + self.index_to_label_element[self.current_label_for_joystick_adjust].setStyleSheet(STYLESHEET_SELECTED) - self.gui_selection_update_needed = False + self.gui_selection_changed = True + self.last_gui_selection_changed_time = time() def __get_cameras(self): topics = rospy.get_published_topics(CAMERA_TOPIC_PATH) @@ -260,7 +275,7 @@ class RoverVideoCoordinator(QtCore.QThread): else: self.current_label_for_joystick_adjust = new_selection - self.gui_selection_update_needed = True + self.update_element_stylesheet__signal.emit() def on_camera_selection_for_current_gui_element_changed(self, direction): if self.current_label_for_joystick_adjust == 0: # primary @@ -271,6 +286,7 @@ class RoverVideoCoordinator(QtCore.QThread): self.tertiary_label_current_setting = (self.tertiary_label_current_setting + direction) % len(self.valid_cameras) self.set_max_resolutions_flag = True + self.update_element_stylesheet__signal.emit() def on_gui_selected_camera_toggled(self): if self.current_label_for_joystick_adjust == 0: # primary @@ -292,5 +308,7 @@ class RoverVideoCoordinator(QtCore.QThread): self.disabled_cameras.append(self.tertiary_label_current_setting) self.camera_threads[self.valid_cameras[self.tertiary_label_current_setting]].toggle_video_display() + self.update_element_stylesheet__signal.emit() + def on_kill_threads_requested__slot(self): self.run_thread_flag = False diff --git a/software/ros_packages/ground_station/src/Resources/Images/compass.png b/software/ros_packages/ground_station/src/Resources/Images/compass.png index d9fcdb4..992eacd 100644 Binary files a/software/ros_packages/ground_station/src/Resources/Images/compass.png and b/software/ros_packages/ground_station/src/Resources/Images/compass.png differ 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 ac1d018..3ecb508 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 @@ -682,6 +682,11 @@ Connected + + + Science Data + + Settings diff --git a/software/ros_packages/ground_station/src/Resources/Ui/right_screen.ui b/software/ros_packages/ground_station/src/Resources/Ui/right_screen.ui index 2eb8b6a..83e605a 100644 --- a/software/ros_packages/ground_station/src/Resources/Ui/right_screen.ui +++ b/software/ros_packages/ground_station/src/Resources/Ui/right_screen.ui @@ -42,16 +42,7 @@ QLayout::SetDefaultConstraint - - 0 - - - 0 - - - 0 - - + 0 @@ -562,16 +553,7 @@ - - 0 - - - 0 - - - 0 - - + 0 @@ -630,6 +612,12 @@ + + + 115 + 0 + + 17 @@ -647,6 +635,12 @@ + + + 115 + 0 + + 17 @@ -677,6 +671,23 @@ + + + + + 19 + 50 + false + + + + + + + Qt::AlignCenter + + + @@ -824,7 +835,7 @@ 0 - + 22 @@ -1050,7 +1061,7 @@ - background-color: darkblue; + background-color:black; @@ -1077,7 +1088,7 @@ - background-color:darkgreen; + background-color:black; @@ -1099,7 +1110,7 @@ - background-color:maroon; + background-color:black;