Skip to content
Snippets Groups Projects
ControlTab.py 4.19 KiB
from PyQt5.QtWidgets import QPushButton, QGridLayout, QWidget, QVBoxLayout
from PyQt5.QtCore import QTimer
from PlottingWindow import PlottingWindow
from LoggingSelectionMenu import LoggingSelectionMenu
from queue import Queue
import queue
from CrazyflieProtoConnection import CrazyflieProtoConnection
from SetpointMenu import SetpointMenu
from SetpointHandler import SetpointHandler
from cfclient.utils.input import JoystickReader


class ControlTab(QWidget):
    def __init__(self, logging_queue: Queue,
                 setpoint_handler: SetpointHandler, joystick: JoystickReader,
                 cf: CrazyflieProtoConnection):
        """
        Initialize the control tab.

        :param logging_queue: Holds data coming from crazyflieProtoConnection
        that has been logged. This data is handled more by the PlottingWindow
        and LoggingSelectionMenu but those are both child widgets of the
        Control tab.
        :param setpoint_handler: When a setpoint is sent from the control tab,
        it is not sent to the crazyflieProtoConnection directly, instead it is
        sent to the setpoint_handler which is able to work with timing a bit
        more accurately than the GUI should need to.
        :param joystick: Connection to any gamepad that is connected.
        :param cf: Reference to the crazyflieProtoConnection, used to send
        setpoints.
        """
        super().__init__()

        self.logging_queue = logging_queue
        self.graph_data = False

        self.cf = cf

        layout = QGridLayout()
        left_side_vertical_layout = QVBoxLayout()

        self.plotting_window = PlottingWindow()
        self.setpoint_menu = SetpointMenu(setpoint_handler, joystick)
        self.logging_menu = LoggingSelectionMenu(self.external_press_pause)

        win2 = QWidget()
        win2.setLayout(left_side_vertical_layout)
        win2.setMaximumWidth(300)

        layout.addWidget(win2, 1, 1)
        layout.addWidget(self.plotting_window, 1, 2)

        self.play_or_pause_logging_button = \
            QPushButton("Begin Graphing Logging")
        self.play_or_pause_logging_button.clicked.connect(
            self.play_pause_button_callback)

        left_side_vertical_layout.addWidget(self.setpoint_menu, 1)
        left_side_vertical_layout.addWidget(
            self.play_or_pause_logging_button, 2)
        left_side_vertical_layout.addWidget(self.logging_menu, 3)

        # Set up the timer to update the plot
        self.timer = QTimer()
        self.timer.timeout.connect(self.update_plot_outer)
        self.timer.start(50)

        # Set the window properties
        self.setLayout(layout)
        self.setWindowTitle("Sine Wave Plot")
        # self.setGeometry(100, 100, 800, 600)
        self.show()

    def update_plot_outer(self):
        """ Empty out logging queue, and update Plotting Window. """

        not_empty = True
        while not_empty:
            try:
                value = self.logging_queue.get_nowait()
                data = value['data']
                timestamp = value['timestamp']

                # Uses the logging menu to check if the signal has been
                # selected to be graphed or not. If no, axis = None.
                axis = self.logging_menu.get_axis_of_signal(value['signal'])

                if axis is not None and self.graph_data:
                    self.plotting_window.update_plot(data, timestamp, axis)

            except queue.Empty:  # done emptying logging queue
                not_empty = False

    def external_press_pause(self):
        """ Made so the logging selection menu can press the pause button
        programatically whenever configurations change. """
        self.play_or_pause_logging_button.click()

    def play_pause_button_callback(self):
        """ This function handles getting the logging to stop or to continue
        graphing. Called when button is clicked. """

        if self.graph_data:
            self.play_or_pause_logging_button.setText(
                "Continue Graphing Logging")
            self.graph_data = False
            self.cf.stop_logging()
        else:
            self.play_or_pause_logging_button.setText("Pause Logging")
            self.graph_data = True
            self.cf.start_logging()