cfclient 2017.4__py3-none-any.whl → 2025.12.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. cfclient/__init__.py +16 -11
  2. cfclient/configs/config.json +4 -3
  3. cfclient/configs/input/Generic_OS_X.json +1 -0
  4. cfclient/configs/input/Joystick.json +1 -0
  5. cfclient/configs/input/PS3_Mode_1.json +1 -0
  6. cfclient/configs/input/PS3_Mode_2.json +1 -0
  7. cfclient/configs/input/PS3_Mode_3.json +1 -0
  8. cfclient/configs/input/PS4_Mode_1.json +1 -0
  9. cfclient/configs/input/PS4_Mode_2.json +1 -0
  10. cfclient/configs/input/PS4_shoulder_btns_yaw.json +1 -0
  11. cfclient/configs/input/xbox360_mode1.json +1 -0
  12. cfclient/configs/log/PID_tuning/Attitude.json +46 -0
  13. cfclient/configs/log/PID_tuning/Attitude_rate.json +46 -0
  14. cfclient/configs/log/PID_tuning/Position.json +46 -0
  15. cfclient/configs/log/PID_tuning/Velocity.json +46 -0
  16. cfclient/configs/log/PID_tuning_components/Pitch.json +22 -0
  17. cfclient/configs/log/PID_tuning_components/Pitch_rate.json +22 -0
  18. cfclient/configs/log/PID_tuning_components/Position_x.json +22 -0
  19. cfclient/configs/log/PID_tuning_components/Position_y.json +22 -0
  20. cfclient/configs/log/PID_tuning_components/Position_z.json +22 -0
  21. cfclient/configs/log/PID_tuning_components/Roll.json +22 -0
  22. cfclient/configs/log/PID_tuning_components/Roll_rate.json +22 -0
  23. cfclient/configs/log/PID_tuning_components/Velocity_x.json +22 -0
  24. cfclient/configs/log/PID_tuning_components/Velocity_y.json +22 -0
  25. cfclient/configs/log/PID_tuning_components/Velocity_z.json +22 -0
  26. cfclient/configs/log/PID_tuning_components/Yaw.json +22 -0
  27. cfclient/configs/log/PID_tuning_components/Yaw_rate.json +22 -0
  28. cfclient/gui.py +44 -9
  29. cfclient/headless.py +3 -12
  30. cfclient/resources/log_param_doc.json +1 -0
  31. cfclient/ui/connectivity_manager.py +198 -0
  32. cfclient/ui/dialogs/about.py +53 -36
  33. cfclient/ui/dialogs/about.ui +23 -3
  34. cfclient/ui/dialogs/anchor_position_dialog.py +252 -0
  35. cfclient/ui/dialogs/anchor_position_dialog.ui +138 -0
  36. cfclient/ui/dialogs/basestation_mode_dialog.py +185 -0
  37. cfclient/ui/dialogs/basestation_mode_dialog.ui +186 -0
  38. cfclient/ui/dialogs/bootloader.py +448 -85
  39. cfclient/ui/dialogs/bootloader.ui +387 -134
  40. cfclient/ui/dialogs/cf2config.py +4 -4
  41. cfclient/ui/dialogs/cf2config.ui +3 -4
  42. cfclient/ui/dialogs/inputconfigdialogue.py +24 -19
  43. cfclient/ui/dialogs/inputconfigdialogue.ui +53 -30
  44. cfclient/ui/dialogs/lighthouse_bs_geometry_dialog.py +220 -0
  45. cfclient/ui/dialogs/lighthouse_bs_geometry_dialog.ui +110 -0
  46. cfclient/ui/dialogs/lighthouse_system_type_dialog.py +93 -0
  47. cfclient/ui/dialogs/lighthouse_system_type_dialog.ui +121 -0
  48. cfclient/ui/dialogs/logconfigdialogue.py +401 -101
  49. cfclient/ui/dialogs/logconfigdialogue.ui +117 -72
  50. cfclient/ui/icons/bl.webp +0 -0
  51. cfclient/ui/icons/bolt.webp +0 -0
  52. cfclient/ui/icons/cf21.webp +0 -0
  53. cfclient/ui/icons/checkmark_black.png +0 -0
  54. cfclient/ui/icons/checkmark_white.png +0 -0
  55. cfclient/ui/icons/create.png +0 -0
  56. cfclient/ui/icons/delete.png +0 -0
  57. cfclient/ui/icons/flapper.webp +0 -0
  58. cfclient/ui/icons/tag.webp +0 -0
  59. cfclient/ui/main.py +328 -258
  60. cfclient/ui/main.ui +184 -80
  61. cfclient/ui/pluginhelper.py +7 -1
  62. cfclient/ui/pose_logger.py +116 -0
  63. cfclient/ui/tab_toolbox.py +208 -0
  64. cfclient/ui/tabs/ColorLEDTab.py +752 -0
  65. cfclient/ui/tabs/ConsoleTab.py +48 -13
  66. cfclient/ui/{toolboxes → tabs}/CrtpSharkToolbox.py +19 -34
  67. cfclient/ui/tabs/ExampleTab.py +9 -16
  68. cfclient/ui/tabs/FlightTab.py +437 -325
  69. cfclient/ui/tabs/GpsTab.py +14 -20
  70. cfclient/ui/tabs/LEDRingTab.py +277 -0
  71. cfclient/ui/tabs/LogBlockDebugTab.py +20 -27
  72. cfclient/ui/tabs/LogBlockTab.py +35 -35
  73. cfclient/ui/tabs/LogClientTab.py +85 -0
  74. cfclient/ui/tabs/LogTab.py +50 -27
  75. cfclient/ui/tabs/ParamTab.py +443 -57
  76. cfclient/ui/tabs/PlotTab.py +23 -25
  77. cfclient/ui/tabs/TuningTab.py +292 -0
  78. cfclient/ui/tabs/__init__.py +12 -2
  79. cfclient/ui/tabs/colorLEDTab.ui +624 -0
  80. cfclient/ui/tabs/consoleTab.ui +46 -0
  81. cfclient/ui/tabs/flightActionContainer.ui +103 -0
  82. cfclient/ui/tabs/flightTab.ui +724 -237
  83. cfclient/ui/tabs/{ledTab.ui → ledRingTab.ui} +63 -46
  84. cfclient/ui/tabs/lighthouse_tab.py +714 -0
  85. cfclient/ui/tabs/lighthouse_tab.ui +430 -0
  86. cfclient/ui/tabs/locopositioning_tab.py +606 -389
  87. cfclient/ui/tabs/locopositioning_tab.ui +370 -253
  88. cfclient/ui/tabs/logClientTab.ui +52 -0
  89. cfclient/ui/tabs/logTab.ui +1 -1
  90. cfclient/ui/tabs/paramTab.ui +204 -3
  91. cfclient/ui/tabs/tuningTab.ui +773 -0
  92. cfclient/ui/widgets/ai.py +37 -39
  93. cfclient/ui/widgets/hexspinbox.py +16 -10
  94. cfclient/ui/widgets/plotter.ui +39 -47
  95. cfclient/ui/widgets/plotwidget.py +57 -22
  96. cfclient/ui/widgets/super_slider.py +112 -0
  97. cfclient/ui/wizards/__init__.py +0 -0
  98. cfclient/ui/wizards/bslh_1.png +0 -0
  99. cfclient/ui/wizards/bslh_2.png +0 -0
  100. cfclient/ui/wizards/bslh_3.png +0 -0
  101. cfclient/ui/wizards/bslh_4.png +0 -0
  102. cfclient/ui/wizards/bslh_5.png +0 -0
  103. cfclient/ui/wizards/lighthouse_geo_bs_estimation_wizard.py +465 -0
  104. cfclient/utils/config_manager.py +5 -4
  105. cfclient/utils/input/__init__.py +77 -19
  106. cfclient/utils/input/inputinterfaces/wiimote.py +2 -2
  107. cfclient/utils/input/inputreaderinterface.py +17 -7
  108. cfclient/utils/input/inputreaders/__init__.py +17 -0
  109. cfclient/utils/logconfigreader.py +245 -25
  110. cfclient/utils/logdatawriter.py +3 -1
  111. cfclient/utils/periodictimer.py +1 -1
  112. cfclient/utils/ui.py +336 -0
  113. cfclient/utils/zmq_led_driver.py +5 -0
  114. cfclient/utils/zmq_param.py +6 -0
  115. cfclient/version.py +34 -1
  116. cfclient-2025.12.1.dist-info/METADATA +70 -0
  117. cfclient-2025.12.1.dist-info/RECORD +152 -0
  118. {cfclient-2017.4.dist-info → cfclient-2025.12.1.dist-info}/WHEEL +1 -1
  119. {cfclient-2017.4.dist-info → cfclient-2025.12.1.dist-info}/entry_points.txt +0 -1
  120. cfclient-2025.12.1.dist-info/licenses/LICENSE.txt +350 -0
  121. {cfclient-2017.4.dist-info → cfclient-2025.12.1.dist-info}/top_level.txt +1 -0
  122. cfconfig/Makefile +51 -0
  123. cfconfig/configblock.py +111 -0
  124. cfloader/__init__.py +41 -55
  125. cfzmq/__init__.py +22 -14
  126. cfclient/ui/dialogs/cf1config.py +0 -265
  127. cfclient/ui/dialogs/cf1config.ui +0 -260
  128. cfclient/ui/tab.py +0 -96
  129. cfclient/ui/tabs/LEDTab.py +0 -169
  130. cfclient/ui/toolboxes/ConsoleToolbox.py +0 -69
  131. cfclient/ui/toolboxes/DebugDriverToolbox.py +0 -107
  132. cfclient/ui/toolboxes/__init__.py +0 -45
  133. cfclient/ui/toolboxes/consoleToolbox.ui +0 -62
  134. cfclient/ui/toolboxes/debugDriverToolbox.ui +0 -86
  135. cfclient-2017.4.dist-info/DESCRIPTION.rst +0 -3
  136. cfclient-2017.4.dist-info/METADATA +0 -22
  137. cfclient-2017.4.dist-info/RECORD +0 -104
  138. cfclient-2017.4.dist-info/metadata.json +0 -1
  139. /cfclient/{icon-256.png → ui/icons/icon-256.png} +0 -0
  140. /cfclient/ui/{toolboxes → tabs}/crtpSharkToolbox.ui +0 -0
