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.
- cfclient/__init__.py +16 -11
- cfclient/configs/config.json +4 -3
- cfclient/configs/input/Generic_OS_X.json +1 -0
- cfclient/configs/input/Joystick.json +1 -0
- cfclient/configs/input/PS3_Mode_1.json +1 -0
- cfclient/configs/input/PS3_Mode_2.json +1 -0
- cfclient/configs/input/PS3_Mode_3.json +1 -0
- cfclient/configs/input/PS4_Mode_1.json +1 -0
- cfclient/configs/input/PS4_Mode_2.json +1 -0
- cfclient/configs/input/PS4_shoulder_btns_yaw.json +1 -0
- cfclient/configs/input/xbox360_mode1.json +1 -0
- cfclient/configs/log/PID_tuning/Attitude.json +46 -0
- cfclient/configs/log/PID_tuning/Attitude_rate.json +46 -0
- cfclient/configs/log/PID_tuning/Position.json +46 -0
- cfclient/configs/log/PID_tuning/Velocity.json +46 -0
- cfclient/configs/log/PID_tuning_components/Pitch.json +22 -0
- cfclient/configs/log/PID_tuning_components/Pitch_rate.json +22 -0
- cfclient/configs/log/PID_tuning_components/Position_x.json +22 -0
- cfclient/configs/log/PID_tuning_components/Position_y.json +22 -0
- cfclient/configs/log/PID_tuning_components/Position_z.json +22 -0
- cfclient/configs/log/PID_tuning_components/Roll.json +22 -0
- cfclient/configs/log/PID_tuning_components/Roll_rate.json +22 -0
- cfclient/configs/log/PID_tuning_components/Velocity_x.json +22 -0
- cfclient/configs/log/PID_tuning_components/Velocity_y.json +22 -0
- cfclient/configs/log/PID_tuning_components/Velocity_z.json +22 -0
- cfclient/configs/log/PID_tuning_components/Yaw.json +22 -0
- cfclient/configs/log/PID_tuning_components/Yaw_rate.json +22 -0
- cfclient/gui.py +44 -9
- cfclient/headless.py +3 -12
- cfclient/resources/log_param_doc.json +1 -0
- cfclient/ui/connectivity_manager.py +198 -0
- cfclient/ui/dialogs/about.py +53 -36
- cfclient/ui/dialogs/about.ui +23 -3
- cfclient/ui/dialogs/anchor_position_dialog.py +252 -0
- cfclient/ui/dialogs/anchor_position_dialog.ui +138 -0
- cfclient/ui/dialogs/basestation_mode_dialog.py +185 -0
- cfclient/ui/dialogs/basestation_mode_dialog.ui +186 -0
- cfclient/ui/dialogs/bootloader.py +448 -85
- cfclient/ui/dialogs/bootloader.ui +387 -134
- cfclient/ui/dialogs/cf2config.py +4 -4
- cfclient/ui/dialogs/cf2config.ui +3 -4
- cfclient/ui/dialogs/inputconfigdialogue.py +24 -19
- cfclient/ui/dialogs/inputconfigdialogue.ui +53 -30
- cfclient/ui/dialogs/lighthouse_bs_geometry_dialog.py +220 -0
- cfclient/ui/dialogs/lighthouse_bs_geometry_dialog.ui +110 -0
- cfclient/ui/dialogs/lighthouse_system_type_dialog.py +93 -0
- cfclient/ui/dialogs/lighthouse_system_type_dialog.ui +121 -0
- cfclient/ui/dialogs/logconfigdialogue.py +401 -101
- cfclient/ui/dialogs/logconfigdialogue.ui +117 -72
- cfclient/ui/icons/bl.webp +0 -0
- cfclient/ui/icons/bolt.webp +0 -0
- cfclient/ui/icons/cf21.webp +0 -0
- cfclient/ui/icons/checkmark_black.png +0 -0
- cfclient/ui/icons/checkmark_white.png +0 -0
- cfclient/ui/icons/create.png +0 -0
- cfclient/ui/icons/delete.png +0 -0
- cfclient/ui/icons/flapper.webp +0 -0
- cfclient/ui/icons/tag.webp +0 -0
- cfclient/ui/main.py +328 -258
- cfclient/ui/main.ui +184 -80
- cfclient/ui/pluginhelper.py +7 -1
- cfclient/ui/pose_logger.py +116 -0
- cfclient/ui/tab_toolbox.py +208 -0
- cfclient/ui/tabs/ColorLEDTab.py +752 -0
- cfclient/ui/tabs/ConsoleTab.py +48 -13
- cfclient/ui/{toolboxes → tabs}/CrtpSharkToolbox.py +19 -34
- cfclient/ui/tabs/ExampleTab.py +9 -16
- cfclient/ui/tabs/FlightTab.py +437 -325
- cfclient/ui/tabs/GpsTab.py +14 -20
- cfclient/ui/tabs/LEDRingTab.py +277 -0
- cfclient/ui/tabs/LogBlockDebugTab.py +20 -27
- cfclient/ui/tabs/LogBlockTab.py +35 -35
- cfclient/ui/tabs/LogClientTab.py +85 -0
- cfclient/ui/tabs/LogTab.py +50 -27
- cfclient/ui/tabs/ParamTab.py +443 -57
- cfclient/ui/tabs/PlotTab.py +23 -25
- cfclient/ui/tabs/TuningTab.py +292 -0
- cfclient/ui/tabs/__init__.py +12 -2
- cfclient/ui/tabs/colorLEDTab.ui +624 -0
- cfclient/ui/tabs/consoleTab.ui +46 -0
- cfclient/ui/tabs/flightActionContainer.ui +103 -0
- cfclient/ui/tabs/flightTab.ui +724 -237
- cfclient/ui/tabs/{ledTab.ui → ledRingTab.ui} +63 -46
- cfclient/ui/tabs/lighthouse_tab.py +714 -0
- cfclient/ui/tabs/lighthouse_tab.ui +430 -0
- cfclient/ui/tabs/locopositioning_tab.py +606 -389
- cfclient/ui/tabs/locopositioning_tab.ui +370 -253
- cfclient/ui/tabs/logClientTab.ui +52 -0
- cfclient/ui/tabs/logTab.ui +1 -1
- cfclient/ui/tabs/paramTab.ui +204 -3
- cfclient/ui/tabs/tuningTab.ui +773 -0
- cfclient/ui/widgets/ai.py +37 -39
- cfclient/ui/widgets/hexspinbox.py +16 -10
- cfclient/ui/widgets/plotter.ui +39 -47
- cfclient/ui/widgets/plotwidget.py +57 -22
- cfclient/ui/widgets/super_slider.py +112 -0
- cfclient/ui/wizards/__init__.py +0 -0
- cfclient/ui/wizards/bslh_1.png +0 -0
- cfclient/ui/wizards/bslh_2.png +0 -0
- cfclient/ui/wizards/bslh_3.png +0 -0
- cfclient/ui/wizards/bslh_4.png +0 -0
- cfclient/ui/wizards/bslh_5.png +0 -0
- cfclient/ui/wizards/lighthouse_geo_bs_estimation_wizard.py +465 -0
- cfclient/utils/config_manager.py +5 -4
- cfclient/utils/input/__init__.py +77 -19
- cfclient/utils/input/inputinterfaces/wiimote.py +2 -2
- cfclient/utils/input/inputreaderinterface.py +17 -7
- cfclient/utils/input/inputreaders/__init__.py +17 -0
- cfclient/utils/logconfigreader.py +245 -25
- cfclient/utils/logdatawriter.py +3 -1
- cfclient/utils/periodictimer.py +1 -1
- cfclient/utils/ui.py +336 -0
- cfclient/utils/zmq_led_driver.py +5 -0
- cfclient/utils/zmq_param.py +6 -0
- cfclient/version.py +34 -1
- cfclient-2025.12.1.dist-info/METADATA +70 -0
- cfclient-2025.12.1.dist-info/RECORD +152 -0
- {cfclient-2017.4.dist-info → cfclient-2025.12.1.dist-info}/WHEEL +1 -1
- {cfclient-2017.4.dist-info → cfclient-2025.12.1.dist-info}/entry_points.txt +0 -1
- cfclient-2025.12.1.dist-info/licenses/LICENSE.txt +350 -0
- {cfclient-2017.4.dist-info → cfclient-2025.12.1.dist-info}/top_level.txt +1 -0
- cfconfig/Makefile +51 -0
- cfconfig/configblock.py +111 -0
- cfloader/__init__.py +41 -55
- cfzmq/__init__.py +22 -14
- cfclient/ui/dialogs/cf1config.py +0 -265
- cfclient/ui/dialogs/cf1config.ui +0 -260
- cfclient/ui/tab.py +0 -96
- cfclient/ui/tabs/LEDTab.py +0 -169
- cfclient/ui/toolboxes/ConsoleToolbox.py +0 -69
- cfclient/ui/toolboxes/DebugDriverToolbox.py +0 -107
- cfclient/ui/toolboxes/__init__.py +0 -45
- cfclient/ui/toolboxes/consoleToolbox.ui +0 -62
- cfclient/ui/toolboxes/debugDriverToolbox.ui +0 -86
- cfclient-2017.4.dist-info/DESCRIPTION.rst +0 -3
- cfclient-2017.4.dist-info/METADATA +0 -22
- cfclient-2017.4.dist-info/RECORD +0 -104
- cfclient-2017.4.dist-info/metadata.json +0 -1
- /cfclient/{icon-256.png → ui/icons/icon-256.png} +0 -0
- /cfclient/ui/{toolboxes → tabs}/crtpSharkToolbox.ui +0 -0
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
#
|
|
4
|
+
# || ____ _ __
|
|
5
|
+
# +------+ / __ )(_) /_______________ _____ ___
|
|
6
|
+
# | 0xBC | / __ / / __/ ___/ ___/ __ `/_ / / _ \
|
|
7
|
+
# +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
|
|
8
|
+
# || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
|
|
9
|
+
#
|
|
10
|
+
# Copyright (C) 2011-2023 Bitcraze AB
|
|
11
|
+
#
|
|
12
|
+
# Crazyflie Nano Quadcopter Client
|
|
13
|
+
#
|
|
14
|
+
# This program is free software; you can redistribute it and/or
|
|
15
|
+
# modify it under the terms of the GNU General Public License
|
|
16
|
+
# as published by the Free Software Foundation; either version 2
|
|
17
|
+
# of the License, or (at your option) any later version.
|
|
18
|
+
#
|
|
19
|
+
# This program is distributed in the hope that it will be useful,
|
|
20
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
21
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
22
|
+
# GNU General Public License for more details.
|
|
23
|
+
|
|
24
|
+
# You should have received a copy of the GNU General Public License along with
|
|
25
|
+
# this program; if not, write to the Free Software Foundation, Inc.,
|
|
26
|
+
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
27
|
+
|
|
28
|
+
"""
|
|
29
|
+
Superclass for all tabs that implements common functions.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
import logging
|
|
33
|
+
|
|
34
|
+
from PyQt6 import QtWidgets
|
|
35
|
+
from PyQt6.QtCore import pyqtSignal
|
|
36
|
+
from PyQt6.QtCore import Qt
|
|
37
|
+
from PyQt6.QtGui import QCloseEvent
|
|
38
|
+
|
|
39
|
+
from cfclient.utils.config import Config
|
|
40
|
+
|
|
41
|
+
__author__ = 'Bitcraze AB'
|
|
42
|
+
__all__ = ['TabToolbox']
|
|
43
|
+
|
|
44
|
+
logger = logging.getLogger(__name__)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class TabToolbox(QtWidgets.QWidget):
|
|
48
|
+
"""Superclass for all tabs that implements common functions."""
|
|
49
|
+
|
|
50
|
+
CONF_KEY_OPEN_TABS = "open_tabs"
|
|
51
|
+
CONF_KEY_OPEN_TOOLBOXES = "open_toolboxes"
|
|
52
|
+
CONF_KEY_TOOLBOX_AREAS = "toolbox_areas"
|
|
53
|
+
|
|
54
|
+
# Display states
|
|
55
|
+
DS_HIDDEN = 0
|
|
56
|
+
DS_TAB = 1
|
|
57
|
+
DS_TOOLBOX = 2
|
|
58
|
+
|
|
59
|
+
def __init__(self, helper, tab_toolbox_name):
|
|
60
|
+
super(TabToolbox, self).__init__()
|
|
61
|
+
self._helper = helper
|
|
62
|
+
self.tab_toolbox_name = tab_toolbox_name
|
|
63
|
+
|
|
64
|
+
# Dock widget for toolbox behavior
|
|
65
|
+
self.dock_widget = self.ClosingDockWidget(tab_toolbox_name)
|
|
66
|
+
self.dock_widget.tab_toolbox = self
|
|
67
|
+
|
|
68
|
+
self._display_state = self.DS_HIDDEN
|
|
69
|
+
|
|
70
|
+
self._dock_area = self._get_toolbox_area_config()
|
|
71
|
+
|
|
72
|
+
# Do not allow floating toolboxes, it seems to be buggy
|
|
73
|
+
self.dock_widget.setFeatures(QtWidgets.QDockWidget.DockWidgetFeature.DockWidgetClosable |
|
|
74
|
+
QtWidgets.QDockWidget.DockWidgetFeature.DockWidgetMovable)
|
|
75
|
+
# If floating is set in the config, change to right docking area
|
|
76
|
+
if self._dock_area == Qt.DockWidgetArea.NoDockWidgetArea:
|
|
77
|
+
self._dock_area = Qt.DockWidgetArea.RightDockWidgetArea
|
|
78
|
+
|
|
79
|
+
def get_tab_toolbox_name(self):
|
|
80
|
+
"""Return the name that will be shown in the tab or toolbox"""
|
|
81
|
+
return self.tab_toolbox_name
|
|
82
|
+
|
|
83
|
+
def is_visible(self):
|
|
84
|
+
return self._display_state != self.DS_HIDDEN
|
|
85
|
+
|
|
86
|
+
def get_display_state(self):
|
|
87
|
+
return self._display_state
|
|
88
|
+
|
|
89
|
+
def set_display_state(self, new_display_state):
|
|
90
|
+
if new_display_state != self._display_state:
|
|
91
|
+
self._display_state = new_display_state
|
|
92
|
+
self._update_open_config(new_display_state)
|
|
93
|
+
|
|
94
|
+
if new_display_state == self.DS_HIDDEN:
|
|
95
|
+
self.disable()
|
|
96
|
+
else:
|
|
97
|
+
self.enable()
|
|
98
|
+
|
|
99
|
+
def preferred_dock_area(self):
|
|
100
|
+
return self._dock_area
|
|
101
|
+
|
|
102
|
+
def set_preferred_dock_area(self, area):
|
|
103
|
+
self._dock_area = area
|
|
104
|
+
self._store_toolbox_area_config(area)
|
|
105
|
+
|
|
106
|
+
def enable(self):
|
|
107
|
+
pass
|
|
108
|
+
|
|
109
|
+
def disable(self):
|
|
110
|
+
pass
|
|
111
|
+
|
|
112
|
+
@classmethod
|
|
113
|
+
def read_open_tab_config(cls):
|
|
114
|
+
return cls._read_open_config(TabToolbox.CONF_KEY_OPEN_TABS)
|
|
115
|
+
|
|
116
|
+
@classmethod
|
|
117
|
+
def read_open_toolbox_config(cls):
|
|
118
|
+
return TabToolbox._read_open_config(TabToolbox.CONF_KEY_OPEN_TOOLBOXES)
|
|
119
|
+
|
|
120
|
+
@classmethod
|
|
121
|
+
def _read_open_config(cls, key):
|
|
122
|
+
config = []
|
|
123
|
+
try:
|
|
124
|
+
value = Config().get(key)
|
|
125
|
+
# Python will return a list of an empty string if value is empty, filter it
|
|
126
|
+
config = list(filter(None, value.split(",")))
|
|
127
|
+
except KeyError:
|
|
128
|
+
logger.info(f'No config found for {key}')
|
|
129
|
+
|
|
130
|
+
return config
|
|
131
|
+
|
|
132
|
+
def _update_open_config(self, display_state):
|
|
133
|
+
if display_state == self.DS_HIDDEN:
|
|
134
|
+
self._remove_from_open_config(TabToolbox.CONF_KEY_OPEN_TABS)
|
|
135
|
+
self._remove_from_open_config(TabToolbox.CONF_KEY_OPEN_TOOLBOXES)
|
|
136
|
+
elif display_state == self.DS_TAB:
|
|
137
|
+
self._add_to_open_config(TabToolbox.CONF_KEY_OPEN_TABS)
|
|
138
|
+
self._remove_from_open_config(TabToolbox.CONF_KEY_OPEN_TOOLBOXES)
|
|
139
|
+
elif display_state == self.DS_TOOLBOX:
|
|
140
|
+
self._remove_from_open_config(TabToolbox.CONF_KEY_OPEN_TABS)
|
|
141
|
+
self._add_to_open_config(TabToolbox.CONF_KEY_OPEN_TOOLBOXES)
|
|
142
|
+
|
|
143
|
+
def _add_to_open_config(self, key):
|
|
144
|
+
config = self._read_open_config(key)
|
|
145
|
+
name = self.tab_toolbox_name
|
|
146
|
+
|
|
147
|
+
if name not in config:
|
|
148
|
+
config.append(name)
|
|
149
|
+
self._store_open_config(key, config)
|
|
150
|
+
|
|
151
|
+
def _remove_from_open_config(self, key):
|
|
152
|
+
config = self._read_open_config(key)
|
|
153
|
+
name = self.tab_toolbox_name
|
|
154
|
+
|
|
155
|
+
if name in config:
|
|
156
|
+
config.remove(name)
|
|
157
|
+
self._store_open_config(key, config)
|
|
158
|
+
|
|
159
|
+
def _store_open_config(self, key, config):
|
|
160
|
+
value = ','.join(config)
|
|
161
|
+
Config().set(key, value)
|
|
162
|
+
|
|
163
|
+
def _get_toolbox_area_config(self):
|
|
164
|
+
result = Qt.DockWidgetArea.RightDockWidgetArea
|
|
165
|
+
|
|
166
|
+
config = self._read_toolbox_area_config()
|
|
167
|
+
|
|
168
|
+
if self.tab_toolbox_name in config.keys():
|
|
169
|
+
result = Qt.DockWidgetArea(config[self.tab_toolbox_name])
|
|
170
|
+
|
|
171
|
+
return result
|
|
172
|
+
|
|
173
|
+
def _store_toolbox_area_config(self, area):
|
|
174
|
+
config = self._read_toolbox_area_config()
|
|
175
|
+
config[self.tab_toolbox_name] = area.value
|
|
176
|
+
self._write_toolbox_area_config(config)
|
|
177
|
+
|
|
178
|
+
def _read_toolbox_area_config(self):
|
|
179
|
+
composite_config = []
|
|
180
|
+
try:
|
|
181
|
+
key = self.CONF_KEY_TOOLBOX_AREAS
|
|
182
|
+
value = Config().get(key)
|
|
183
|
+
# Python will return a list of an empty string if value is empty, filter it
|
|
184
|
+
composite_config = list(filter(None, value.split(",")))
|
|
185
|
+
except KeyError:
|
|
186
|
+
logger.info(f'No config found for {key}')
|
|
187
|
+
|
|
188
|
+
config = {}
|
|
189
|
+
for composite in composite_config:
|
|
190
|
+
try:
|
|
191
|
+
parts = composite.split(':')
|
|
192
|
+
config[parts[0]] = int(parts[1])
|
|
193
|
+
except (KeyError, ValueError):
|
|
194
|
+
logger.info(f'Can not understand config {composite}')
|
|
195
|
+
|
|
196
|
+
return config
|
|
197
|
+
|
|
198
|
+
def _write_toolbox_area_config(self, config):
|
|
199
|
+
key = self.CONF_KEY_TOOLBOX_AREAS
|
|
200
|
+
value = ','.join(map(lambda item: f'{item[0]}:{item[1]}', config.items()))
|
|
201
|
+
Config().set(key, value)
|
|
202
|
+
|
|
203
|
+
class ClosingDockWidget(QtWidgets.QDockWidget):
|
|
204
|
+
closed = pyqtSignal()
|
|
205
|
+
|
|
206
|
+
def closeEvent(self, event: QCloseEvent) -> None:
|
|
207
|
+
super(TabToolbox.ClosingDockWidget, self).closeEvent(event)
|
|
208
|
+
self.closed.emit()
|