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