@@ -7,7 +7,7 @@
7
7
  # +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
8
8
  # || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
9
9
  #
10
- # Copyright (C) 2011-2013 Bitcraze AB
10
+ # Copyright (C) 2011-2023 Bitcraze AB
11
11
  #
12
12
  # Crazyflie Nano Quadcopter Client
13
13
  #
@@ -31,11 +31,12 @@ The console tab is used as a console for printouts from the Crazyflie.
31
31
 
32
32
  import logging
33
33
 
34
- from PyQt5 import uic
35
- from PyQt5.QtCore import pyqtSignal
34
+ from PyQt6 import uic
35
+ from PyQt6.QtCore import pyqtSignal
36
+ from PyQt6.QtGui import QTextCursor
36
37
 
37
38
  import cfclient
38
- from cfclient.ui.tab import Tab
39
+ from cfclient.ui.tab_toolbox import TabToolbox
39
40
 
40
41
  __author__ = 'Bitcraze AB'
41
42
  __all__ = ['ConsoleTab']
@@ -46,30 +47,27 @@ console_tab_class = uic.loadUiType(cfclient.module_path +
46
47
  "/ui/tabs/consoleTab.ui")[0]
47
48
 
48
49
 
49
- class ConsoleTab(Tab, console_tab_class):
50
+ class ConsoleTab(TabToolbox, console_tab_class):
50
51
  """Console tab for showing printouts from Crazyflie"""
