diff --git a/pycrocart/ControlWindow.py b/pycrocart/ControlWindow.py index 636e47ca7abd1264752555b0fd7b8ff6d3aa3776..f44b76013e0626fee20a1e10555a971e57f9c093 100644 --- a/pycrocart/ControlWindow.py +++ b/pycrocart/ControlWindow.py @@ -1,12 +1,5 @@ -import sys -from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QGridLayout, \ - QWidget, QVBoxLayout, QComboBox -from PyQt5.QtCore import Qt, QTimer -from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas -from matplotlib.figure import Figure -import numpy as np -from time import time -import pyqtgraph as pg +from PyQt5.QtWidgets import QPushButton, QGridLayout, QWidget, QVBoxLayout +from PyQt5.QtCore import QTimer from PlottingWindow import PlotCanvas from LoggingSelectionMenu import LoggingSelectionMenu from queue import Queue @@ -34,29 +27,25 @@ class ControlWindow(QWidget): self.canvas = PlotCanvas() self.setpoint_menu = SetpointMenu(setpoint_handler, joystick) - self.logging_menu = LoggingSelectionMenu(self.selectionchange) + self.logging_menu = LoggingSelectionMenu() win2 = QWidget() win2.setLayout(left_side_vertical_layout) win2.setMaximumWidth(300) - # win2.setMinimumWidth(100) layout.addWidget(win2, 1, 1) layout.addWidget(self.canvas, 1, 2) - - self.print_button = QPushButton("Begin Graphing Logging") - self.print_button.clicked.connect(self.print_entry_boxes) - - + 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.print_button, 2) + 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) @@ -69,45 +58,30 @@ class ControlWindow(QWidget): self.show() def update_plot_outer(self): - not_empty = True - while not_empty: - try: - value = self.logging_queue.get_nowait() - data = value['data'] - timestamp = value['timestamp'] - axis = self.logging_menu.get_axis_of_signal(value['signal']) + not_empty = True + while not_empty: + try: + value = self.logging_queue.get_nowait() + data = value['data'] + timestamp = value['timestamp'] + axis = self.logging_menu.get_axis_of_signal(value['signal']) - if axis is not None and self.graph_data: - self.canvas.update_plot(data, timestamp, axis) + if axis is not None and self.graph_data: + self.canvas.update_plot(data, timestamp, axis) - except queue.Empty: # done emptying logging queue + except queue.Empty: # done emptying logging queue - not_empty = False + not_empty = False - def selectionchange(self): - print("Change") - - def print_entry_boxes(self): + def play_pause_button_callback(self): print("Hello world!") if self.graph_data: - self.print_button.setText("Continue Graphing Logging") + self.play_or_pause_logging_button.setText( + "Continue Graphing Logging") self.graph_data = False self.cf.stop_logging() else: - self.print_button.setText("Pause Logging") + self.play_or_pause_logging_button.setText("Pause Logging") self.graph_data = True self.cf.start_logging() - - -# Start the application -if __name__ == '__main__': - app = QApplication(sys.argv) - - cf1 = CrazyflieProtoConnection() - - window = ControlWindow(cf1.logging_queue) - win = QMainWindow() - win.setCentralWidget(window) - win.show() - sys.exit(app.exec_()) diff --git a/pycrocart/CrazyflieProtoConnection.py b/pycrocart/CrazyflieProtoConnection.py index 1d51acc327c6755cc95c1371ec3c23426ed45733..35898890ac1beea3ecb3d0214a384c67a5afbf48 100644 --- a/pycrocart/CrazyflieProtoConnection.py +++ b/pycrocart/CrazyflieProtoConnection.py @@ -1,31 +1,13 @@ -import random -import sys -from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QGridLayout, \ - QWidget, QVBoxLayout, QComboBox -from PyQt5.QtCore import Qt, QTimer -from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas -from matplotlib.figure import Figure -import numpy as np from time import time -import time as t1 -import pyqtgraph as pg -from queue import Queue from typing import List - -import logging import time import cflib.crtp from cflib.crazyflie import Crazyflie from cflib.crazyflie.syncCrazyflie import SyncCrazyflie from queue import Queue -from threading import Semaphore -from PyQt5.QtCore import Qt, QTimer from cflib.crazyflie.log import LogConfig -from cflib.crazyflie.syncLogger import SyncLogger - -cflib.crtp.init_drivers() # If this file is ever imported this will be run class CrazyflieProtoConnection: @@ -40,65 +22,72 @@ class CrazyflieProtoConnection: self.param_callback_count = 0 self.logging_configs = [] - def logging_callback(self, timestamp, data, logconf): + def logging_callback(self, _timestamp, data, _logconf): timestamp1 = time.time() - self.start_time - print('[%d][%s]: %s' % (timestamp, logconf.name, data)) - for key in data.keys(): value_pair = {'timestamp': timestamp1, 'data': data[key], 'signal': key} self.logging_queue.put(value_pair) def param_set_value(self, group: str, name: str, value: float): + try: + if self.scf.is_link_open(): + full_name = group + "." + name + cf = self.scf.cf + cf.param.add_update_callback(group=group, name=name, + cb=self.done_setting_param_value) - if self.scf.is_link_open(): - full_name = group + "." + name - cf = self.scf.cf - cf.param.add_update_callback(group=group, name=name, - cb=self.done_setting_param_value) - - - cf.param.set_value(full_name, value) + cf.param.set_value(full_name, value) - # Don't return until the parameter is done getting set - while self.param_callback_count < 1: - time.sleep(0.01) + # Don't return until the parameter is done getting set + while self.param_callback_count < 1: + time.sleep(0.01) - self.param_callback_count = 0 + self.param_callback_count = 0 + except AttributeError: + print("Nothing connected") - def done_setting_param_value(self, *args): + def done_setting_param_value(self, *_args): print("Done setting param") self.param_callback_count += 1 def param_get_value(self, group: str, name: str): - if self.scf.is_link_open(): - full_name = group + "." + name - - return self.scf.cf.param.values[group][name] + try: + if self.scf.is_link_open(): + return self.scf.cf.param.values[group][name] + except AttributeError: + pass + return -1.234567890 def get_logging_toc(self): - - if self.scf.is_link_open(): - tocFull = self.scf.cf.log.toc.toc - toc = [] - for key in tocFull.keys(): - for inner_key in tocFull[key].keys(): - full_name = key + "." + inner_key - toc.append(full_name) - - return toc - else: - return {} + try: + if self.scf.is_link_open(): + tocFull = self.scf.cf.log.toc.toc + toc = [] + for key in tocFull.keys(): + for inner_key in tocFull[key].keys(): + full_name = key + "." + inner_key + toc.append(full_name) + + return toc + else: + return {} + except AttributeError: + pass + return {} def get_param_toc(self): + try: + if self.scf.is_link_open(): + toc = self.scf.cf.param.values - if self.scf.is_link_open(): - toc = self.scf.cf.param.values - - return toc + return toc + except AttributeError: + pass + return {} def add_log_config(self, name: str, period: int, variables: List[str]): print("Name: " + name + ", period: " + str(period) + ", variables: " @@ -135,9 +124,8 @@ class CrazyflieProtoConnection: if self.is_connected: self.scf.close_link() - def list_available_crazyflies(self): + @staticmethod + def list_available_crazyflies(): cflib.crtp.init_drivers() # run this again just in case you plug the # dongle in return cflib.crtp.scan_interfaces() - - diff --git a/pycrocart/GamepadWizard.py b/pycrocart/GamepadWizard.py index 6ecb2e2b4005bc6d866c092c1138212076f68f31..3e16ea5987287ce44f213ec5ecb5a073e3dc0efd 100644 --- a/pycrocart/GamepadWizard.py +++ b/pycrocart/GamepadWizard.py @@ -37,7 +37,8 @@ from PyQt5.QtWidgets import QMessageBox from cfclient.utils.config_manager import ConfigManager from PyQt5 import Qt from PyQt5 import QtWidgets -from PyQt5 import uic +from PyQt5 import uic # pycharm seems to think this doesn't exist, +# but pycharm is stupid and it does exist, get over it. from PyQt5.Qt import * # noqa from cfclient.utils.input import JoystickReader import sys @@ -436,7 +437,7 @@ class DeviceReader(QThread): if __name__ == "__main__": app = QApplication(sys.argv) - win2 = InputConfigDialogue(JoystickReader()) + win2 = InputConfigDialogue(JoystickReader(), print) win = QMainWindow() win.setCentralWidget(win2) win.show() diff --git a/pycrocart/LoggingConfigWindow.py b/pycrocart/LoggingConfigWindow.py index 0330b66e2c713008e6e72e1aa0de9fd0724301b6..7ac80a82fd00b9a715e85f7b1f6ab12119ed48ae 100644 --- a/pycrocart/LoggingConfigWindow.py +++ b/pycrocart/LoggingConfigWindow.py @@ -1,30 +1,21 @@ -import sys -from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QGridLayout, \ - QWidget, QVBoxLayout, QComboBox, QLabel, QLineEdit, QProgressBar, \ - QHBoxLayout, QListWidget -from PyQt5.QtCore import Qt, QTimer -from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas -from matplotlib.figure import Figure -import numpy as np -import time -import pyqtgraph as pg -from PyQt5 import QtWidgets +from PyQt5.QtWidgets import QPushButton, QGridLayout, QWidget, QVBoxLayout, \ + QLabel, QHBoxLayout, QListWidget from PyQt5.QtCore import Qt -from PyLine import QHSeparationLine import os import json -from queue import Queue -import queue from CrazyflieProtoConnection import CrazyflieProtoConnection class LoggingConfigWindow(QWidget): - def __init__(self, cf: CrazyflieProtoConnection): + def __init__(self, cf: CrazyflieProtoConnection, + logging_selection_menu_update_function): super().__init__() layout = QHBoxLayout() self.setLayout(layout) self.cf = cf + self.logging_selection_menu_update_function = \ + logging_selection_menu_update_function self.items = [] self.items_text = [] @@ -95,7 +86,8 @@ class LoggingConfigWindow(QWidget): stop_logging_button.setMaximumWidth(200) horizontal_layout.addWidget(stop_logging_button, 2) - def open_log_file(self): + @staticmethod + def open_log_file(_self): os.startfile('logging_variables.json') def on_refresh(self): @@ -212,8 +204,9 @@ class LoggingConfigWindow(QWidget): if blocks_valid: self.error_label.setText("") - + variables = [] for block in blocks: self.cf.add_log_config(block['name'], block['period'], block['vars']) - + variables.append(block['vars']) + self.logging_selection_menu_update_function(variables) diff --git a/pycrocart/LoggingSelectionMenu.py b/pycrocart/LoggingSelectionMenu.py index 475b7de4a9ce0d3f52ee2601c9eb8ba84a9d197b..2eff19c92b0350c2c14911b88e311905402249f9 100644 --- a/pycrocart/LoggingSelectionMenu.py +++ b/pycrocart/LoggingSelectionMenu.py @@ -1,32 +1,21 @@ -import sys -from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QGridLayout, \ - QWidget, QVBoxLayout, QComboBox -from PyQt5.QtCore import Qt, QTimer -from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas -from matplotlib.figure import Figure -import numpy as np -from time import time -import pyqtgraph as pg +from PyQt5.QtWidgets import QWidget, QVBoxLayout, QComboBox class LoggingSelectionMenu(QWidget): - def __init__(self, callback=None): + def __init__(self): super().__init__() - self.callback = callback - layout = QVBoxLayout() self.setLayout(layout) - self.available_logging_variables = \ - ["stateEstimate.pitch", "stateEstimate.roll", "stateEstimate.yaw", "pm.batteryLevel"] + self.available_logging_variables = [] self.cbs = [QComboBox(), QComboBox(), QComboBox(), QComboBox(), QComboBox()] for i in range(0, len(self.cbs)): - list = ["Logging Variable " + str(i+1)] - list.extend(self.available_logging_variables) + lst = ["Logging Variable " + str(i+1)] + lst.extend(self.available_logging_variables) self.cbs[i].addItems(list) layout.addWidget(self.cbs[i], i+1) self.cbs[i].currentIndexChanged.connect( @@ -38,8 +27,10 @@ class LoggingSelectionMenu(QWidget): if signal_name == self.cbs[i].currentText(): return i+1 + def update_available_logging_variables(self, variables_list: list): + self.available_logging_variables = variables_list + def selection_change_callback(self): - self.callback() selected_signals = [ self.cbs[0].currentText(), self.cbs[1].currentText(), @@ -73,7 +64,3 @@ class LoggingSelectionMenu(QWidget): self.cbs[i].currentIndexChanged.connect( self.selection_change_callback) - - - - diff --git a/pycrocart/ParameterWindow.py b/pycrocart/ParameterWindow.py index 637652d565a056561527d0919e947dee3fa4d2f5..65a3f7230319b68eda7e77ee5318024f85a6a2b8 100644 --- a/pycrocart/ParameterWindow.py +++ b/pycrocart/ParameterWindow.py @@ -1,12 +1,6 @@ -import sys -from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QGridLayout, \ - QWidget, QVBoxLayout, QComboBox, QLabel, QLineEdit, QProgressBar -from PyQt5.QtCore import Qt, QTimer -from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas -from matplotlib.figure import Figure -import numpy as np -import time -import pyqtgraph as pg +from PyQt5.QtWidgets import QPushButton, QGridLayout, QWidget, QComboBox, \ + QLabel, QLineEdit, QProgressBar +from PyQt5.QtCore import QTimer from PyQt5 import QtWidgets from PyQt5.QtCore import Qt from PyLine import QHSeparationLine @@ -33,26 +27,21 @@ class ParameterWindow(QWidget): self.toc = {} self.timer = QTimer() - horizontal_spacer = QtWidgets.QSpacerItem(1, 1, - QtWidgets.QSizePolicy.Expanding, - QtWidgets.QSizePolicy.Minimum) + horizontal_spacer = QtWidgets.QSpacerItem( + 1, 1, QtWidgets.QSizePolicy.Expanding, + QtWidgets.QSizePolicy.Minimum) layout.addItem(horizontal_spacer, 1, 2, Qt.AlignRight) - horizontal_spacer2 = QtWidgets.QSpacerItem(1, 1, - QtWidgets.QSizePolicy.Expanding, - QtWidgets.QSizePolicy.Minimum) + horizontal_spacer2 = QtWidgets.QSpacerItem( + 1, 1, QtWidgets.QSizePolicy.Expanding, + QtWidgets.QSizePolicy.Minimum) layout.addItem(horizontal_spacer2, 1, 0, Qt.AlignRight) - horizontal_spacer3 = QtWidgets.QSpacerItem(1, 1, - QtWidgets.QSizePolicy.Minimum, - QtWidgets.QSizePolicy.Expanding) + horizontal_spacer3 = QtWidgets.QSpacerItem( + 1, 1, QtWidgets.QSizePolicy.Minimum, + QtWidgets.QSizePolicy.Expanding) layout.addItem(horizontal_spacer3, 0, 1, Qt.AlignTop) - horizontal_spacer4 = QtWidgets.QSpacerItem(1, 1, - QtWidgets.QSizePolicy.Minimum, - QtWidgets.QSizePolicy.Expanding) - layout.addItem(horizontal_spacer4, 100, 1, Qt.AlignBottom) - # --------------------- Get Param -------------------------------------- get_paraml = QLabel("Get Parameter") layout.addWidget(get_paraml, 1, 1) @@ -90,7 +79,7 @@ class ParameterWindow(QWidget): self.get_param_button = QPushButton("Get Param") self.get_param_button.clicked.connect(self.get_param) - layout.addWidget(self.get_param_button, 3, 1, alignment=Qt.AlignCenter) + layout.addWidget(self.get_param_button, 3, 1, alignment=Qt.AlignHCenter) self.get_param_button.setMinimumWidth(150) self.get_param_button.setMaximumWidth(150) @@ -139,7 +128,7 @@ class ParameterWindow(QWidget): self.set_param_button.setMinimumWidth(150) self.set_param_button.setMaximumWidth(150) self.set_param_button.clicked.connect(self.set_param) - layout.addWidget(self.set_param_button, 8, 1, alignment=Qt.AlignCenter) + layout.addWidget(self.set_param_button, 8, 1, alignment=Qt.AlignHCenter) # -------------------- File interaction -------------------------------- @@ -149,8 +138,8 @@ class ParameterWindow(QWidget): layout.addWidget(file_interaction_widget, 9, 1) self.set_from_file_button = QPushButton("Set Params from Json file") - self.set_from_file_button.setMinimumWidth(150) - self.set_from_file_button.setMaximumWidth(150) + self.set_from_file_button.setMinimumWidth(200) + self.set_from_file_button.setMaximumWidth(200) file_interaction_layout.addWidget(self.set_from_file_button, 1, 1) self.set_from_file_button.clicked.connect(self.on_send) @@ -161,15 +150,15 @@ class ParameterWindow(QWidget): self.edit_file_button.clicked.connect(self.on_edit) file_note = QLabel("Note: This may take a few seconds") - layout.addWidget(file_note, 10, 1, alignment=Qt.AlignCenter) + layout.addWidget(file_note, 10, 1, alignment=Qt.AlignHCenter) self.complete_label = QLabel("Complete ✓") - layout.addWidget(self.complete_label, 11, 1, alignment=Qt.AlignCenter) + layout.addWidget(self.complete_label, 11, 1, alignment=Qt.AlignHCenter) self.progress_bar = QProgressBar() self.progress_bar.setMinimumWidth(100) self.progress_bar.setMaximumWidth(200) - layout.addWidget(self.progress_bar, 12, 1, alignment=Qt.AlignCenter) + layout.addWidget(self.progress_bar, 12, 1, alignment=Qt.AlignHCenter) # todo self.on_connect() @@ -213,13 +202,14 @@ class ParameterWindow(QWidget): if self.set_value_label.text() != "Value": self.set_value_label.setText("Value") - + except ValueError: error_text = "Unaccepted value" self.set_value_label.setText( - "<span style='color: red;'>" + error_text + "</span>") + "<span style='color: red;'>" + error_text + "</span>") - def on_edit(self): + @staticmethod + def on_edit(_self): os.startfile('mp4params.json') def on_send(self): @@ -250,8 +240,8 @@ class ParameterWindow(QWidget): value = vals['value'] self.cf.param_set_value(key, sub_key, value) self.num_sent += 1 - self.progress_bar.setValue(int((self.num_sent / self.num_to_send) * - 100)) + self.progress_bar.setValue( + int((self.num_sent / self.num_to_send) * 100)) except queue.Empty: # stop sending once the queue is empty @@ -262,6 +252,3 @@ class ParameterWindow(QWidget): self.num_to_send = 0 self.num_sent = 0 self.progress_bar.setValue(int(0)) - - - diff --git a/pycrocart/PlottingWindow.py b/pycrocart/PlottingWindow.py index f3d4d476b142b9d1820957ac511495ceb6aa7576..34486c145282d1ac0558a6fd9ec8e8c6bd5bee33 100644 --- a/pycrocart/PlottingWindow.py +++ b/pycrocart/PlottingWindow.py @@ -1,11 +1,4 @@ -import sys -from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, \ - QGridLayout, QWidget, QVBoxLayout, QComboBox -from PyQt5.QtCore import Qt, QTimer -from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas -from matplotlib.figure import Figure import numpy as np -from time import time import pyqtgraph as pg @@ -56,9 +49,8 @@ class PlotCanvas(pg.PlotWidget): self.plot_data_ys[:, input_axis]) if max(self.plot_data_xs[-1]) < 10: - self.setXRange(0, 10, padding=0) + self.setXRange(0, 10) # had padding=0 on both these ranges in + # case that's needed else: self.setXRange(max(self.plot_data_xs[-1])-10, - max(self.plot_data_xs[-1]), - padding=0) - + max(self.plot_data_xs[-1])) diff --git a/pycrocart/PyCroCart.py b/pycrocart/PyCroCart.py index 8e5356aba8f171a4a30dac6081188608f14da08c..6e3a3d1681f1968cac68f9451bed7f595b2328b0 100644 --- a/pycrocart/PyCroCart.py +++ b/pycrocart/PyCroCart.py @@ -1,18 +1,6 @@ import sys -from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QGridLayout, \ - QWidget, QVBoxLayout, QComboBox, QTabWidget -from PyQt5.QtCore import Qt, QTimer -from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas -from matplotlib.figure import Figure -import numpy as np -from time import time -import pyqtgraph as pg -from PlottingWindow import PlotCanvas -from LoggingSelectionMenu import LoggingSelectionMenu -from queue import Queue -import queue +from PyQt5.QtWidgets import QApplication, QMainWindow, QTabWidget from CrazyflieProtoConnection import CrazyflieProtoConnection -from SetpointMenu import SetpointMenu from ControlWindow import ControlWindow from SetpointHandler import SetpointHandler from GamepadWizard import InputConfigDialogue @@ -34,9 +22,10 @@ class PyCroCart(QMainWindow): self.tab2 = InputConfigDialogue(self.joystick_reader, self.tab1.setpoint_menu.enableGamepad) self.tab3 = ParameterWindow(cf) - self.tab4 = LoggingConfigWindow(cf) + self.tab4 = LoggingConfigWindow( + cf, self.tab1.logging_menu.update_available_logging_variables) - self.setGeometry(100, 200, 800, 800) + self.setGeometry(100, 200, 600, 600) self.tabs.addTab(self.tab1, "Controls Window") self.tabs.addTab(self.tab2, "Gamepad Configuration") @@ -54,7 +43,7 @@ if __name__ == '__main__': cf1 = CrazyflieProtoConnection() uri = 'radio://0/75/2M/E7E7E7E7E7' - cf1.connect(uri) + # cf1.connect(uri) setpoint_handler1 = SetpointHandler() window = PyCroCart(cf1, setpoint_handler1) diff --git a/pycrocart/SetpointHandler.py b/pycrocart/SetpointHandler.py index 6e40058bc009e8a12c32abc9ecab48fc19353fd2..371241c83b145a116513308b833dc1e72084356e 100644 --- a/pycrocart/SetpointHandler.py +++ b/pycrocart/SetpointHandler.py @@ -104,4 +104,3 @@ class SetpointHandler: """ self.setpoint_semaphore.release() - diff --git a/pycrocart/SetpointMenu.py b/pycrocart/SetpointMenu.py index 18c4d18c7c817c1fc9c51bee7601fbfc7dab9397..cdaa6b323a135d9f6b2b4490033e0e1ed6f3c5c1 100644 --- a/pycrocart/SetpointMenu.py +++ b/pycrocart/SetpointMenu.py @@ -1,11 +1,6 @@ -import sys -import numpy as np -from PyQt5.QtWidgets import QApplication, QWidget, QGridLayout, QLabel, \ - QLineEdit, QSlider, QPushButton, QButtonGroup, QCheckBox, QVBoxLayout -from PyQt5.QtGui import QPainter, QPen, QColor +from PyQt5.QtWidgets import QWidget, QGridLayout, QLabel, QLineEdit, QSlider, \ + QPushButton, QButtonGroup, QCheckBox, QVBoxLayout from PyQt5.QtCore import Qt, QTimer -from time import time -import pyqtgraph as pg from SetpointHandler import SetpointHandler, FlightMode, Setpoint from cfclient.utils.input import JoystickReader from GamepadWizard import DeviceReader diff --git a/pycrocart/crazyflieTestScript.py b/pycrocart/crazyflieTestScript.py index 993c2cb47231ee1a074f36482b00194e6b6fb19d..427d1d848c2007952d3d11c5dd067187d5b4a8ba 100644 --- a/pycrocart/crazyflieTestScript.py +++ b/pycrocart/crazyflieTestScript.py @@ -1,18 +1,8 @@ - import logging import time - import cflib.crtp from cflib.crazyflie import Crazyflie from cflib.crazyflie.syncCrazyflie import SyncCrazyflie -from queue import Queue -from threading import Semaphore -from PyQt5.QtCore import Qt, QTimer - -from cflib.crazyflie.log import LogConfig -from cflib.crazyflie.syncLogger import SyncLogger - -# URI to the Crazyflie to connect to # Only output errors from the logging framework logging.basicConfig(level=logging.ERROR) @@ -28,39 +18,45 @@ def simple_connect(): def log_stab_callback(timestamp, data, logconf): print('[%d][%s]: %s' % (timestamp, logconf.name, data)) -def simple_log_async(scf, logconf): - cf = scf.cf + +def simple_log_async(scf1, logconf): + cf = scf1.cf cf.log.add_config(logconf) logconf.data_received_cb.add_callback(log_stab_callback) logconf.start() time.sleep(50) logconf.stop() -def get_param_toc(scf): - toc = scf.cf.param.values +def get_param_toc(scf1): + + toc = scf1.cf.param.values print(len(toc)) return toc -def get_logging_toc(scf): - toc = scf.cf.log.toc.toc +def get_logging_toc(scf1): + + toc = scf1.cf.log.toc.toc print(len(toc)) return toc -def set_param(scf, group: str, name: str, value: float): + +def set_param(scf1, group: str, name: str, value: float): full_name = group + '.' + name - scf.cf.param.add_update_callback(group=group, name=name, cb=done_set_param) + scf1.cf.param.add_update_callback(group=group, name=name, cb=done_set_param) time.sleep(1) - scf.cf.param.set_value(full_name, value) + scf1.cf.param.set_value(full_name, value) time.sleep(1) -def done_set_param(*args): + +def done_set_param(*_args): print("Done setting param") + def find_available_crazyflies(): cflib.crtp.init_drivers() @@ -80,4 +76,3 @@ if __name__ == '__main__': scf.wait_for_params() print("Done") - diff --git a/pycrocart/uCartCommander.py b/pycrocart/uCartCommander.py index 5efa3f010af477b8d00e559d44f734ea1e04ceae..389df4e8ef0d7074bbd2f451cb2146b67342f9cc 100644 --- a/pycrocart/uCartCommander.py +++ b/pycrocart/uCartCommander.py @@ -65,7 +65,7 @@ class Commander: def __init__(self, crazyflie=None): """ - Initialize the commander object. By default the commander is in + Initialize the commander object. By default, the commander is in +-mode (not x-mode). """ self._cf = crazyflie @@ -80,12 +80,15 @@ class Commander: def send_setpoint(self, roll, pitch, yawrate, thrust): """ - Send a new control setpoint for roll/pitch/yaw_Rate/thrust to the copter. - The meaning of these values is depended on the mode of the RPYT commander in the firmware + Send a new control setpoint for roll/pitch/yaw_Rate/thrust to the + copter. + The meaning of these values is depended on the mode of the RPYT + commander in the firmware Default settings are Roll, pitch, yawrate and thrust roll, pitch are in degrees yawrate is in degrees/s - thrust is an integer value ranging from 10001 (next to no power) to 60000 (full power) + thrust is an integer value ranging from 10001 (next to no power) to + 60000 (full power) """ if thrust > 0xFFFF or thrust < 0: raise ValueError('Thrust must be between 0 and 0xFFFF') @@ -100,7 +103,8 @@ class Commander: def send_notify_setpoint_stop(self, remain_valid_milliseconds=0): """ - Sends a packet so that the priority of the current setpoint to the lowest non-disabled value, + Sends a packet so that the priority of the current setpoint to the + lowest non-disabled value, so any new setpoint regardless of source will overwrite it. """ pk = CRTPPacket() @@ -112,7 +116,7 @@ class Commander: def send_stop_setpoint(self): """ - Send STOP setpoing, stopping the motors and (potentially) falling. + Send STOP setpoint, stopping the motors and (potentially) falling. """ pk = CRTPPacket() pk.port = CRTPPort.COMMANDER_GENERIC @@ -121,7 +125,8 @@ class Commander: def send_velocity_world_setpoint(self, vx, vy, vz, yawrate): """ - Send Velocity in the world frame of reference setpoint with yawrate commands + Send Velocity in the world frame of reference setpoint with yawrate + commands vx, vy, vz are in m/s yawrate is in degrees/s """ @@ -134,8 +139,9 @@ class Commander: def send_zdistance_setpoint(self, roll, pitch, yawrate, zdistance): """ - Control mode where the height is send as an absolute setpoint (intended - to be the distance to the surface under the Crazflie), while giving roll, + Control mode where the height is sent as an absolute setpoint (intended + to be the distance to the surface under the Crazflie), + while giving roll, pitch and yaw rate commands roll, pitch are in degrees yawrate is in degrees/s @@ -150,8 +156,9 @@ class Commander: def send_hover_setpoint(self, vx, vy, yawrate, zdistance): """ - Control mode where the height is send as an absolute setpoint (intended - to be the distance to the surface under the Crazflie), while giving x, y velocity + Control mode where the height is sent as an absolute setpoint (intended + to be the distance to the surface under the Crazflie), while giving x, + y velocity commands in body-fixed coordinates. vx, vy are in m/s yawrate is in degrees/s @@ -166,7 +173,8 @@ class Commander: def send_position_setpoint(self, x, y, z, yaw): """ - Control mode where the position is sent as absolute (world) x,y,z coordinate in + Control mode where the position is sent as absolute (world) x,y,z + coordinate in meter and the yaw is the absolute orientation. x, y, z are in m yaw is in degrees @@ -219,4 +227,3 @@ class Commander: self._cf.send_packet(pk) # todo confirm struct is right , I tried to # format it using H for the int of thrust and f for # floats otherwise. Kinda looks like what is above -