diff --git a/src/rov_msgs/CMakeLists.txt b/src/rov_msgs/CMakeLists.txt index 1d005b64..d8848f4e 100644 --- a/src/rov_msgs/CMakeLists.txt +++ b/src/rov_msgs/CMakeLists.txt @@ -29,6 +29,7 @@ rosidl_generate_interfaces(${PROJECT_NAME} "srv/AutonomousFlight.srv" "msg/Manip.msg" "msg/CameraControllerSwitch.msg" + "msg/Flooding.msg" DEPENDENCIES std_msgs ) diff --git a/src/rov_msgs/msg/Flooding.msg b/src/rov_msgs/msg/Flooding.msg new file mode 100644 index 00000000..ce5dd7ee --- /dev/null +++ b/src/rov_msgs/msg/Flooding.msg @@ -0,0 +1,2 @@ +# True means the robot is actively flooding +bool flooding \ No newline at end of file diff --git a/src/surface/gui/README.md b/src/surface/gui/README.md index b159a5d6..29414b03 100644 --- a/src/surface/gui/README.md +++ b/src/surface/gui/README.md @@ -64,6 +64,16 @@ Has two buttons for arming and disarming the pixhawk. Sends a request to arm or disarm the pixhawk. Receives a confirmation about the success of the arm or disarm. +### Flood Warnng + +Shows whether the robot is flooding or not on the GUI + +#### Subscribed Topics + +* **`/tether/flooding`** ([rov_msgs/msg/Flooding]) + + A custom message for whether the robot is actively flooding + ### Logger Reads ROS logging information and displays it on the gui. diff --git a/src/surface/gui/gui/pilot_app.py b/src/surface/gui/gui/pilot_app.py index 7c5e4e90..71cffb8f 100644 --- a/src/surface/gui/gui/pilot_app.py +++ b/src/surface/gui/gui/pilot_app.py @@ -1,5 +1,6 @@ from gui.app import App from gui.widgets.arm import Arm +from gui.widgets.flood_warning import FloodWarning from gui.widgets.video_widget import SwitchableVideoWidget from PyQt6.QtCore import Qt from PyQt6.QtWidgets import QHBoxLayout @@ -23,6 +24,10 @@ def __init__(self) -> None: "camera_switch") layout.addWidget(self.video_area, alignment=Qt.AlignmentFlag.AlignCenter) + self.floodWidget: FloodWarning = FloodWarning() + layout.addWidget(self.floodWidget, alignment=Qt.AlignmentFlag.AlignRight + | Qt.AlignmentFlag.AlignTop) + self.arm: Arm = Arm() layout.addWidget(self.arm, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignBottom) diff --git a/src/surface/gui/gui/widgets/flood_warning.py b/src/surface/gui/gui/widgets/flood_warning.py new file mode 100644 index 00000000..2db78541 --- /dev/null +++ b/src/surface/gui/gui/widgets/flood_warning.py @@ -0,0 +1,45 @@ +from gui.event_nodes.subscriber import GUIEventSubscriber +from PyQt6.QtCore import pyqtSignal, pyqtSlot +from PyQt6.QtGui import QFont +from PyQt6.QtWidgets import QLabel, QVBoxLayout, QWidget + +from rov_msgs.msg import Flooding + + +class FloodWarning(QWidget): + + signal: pyqtSignal = pyqtSignal(Flooding) + + def __init__(self) -> None: + super().__init__() + # Boilerplate PyQt Setup to link to ROS through a signal/subscriber + self.signal.connect(self.refresh) + self.subscription: GUIEventSubscriber = GUIEventSubscriber(Flooding, + 'flooding', + self.signal) + # Create a latch variable + self.warning_msg_latch: bool = False + # Create basic 2 vertical stacked boxes layout + self.flood_layour = QVBoxLayout() + # Create the label that tells us what this is + self.label: QLabel = QLabel('Flooding Indicator') + font: QFont = QFont("Arial", 14) + self.label.setFont(font) + self.flood_layour.addWidget(self.label) + + self.indicator: QLabel = QLabel('No Water present') + self.indicator.setFont(font) + self.flood_layour.addWidget(self.indicator) + self.setLayout(self.flood_layour) + + @pyqtSlot(Flooding) + def refresh(self, msg: Flooding) -> None: + if msg.flooding: + self.indicator.setText('FLOODING') + self.subscription.get_logger().error("Robot is actively flooding, do something!") + self.warning_msg_latch = True + else: + self.indicator.setText('No Water present') + if self.warning_msg_latch: + self.subscription.get_logger().warning("Robot flooding has reset itself.") + self.warning_msg_latch = False diff --git a/src/surface/gui/launch/pilot_launch.py b/src/surface/gui/launch/pilot_launch.py index feffc3d0..cc5a4a7e 100644 --- a/src/surface/gui/launch/pilot_launch.py +++ b/src/surface/gui/launch/pilot_launch.py @@ -13,7 +13,8 @@ def generate_launch_description() -> LaunchDescription: remappings=[("/surface/gui/mavros/cmd/arming", "/tether/mavros/cmd/arming"), ("/surface/gui/camera_switch", "/surface/camera_switch"), ("/surface/gui/bottom_cam/image_raw", "/tether/bottom_cam/image_raw"), - ("/surface/gui/front_cam/image_raw", "/tether/front_cam/image_raw")], + ("/surface/gui/front_cam/image_raw", "/tether/front_cam/image_raw"), + ("/surface/gui/flooding", "/tether/flooding")], emulate_tty=True, output='screen' )