52
+ _link_established_signal = pyqtSignal(str)
51
53
  _connected_signal = pyqtSignal(str)
52
54
  _disconnected_signal = pyqtSignal(str)
53
55
  _update = pyqtSignal(str)
54
56
 
55
- def __init__(self, tabWidget, helper, *args):
56
- super(ConsoleTab, self).__init__(*args)
57
+ def __init__(self, helper):
58
+ super(ConsoleTab, self).__init__(helper, 'Console')
57
59
  self.setupUi(self)
58
60
 
59
- self.tabName = "Console"
60
- self.menuName = "Console"
61
-
62
- self.tabWidget = tabWidget
63
- self._helper = helper
64
-
65
61
  # Always wrap callbacks from Crazyflie API though QT Signal/Slots
66
62
  # to avoid manipulating the UI when rendering it
63
+ self._link_established_signal.connect(self._link_established)
67
64
  self._connected_signal.connect(self._connected)
68
65
  self._disconnected_signal.connect(self._disconnected)
69
66
  self._update.connect(self.printText)
70
67
 
71
68
  self._helper.cf.console.receivedChar.add_callback(self._update.emit)
72
69
  self._helper.cf.connected.add_callback(self._connected_signal.emit)
70
+ self._helper.cf.link_established.add_callback(self._link_established_signal.emit)
73
71
  self._helper.cf.disconnected.add_callback(
74
72
  self._disconnected_signal.emit)
75
73
 
@@ -77,20 +75,57 @@ class ConsoleTab(Tab, console_tab_class):
77
75
  self._dumpSystemLoadButton.clicked.connect(
78
76
  lambda enabled:
79
77
  self._helper.cf.param.set_value("system.taskDump", '1'))
78
+ self._dumpAssertInformation.clicked.connect(
79
+ lambda enabled:
80
+ self._helper.cf.param.set_value_raw("system.assertInfo", 0x08, 1))
81
+ self._propellerTestButton.clicked.connect(
82
+ lambda enabled:
83
+ self._helper.cf.param.set_value("health.startPropTest", '1'))
84
+ self._batteryTestButton.clicked.connect(
85
+ lambda enabled:
86
+ self._helper.cf.param.set_value("health.startBatTest", '1'))
87
+ self._storageStatsButton.clicked.connect(
88
+ lambda enabled:
89
+ self._helper.cf.param.set_value("system.storageStats", '1'))
80
90
 
81
91
  def printText(self, text):
82
92
  # Make sure we get printouts from the Crazyflie into the log (such as
83
93
  # build version and test ok/fail)
84
94
  logger.debug("[%s]", text)
95
+ scrollbar = self.console.verticalScrollBar()
96
+ prev_scroll = scrollbar.value()
97
+ prev_cursor = self.console.textCursor()
98
+ was_maximum = prev_scroll == scrollbar.maximum()
99
+
100
+ self.console.moveCursor(QTextCursor.MoveOperation.End)
85
101
  self.console.insertPlainText(text)
86
102
 
103
+ self.console.setTextCursor(prev_cursor)
104
+
105
+ if was_maximum and not prev_cursor.hasSelection():
106
+ scrollbar.setValue(scrollbar.maximum())
107
+ else:
108
+ scrollbar.setValue(prev_scroll)
109
+
87
110
  def clear(self):
88
111
  self.console.clear()
89
112
 
90
113
  def _connected(self, link_uri):
91
114
  """Callback when the Crazyflie has been connected"""
92
115
  self._dumpSystemLoadButton.setEnabled(True)
116
+ self._propellerTestButton.setEnabled(True)
117
+ self._batteryTestButton.setEnabled(True)
118
+ self._storageStatsButton.setEnabled(True)
93
119
 
94
120
  def _disconnected(self, link_uri):
95
121
  """Callback for when the Crazyflie has been disconnected"""
96
122
  self._dumpSystemLoadButton.setEnabled(False)
123
+ self._dumpAssertInformation.setEnabled(False)
124
+ self._propellerTestButton.setEnabled(False)
125
+ self._batteryTestButton.setEnabled(False)
126
+ self._storageStatsButton.setEnabled(False)
127
+
128
+ def _link_established(self, link_uri):
129
+ """Callback when the first packet on a new link is received"""
130
+ # Enable the assert dump button as early as possible. After an assert we will never get the connected() cb.
131
+ self._dumpAssertInformation.setEnabled(True)
@@ -7,7 +7,7 @@
7
7
  # +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
8
8
  # || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
9
9
  #
10
- # Copyright (C) 2011-2013 Bitcraze AB
10
+ # Copyright (C) 2011-2023 Bitcraze AB
11
11
  #
12
12
  # Crazyflie Nano Quadcopter Client
13
13
  #
@@ -31,33 +31,31 @@ import os
31
31
  from time import time
32
32
  from binascii import hexlify
33
33
 
34
- from PyQt5 import QtWidgets
35
- from PyQt5 import uic
36
- from PyQt5.QtCore import pyqtSignal
37
- from PyQt5.QtCore import pyqtSlot
38
- from PyQt5.QtCore import Qt
34
+ from PyQt6 import QtWidgets
35
+ from PyQt6 import uic
36
+ from PyQt6.QtCore import pyqtSignal
37
+ from PyQt6.QtCore import pyqtSlot
38
+ from PyQt6.QtCore import Qt
39
39
 
40
40
  import cfclient
41
+ from cfclient.ui.tab_toolbox import TabToolbox
41
42
 
42
43
  __author__ = 'Bitcraze AB'
43
44
  __all__ = ['CrtpSharkToolbox']
44
45
 
45
- param_tab_class = uic.loadUiType(
46
- cfclient.module_path + "/ui/toolboxes/crtpSharkToolbox.ui")[0]
46
+ param_tab_class = uic.loadUiType(cfclient.module_path + "/ui/tabs/crtpSharkToolbox.ui")[0]
47
47
 
48
48
 
49
- class CrtpSharkToolbox(QtWidgets.QWidget, param_tab_class):
49
+ class CrtpSharkToolbox(TabToolbox, param_tab_class):
50
50
  """Show packets that is sent vie the communication link"""
51
51
  nameModified = pyqtSignal()
52
52
  _incoming_packet_signal = pyqtSignal(object)
53
53
  _outgoing_packet_signal = pyqtSignal(object)
54
54
 
55
- def __init__(self, helper, *args):
56
- super(CrtpSharkToolbox, self).__init__(*args)
55
+ def __init__(self, helper):
56
+ super(CrtpSharkToolbox, self).__init__(helper, 'Crtp sniffer')
57
57
  self.setupUi(self)
58
58
 
59
- self.helper = helper
60
-
61
59
  # Init the tree widget
62
60
  self.logTree.setHeaderLabels(['ms', 'Direction', 'Port/Chan', 'Data'])
63
61
 
@@ -77,11 +75,11 @@ class CrtpSharkToolbox(QtWidgets.QWidget, param_tab_class):
77
75
  line = QtWidgets.QTreeWidgetItem()
78
76
 
79
77
  ms_diff = int(round(time() * 1000)) - self._ms_offset
80
- line.setData(0, Qt.DisplayRole, "%d" % ms_diff)
81
- line.setData(1, Qt.DisplayRole, "%s" % dir)
82
- line.setData(2, Qt.DisplayRole, "%d/%d" % (pk.port, pk.channel))
78
+ line.setData(0, Qt.ItemDataRole.DisplayRole, "%d" % ms_diff)
79
+ line.setData(1, Qt.ItemDataRole.DisplayRole, "%s" % dir)
80
+ line.setData(2, Qt.ItemDataRole.DisplayRole, "%d/%d" % (pk.port, pk.channel))
83
81
 
84
- line.setData(3, Qt.DisplayRole, hexlify(pk.data).decode('utf8'))
82
+ line.setData(3, Qt.ItemDataRole.DisplayRole, hexlify(pk.data).decode('utf8'))
85
83
 
86
84
  s = "%d, %s, %d/%d, %s" % (ms_diff, dir, pk.port, pk.channel,
87
85
  hexlify(pk.data).decode('utf8'))
@@ -95,12 +93,6 @@ class CrtpSharkToolbox(QtWidgets.QWidget, param_tab_class):
95
93
  self.logTree.clear()
96
94
  self._data = []
97
95
 
98
- def getName(self):
99
- return 'Crtp sniffer'
100
-
101
- def getTabName(self):
102
- return 'Crtp sniffer'
103
-
104
96
  def _incoming_packet(self, pk):
105
97
  self._incoming_packet_signal.emit(pk)
106
98
 
@@ -108,19 +100,12 @@ class CrtpSharkToolbox(QtWidgets.QWidget, param_tab_class):
108
100
  self._outgoing_packet_signal.emit(pk)
109
101
 
110
102
  def enable(self):
111
- self.helper.cf.packet_received.add_callback(
112
- self._incoming_packet)
113
- self.helper.cf.packet_sent.add_callback(
114
- self._outgoing_packet)
103
+ self._helper.cf.packet_received.add_callback(self._incoming_packet)
104
+ self._helper.cf.packet_sent.add_callback(self._outgoing_packet)
115
105
 
116
106
  def disable(self):
117
- self.helper.cf.packet_received.remove_callback(
118
- self._incoming_packet)
119
- self.helper.cf.packet_sent.remove_callback(
120
- self._outgoing_packet)
121
-
122
- def preferedDockArea(self):
123
- return Qt.RightDockWidgetArea
107
+ self._helper.cf.packet_received.remove_callback(self._incoming_packet)
108
+ self._helper.cf.packet_sent.remove_callback(self._outgoing_packet)
124
109
 
125
110
  def _save_data(self):
126
111
  dir = os.path.join(cfclient.config_path, "logdata")
@@ -7,7 +7,7 @@
7
7
  # +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
8
8
  # || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
9
9
  #
10
- # Copyright (C) 2011-2013 Bitcraze AB
10
+ # Copyright (C) 2011-2023 Bitcraze AB
11
11
  #
12
12
  # Crazyflie Nano Quadcopter Client
13
13
  #
@@ -34,23 +34,22 @@ connects the connected/disconnected callbacks.
34
34
 
35
35
  import logging
36
36
 
37
- from PyQt5 import uic
38
- from PyQt5.QtCore import pyqtSignal
39
- from PyQt5.QtWidgets import QMessageBox
37
+ from PyQt6 import uic
38
+ from PyQt6.QtCore import pyqtSignal
39
+ from PyQt6.QtWidgets import QMessageBox
40
40
 
41
41
  import cfclient
42
- from cfclient.ui.tab import Tab
42
+ from cfclient.ui.tab_toolbox import TabToolbox
43
43
 
44
44
  __author__ = 'Bitcraze AB'
45
45
  __all__ = ['ExampleTab']
46
46
 
47
47
  logger = logging.getLogger(__name__)
48
48
 
49
- example_tab_class = uic.loadUiType(cfclient.module_path +
50
- "/ui/tabs/exampleTab.ui")[0]
49
+ example_tab_class = uic.loadUiType(cfclient.module_path + "/ui/tabs/exampleTab.ui")[0]
51
50
 
52
51
 
53
- class ExampleTab(Tab, example_tab_class):
52
+ class ExampleTab(TabToolbox, example_tab_class):
54
53
  """Tab for plotting logging data"""
55
54
 
56
55
  _connected_signal = pyqtSignal(str)
@@ -59,16 +58,10 @@ class ExampleTab(Tab, example_tab_class):
59
58
  _log_error_signal = pyqtSignal(object, str)
60
59
  _param_updated_signal = pyqtSignal(str, str)
61
60
 
62
- def __init__(self, tabWidget, helper, *args):
63
- super(ExampleTab, self).__init__(*args)
61
+ def __init__(self, helper):
62
+ super(ExampleTab, self).__init__(helper, 'Example')
64
63
  self.setupUi(self)
65
64
 
66
- self.tabName = "Example"
67
- self.menuName = "Example Tab"
68
- self.tabWidget = tabWidget
69
-
70
- self._helper = helper
71
-
72
65
  # Always wrap callbacks from Crazyflie API though QT Signal/Slots
73
66
  # to avoid manipulating the UI when rendering it
74
67
  self._connected_signal.connect(self._connected)