dexter-controller 0.3.0__tar.gz → 1.0.0a2__tar.gz
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.
- {dexter_controller-0.3.0 → dexter_controller-1.0.0a2}/PKG-INFO +55 -48
- {dexter_controller-0.3.0 → dexter_controller-1.0.0a2}/README.md +51 -44
- {dexter_controller-0.3.0 → dexter_controller-1.0.0a2}/pyproject.toml +4 -4
- {dexter_controller-0.3.0 → dexter_controller-1.0.0a2}/pyproject.toml.orig +4 -4
- {dexter_controller-0.3.0 → dexter_controller-1.0.0a2}/src/dexter_controller/__init__.py +24 -10
- dexter_controller-1.0.0a2/src/dexter_controller/ble_dexter_device.py +515 -0
- dexter_controller-1.0.0a2/src/dexter_controller/calibration.py +294 -0
- dexter_controller-1.0.0a2/src/dexter_controller/dexter_device.py +445 -0
- dexter_controller-1.0.0a2/src/dexter_controller/finger.py +49 -0
- {dexter_controller-0.3.0 → dexter_controller-1.0.0a2}/src/dexter_controller/force_converter.py +3 -37
- {dexter_controller-0.3.0 → dexter_controller-1.0.0a2}/src/dexter_controller/force_processor.py +5 -22
- dexter_controller-1.0.0a2/src/dexter_controller/harp/dexter/__init__.py +503 -0
- dexter_controller-1.0.0a2/src/dexter_controller/harp/dexter/py.typed +0 -0
- {dexter_controller-0.3.0 → dexter_controller-1.0.0a2}/src/dexter_controller/recording_metadata.py +1 -1
- dexter_controller-1.0.0a2/src/dexter_controller/uart_dexter_device.py +476 -0
- dexter_controller-0.3.0/src/dexter_controller/ble_loadcell_device.py +0 -400
- dexter_controller-0.3.0/src/dexter_controller/calibration.py +0 -99
- dexter_controller-0.3.0/src/dexter_controller/dexter_hand_controller.py +0 -290
- dexter_controller-0.3.0/src/dexter_controller/finger.py +0 -73
- dexter_controller-0.3.0/src/dexter_controller/loadcell_device.py +0 -69
- {dexter_controller-0.3.0 → dexter_controller-1.0.0a2}/src/dexter_controller/data_recorder.py +0 -0
- {dexter_controller-0.3.0 → dexter_controller-1.0.0a2}/src/dexter_controller/finger_orientation.py +0 -0
- {dexter_controller-0.3.0 → dexter_controller-1.0.0a2}/src/dexter_controller/recording.py +0 -0
- {dexter_controller-0.3.0 → dexter_controller-1.0.0a2}/src/dexter_controller/recording_format.py +0 -0
- {dexter_controller-0.3.0 → dexter_controller-1.0.0a2}/src/dexter_controller/recording_reader.py +0 -0
- {dexter_controller-0.3.0 → dexter_controller-1.0.0a2}/src/dexter_controller/tare.py +0 -0
- {dexter_controller-0.3.0 → dexter_controller-1.0.0a2}/src/dexter_controller/writers.py +0 -0
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: dexter-controller
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 1.0.0a2
|
|
4
4
|
Summary: Dexter device Controller
|
|
5
5
|
Author: Hardware and Software Platform, Champalimaud Foundation
|
|
6
6
|
Author-email: Hardware and Software Platform, Champalimaud Foundation <software@research.fchampalimaud.org>
|
|
7
7
|
Classifier: Programming Language :: Python :: 3
|
|
8
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
9
8
|
Classifier: Programming Language :: Python :: 3.11
|
|
10
9
|
Classifier: Programming Language :: Python :: 3.12
|
|
11
10
|
Classifier: Programming Language :: Python :: 3.13
|
|
12
11
|
Requires-Dist: bleak==2.1.1
|
|
13
|
-
Requires-Dist: harp-
|
|
12
|
+
Requires-Dist: harp-protocol==0.5.0
|
|
13
|
+
Requires-Dist: harp-serial==0.5.0
|
|
14
14
|
Requires-Dist: pydoc-markdown>=4.8.2 ; extra == 'docs'
|
|
15
15
|
Requires-Dist: pyarrow>=14.0.0 ; extra == 'parquet'
|
|
16
16
|
Requires-Dist: dexter-controller[reader] ; extra == 'parquet'
|
|
17
17
|
Requires-Dist: numpy>=1.25.0 ; extra == 'reader'
|
|
18
|
-
Requires-Python: >=3.
|
|
18
|
+
Requires-Python: >=3.11
|
|
19
19
|
Project-URL: Repository, https://github.com/fchampalimaud/dexter-controller/
|
|
20
20
|
Project-URL: Bug Tracker, https://github.com/fchampalimaud/dexter-controller/issues
|
|
21
21
|
Provides-Extra: docs
|
|
@@ -52,33 +52,35 @@ pip install dexter-controller[parquet] # pyarrow + numpy, for Parquet format s
|
|
|
52
52
|
|
|
53
53
|
## Quick start
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
Connect over BLE or UART using the `DexterDevice` factory:
|
|
56
56
|
|
|
57
57
|
```python
|
|
58
58
|
import time
|
|
59
|
-
from dexter_controller import
|
|
59
|
+
from dexter_controller import DexterDevice, Finger
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
#
|
|
63
|
-
#
|
|
61
|
+
device = DexterDevice.create_ble(
|
|
62
|
+
# connect to a specific device by name:
|
|
63
|
+
# device_name="Dexter-001"
|
|
64
64
|
)
|
|
65
|
+
device.connect()
|
|
66
|
+
device.start_acquisition()
|
|
65
67
|
|
|
66
|
-
device_name =
|
|
67
|
-
battery =
|
|
68
|
-
rate =
|
|
68
|
+
device_name = device.get_device_name()
|
|
69
|
+
battery = device.get_battery_level()
|
|
70
|
+
rate = device.get_sampling_rate()
|
|
69
71
|
print(f"Device: {device_name} | Battery: {battery}% | Rate: {rate.value} Hz")
|
|
70
72
|
|
|
71
73
|
try:
|
|
72
74
|
while True:
|
|
73
75
|
for finger in Finger:
|
|
74
|
-
data =
|
|
76
|
+
data = device.finger_data[finger]
|
|
75
77
|
print(f"{finger.name}: {data.raw_data}", end=" ")
|
|
76
78
|
print(end="\r", flush=True)
|
|
77
79
|
time.sleep(0.02)
|
|
78
80
|
except KeyboardInterrupt:
|
|
79
81
|
pass
|
|
80
82
|
finally:
|
|
81
|
-
|
|
83
|
+
device.close()
|
|
82
84
|
```
|
|
83
85
|
|
|
84
86
|
## Force computation
|
|
@@ -87,23 +89,25 @@ Convert raw load-cell readings into calibrated 2D force vectors (Fx, Fy):
|
|
|
87
89
|
|
|
88
90
|
```python
|
|
89
91
|
from dexter_controller import (
|
|
90
|
-
|
|
91
|
-
|
|
92
|
+
DEFAULT_CALIBRATION,
|
|
93
|
+
DexterDevice,
|
|
92
94
|
Finger,
|
|
93
95
|
ForceProcessor,
|
|
94
96
|
get_default_orientation,
|
|
95
97
|
)
|
|
96
98
|
|
|
97
|
-
|
|
99
|
+
device = DexterDevice.create_ble()
|
|
100
|
+
device.connect()
|
|
101
|
+
device.start_acquisition()
|
|
98
102
|
|
|
99
103
|
processors = {}
|
|
100
104
|
for finger in Finger:
|
|
101
105
|
orientation = get_default_orientation(finger)
|
|
102
|
-
processors[finger] = ForceProcessor(
|
|
106
|
+
processors[finger] = ForceProcessor(DEFAULT_CALIBRATION, orientation)
|
|
103
107
|
|
|
104
108
|
# In your read loop:
|
|
105
|
-
data =
|
|
106
|
-
fx, fy = processors[Finger.INDEX].
|
|
109
|
+
data = device.finger_data[Finger.INDEX]
|
|
110
|
+
fx, fy = processors[Finger.INDEX].process(data)
|
|
107
111
|
```
|
|
108
112
|
|
|
109
113
|
Each `ForceProcessor` includes a `TareState` that lets you zero-out the baseline:
|
|
@@ -118,9 +122,9 @@ Record sessions to disk in CSV, SQLite (**default**), or Parquet format:
|
|
|
118
122
|
|
|
119
123
|
```python
|
|
120
124
|
from dexter_controller import (
|
|
121
|
-
|
|
125
|
+
DEFAULT_CALIBRATION,
|
|
122
126
|
DataRecorder,
|
|
123
|
-
|
|
127
|
+
DexterDevice,
|
|
124
128
|
Finger,
|
|
125
129
|
ForceProcessor,
|
|
126
130
|
RecordingMetadata,
|
|
@@ -128,35 +132,37 @@ from dexter_controller import (
|
|
|
128
132
|
)
|
|
129
133
|
from dexter_controller.recording_format import RecordingFormat
|
|
130
134
|
|
|
131
|
-
|
|
135
|
+
device = DexterDevice.create_ble()
|
|
136
|
+
device.connect()
|
|
137
|
+
device.start_acquisition()
|
|
132
138
|
|
|
133
139
|
processors = {}
|
|
134
140
|
for finger in Finger:
|
|
135
141
|
processors[finger] = ForceProcessor(
|
|
136
|
-
|
|
142
|
+
DEFAULT_CALIBRATION, get_default_orientation(finger)
|
|
137
143
|
)
|
|
138
144
|
|
|
139
145
|
recorder = DataRecorder(
|
|
140
146
|
"./recordings",
|
|
141
147
|
file_format=RecordingFormat.SQLITE,
|
|
142
148
|
metadata=RecordingMetadata(
|
|
143
|
-
device_name=
|
|
144
|
-
sampling_rate_hz=
|
|
149
|
+
device_name=device.get_device_name(),
|
|
150
|
+
sampling_rate_hz=device.get_sampling_rate().value,
|
|
145
151
|
),
|
|
146
152
|
)
|
|
147
153
|
|
|
148
154
|
def on_sample(_data):
|
|
149
|
-
fingers = [
|
|
150
|
-
forces = [processors[f].
|
|
155
|
+
fingers = [device.finger_data[f] for f in Finger]
|
|
156
|
+
forces = [processors[f].process(device.finger_data[f]) for f in Finger]
|
|
151
157
|
baselines = [(processors[f].tare.baseline_x, processors[f].tare.baseline_y) for f in Finger]
|
|
152
158
|
recorder.write_sample(fingers, forces, baselines)
|
|
153
159
|
|
|
154
|
-
|
|
160
|
+
device.register_finger_callback(Finger.PINKY, on_sample)
|
|
155
161
|
|
|
156
162
|
recorder.start_recording()
|
|
157
163
|
# ... run until done ...
|
|
158
164
|
recorder.stop_recording()
|
|
159
|
-
|
|
165
|
+
device.close()
|
|
160
166
|
```
|
|
161
167
|
|
|
162
168
|
Each recording file includes session metadata.
|
|
@@ -225,11 +231,11 @@ When connected via BLE, you can read and write device settings:
|
|
|
225
231
|
```python
|
|
226
232
|
from dexter_controller import SamplingRate
|
|
227
233
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
234
|
+
device.get_device_name() # read name
|
|
235
|
+
device.set_device_name("MyDexter") # rename device
|
|
236
|
+
device.get_sampling_rate() # current rate
|
|
237
|
+
device.set_sampling_rate(SamplingRate.HZ_1000) # change rate
|
|
238
|
+
device.get_battery_level() # battery percentage
|
|
233
239
|
```
|
|
234
240
|
|
|
235
241
|
> [!WARNING]
|
|
@@ -246,21 +252,22 @@ See the [example/](example/) directory for complete, runnable scripts:
|
|
|
246
252
|
| [example_ble.py](example/example_ble.py) | BLE connection with raw data streaming and event rate monitoring |
|
|
247
253
|
| [example_ble_force.py](example/example_ble_force.py) | BLE connection with real-time force computation using `ForceProcessor` |
|
|
248
254
|
| [example_ble_recording.py](example/example_ble_recording.py) | Full recording session: BLE connect, force processing, and data recording to file |
|
|
249
|
-
| [
|
|
255
|
+
| [example_uart.py](example/example_uart.py) | UART (wired) connection |
|
|
250
256
|
|
|
251
|
-
##
|
|
257
|
+
## UART connection
|
|
252
258
|
|
|
253
|
-
For wired setups using
|
|
259
|
+
For wired setups using UART:
|
|
254
260
|
|
|
255
261
|
```python
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
"COM4": [Finger.MIDDLE, Finger.RING],
|
|
261
|
-
"COM5": [Finger.PINKY],
|
|
262
|
-
}
|
|
263
|
-
controller = DexterHandController(mapping)
|
|
264
|
-
```
|
|
262
|
+
import sys
|
|
263
|
+
from dexter_controller import DexterDevice, EventFlags, Finger, SamplingRate
|
|
264
|
+
|
|
265
|
+
device = DexterDevice.create_uart("COM3") # or /dev/ttyUSB0 on Linux
|
|
265
266
|
|
|
266
|
-
|
|
267
|
+
with device:
|
|
268
|
+
device.set_sampling_rate(SamplingRate.HZ_800)
|
|
269
|
+
device.set_event_enable(EventFlags.LOAD_CELL_DATA)
|
|
270
|
+
device.set_finger_channel_mapping([Finger.RING, None, None, None, None])
|
|
271
|
+
device.start_acquisition()
|
|
272
|
+
# ... read data via device.register_data_callback(callback)
|
|
273
|
+
```
|
|
@@ -27,33 +27,35 @@ pip install dexter-controller[parquet] # pyarrow + numpy, for Parquet format s
|
|
|
27
27
|
|
|
28
28
|
## Quick start
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
Connect over BLE or UART using the `DexterDevice` factory:
|
|
31
31
|
|
|
32
32
|
```python
|
|
33
33
|
import time
|
|
34
|
-
from dexter_controller import
|
|
34
|
+
from dexter_controller import DexterDevice, Finger
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
#
|
|
38
|
-
#
|
|
36
|
+
device = DexterDevice.create_ble(
|
|
37
|
+
# connect to a specific device by name:
|
|
38
|
+
# device_name="Dexter-001"
|
|
39
39
|
)
|
|
40
|
+
device.connect()
|
|
41
|
+
device.start_acquisition()
|
|
40
42
|
|
|
41
|
-
device_name =
|
|
42
|
-
battery =
|
|
43
|
-
rate =
|
|
43
|
+
device_name = device.get_device_name()
|
|
44
|
+
battery = device.get_battery_level()
|
|
45
|
+
rate = device.get_sampling_rate()
|
|
44
46
|
print(f"Device: {device_name} | Battery: {battery}% | Rate: {rate.value} Hz")
|
|
45
47
|
|
|
46
48
|
try:
|
|
47
49
|
while True:
|
|
48
50
|
for finger in Finger:
|
|
49
|
-
data =
|
|
51
|
+
data = device.finger_data[finger]
|
|
50
52
|
print(f"{finger.name}: {data.raw_data}", end=" ")
|
|
51
53
|
print(end="\r", flush=True)
|
|
52
54
|
time.sleep(0.02)
|
|
53
55
|
except KeyboardInterrupt:
|
|
54
56
|
pass
|
|
55
57
|
finally:
|
|
56
|
-
|
|
58
|
+
device.close()
|
|
57
59
|
```
|
|
58
60
|
|
|
59
61
|
## Force computation
|
|
@@ -62,23 +64,25 @@ Convert raw load-cell readings into calibrated 2D force vectors (Fx, Fy):
|
|
|
62
64
|
|
|
63
65
|
```python
|
|
64
66
|
from dexter_controller import (
|
|
65
|
-
|
|
66
|
-
|
|
67
|
+
DEFAULT_CALIBRATION,
|
|
68
|
+
DexterDevice,
|
|
67
69
|
Finger,
|
|
68
70
|
ForceProcessor,
|
|
69
71
|
get_default_orientation,
|
|
70
72
|
)
|
|
71
73
|
|
|
72
|
-
|
|
74
|
+
device = DexterDevice.create_ble()
|
|
75
|
+
device.connect()
|
|
76
|
+
device.start_acquisition()
|
|
73
77
|
|
|
74
78
|
processors = {}
|
|
75
79
|
for finger in Finger:
|
|
76
80
|
orientation = get_default_orientation(finger)
|
|
77
|
-
processors[finger] = ForceProcessor(
|
|
81
|
+
processors[finger] = ForceProcessor(DEFAULT_CALIBRATION, orientation)
|
|
78
82
|
|
|
79
83
|
# In your read loop:
|
|
80
|
-
data =
|
|
81
|
-
fx, fy = processors[Finger.INDEX].
|
|
84
|
+
data = device.finger_data[Finger.INDEX]
|
|
85
|
+
fx, fy = processors[Finger.INDEX].process(data)
|
|
82
86
|
```
|
|
83
87
|
|
|
84
88
|
Each `ForceProcessor` includes a `TareState` that lets you zero-out the baseline:
|
|
@@ -93,9 +97,9 @@ Record sessions to disk in CSV, SQLite (**default**), or Parquet format:
|
|
|
93
97
|
|
|
94
98
|
```python
|
|
95
99
|
from dexter_controller import (
|
|
96
|
-
|
|
100
|
+
DEFAULT_CALIBRATION,
|
|
97
101
|
DataRecorder,
|
|
98
|
-
|
|
102
|
+
DexterDevice,
|
|
99
103
|
Finger,
|
|
100
104
|
ForceProcessor,
|
|
101
105
|
RecordingMetadata,
|
|
@@ -103,35 +107,37 @@ from dexter_controller import (
|
|
|
103
107
|
)
|
|
104
108
|
from dexter_controller.recording_format import RecordingFormat
|
|
105
109
|
|
|
106
|
-
|
|
110
|
+
device = DexterDevice.create_ble()
|
|
111
|
+
device.connect()
|
|
112
|
+
device.start_acquisition()
|
|
107
113
|
|
|
108
114
|
processors = {}
|
|
109
115
|
for finger in Finger:
|
|
110
116
|
processors[finger] = ForceProcessor(
|
|
111
|
-
|
|
117
|
+
DEFAULT_CALIBRATION, get_default_orientation(finger)
|
|
112
118
|
)
|
|
113
119
|
|
|
114
120
|
recorder = DataRecorder(
|
|
115
121
|
"./recordings",
|
|
116
122
|
file_format=RecordingFormat.SQLITE,
|
|
117
123
|
metadata=RecordingMetadata(
|
|
118
|
-
device_name=
|
|
119
|
-
sampling_rate_hz=
|
|
124
|
+
device_name=device.get_device_name(),
|
|
125
|
+
sampling_rate_hz=device.get_sampling_rate().value,
|
|
120
126
|
),
|
|
121
127
|
)
|
|
122
128
|
|
|
123
129
|
def on_sample(_data):
|
|
124
|
-
fingers = [
|
|
125
|
-
forces = [processors[f].
|
|
130
|
+
fingers = [device.finger_data[f] for f in Finger]
|
|
131
|
+
forces = [processors[f].process(device.finger_data[f]) for f in Finger]
|
|
126
132
|
baselines = [(processors[f].tare.baseline_x, processors[f].tare.baseline_y) for f in Finger]
|
|
127
133
|
recorder.write_sample(fingers, forces, baselines)
|
|
128
134
|
|
|
129
|
-
|
|
135
|
+
device.register_finger_callback(Finger.PINKY, on_sample)
|
|
130
136
|
|
|
131
137
|
recorder.start_recording()
|
|
132
138
|
# ... run until done ...
|
|
133
139
|
recorder.stop_recording()
|
|
134
|
-
|
|
140
|
+
device.close()
|
|
135
141
|
```
|
|
136
142
|
|
|
137
143
|
Each recording file includes session metadata.
|
|
@@ -200,11 +206,11 @@ When connected via BLE, you can read and write device settings:
|
|
|
200
206
|
```python
|
|
201
207
|
from dexter_controller import SamplingRate
|
|
202
208
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
209
|
+
device.get_device_name() # read name
|
|
210
|
+
device.set_device_name("MyDexter") # rename device
|
|
211
|
+
device.get_sampling_rate() # current rate
|
|
212
|
+
device.set_sampling_rate(SamplingRate.HZ_1000) # change rate
|
|
213
|
+
device.get_battery_level() # battery percentage
|
|
208
214
|
```
|
|
209
215
|
|
|
210
216
|
> [!WARNING]
|
|
@@ -221,21 +227,22 @@ See the [example/](example/) directory for complete, runnable scripts:
|
|
|
221
227
|
| [example_ble.py](example/example_ble.py) | BLE connection with raw data streaming and event rate monitoring |
|
|
222
228
|
| [example_ble_force.py](example/example_ble_force.py) | BLE connection with real-time force computation using `ForceProcessor` |
|
|
223
229
|
| [example_ble_recording.py](example/example_ble_recording.py) | Full recording session: BLE connect, force processing, and data recording to file |
|
|
224
|
-
| [
|
|
230
|
+
| [example_uart.py](example/example_uart.py) | UART (wired) connection |
|
|
225
231
|
|
|
226
|
-
##
|
|
232
|
+
## UART connection
|
|
227
233
|
|
|
228
|
-
For wired setups using
|
|
234
|
+
For wired setups using UART:
|
|
229
235
|
|
|
230
236
|
```python
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
"COM4": [Finger.MIDDLE, Finger.RING],
|
|
236
|
-
"COM5": [Finger.PINKY],
|
|
237
|
-
}
|
|
238
|
-
controller = DexterHandController(mapping)
|
|
239
|
-
```
|
|
237
|
+
import sys
|
|
238
|
+
from dexter_controller import DexterDevice, EventFlags, Finger, SamplingRate
|
|
239
|
+
|
|
240
|
+
device = DexterDevice.create_uart("COM3") # or /dev/ttyUSB0 on Linux
|
|
240
241
|
|
|
241
|
-
|
|
242
|
+
with device:
|
|
243
|
+
device.set_sampling_rate(SamplingRate.HZ_800)
|
|
244
|
+
device.set_event_enable(EventFlags.LOAD_CELL_DATA)
|
|
245
|
+
device.set_finger_channel_mapping([Finger.RING, None, None, None, None])
|
|
246
|
+
device.start_acquisition()
|
|
247
|
+
# ... read data via device.register_data_callback(callback)
|
|
248
|
+
```
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "dexter-controller"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "1.0.0a2"
|
|
4
4
|
description = "Dexter device Controller"
|
|
5
5
|
readme = "README.md"
|
|
6
|
-
requires-python = ">=3.
|
|
6
|
+
requires-python = ">=3.11"
|
|
7
7
|
classifiers = [
|
|
8
8
|
"Programming Language :: Python :: 3",
|
|
9
|
-
"Programming Language :: Python :: 3.10",
|
|
10
9
|
"Programming Language :: Python :: 3.11",
|
|
11
10
|
"Programming Language :: Python :: 3.12",
|
|
12
11
|
"Programming Language :: Python :: 3.13",
|
|
13
12
|
]
|
|
14
13
|
dependencies = [
|
|
15
14
|
"bleak==2.1.1",
|
|
16
|
-
"harp-
|
|
15
|
+
"harp-protocol==0.5.0",
|
|
16
|
+
"harp-serial==0.5.0",
|
|
17
17
|
]
|
|
18
18
|
|
|
19
19
|
[[project.authors]]
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "dexter-controller"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "1.0.0a2"
|
|
4
4
|
description = "Dexter device Controller"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [
|
|
7
7
|
{ name = "Hardware and Software Platform, Champalimaud Foundation", email = "software@research.fchampalimaud.org" }
|
|
8
8
|
]
|
|
9
|
-
requires-python = ">=3.
|
|
9
|
+
requires-python = ">=3.11"
|
|
10
10
|
classifiers = [
|
|
11
11
|
"Programming Language :: Python :: 3",
|
|
12
|
-
"Programming Language :: Python :: 3.10",
|
|
13
12
|
"Programming Language :: Python :: 3.11",
|
|
14
13
|
"Programming Language :: Python :: 3.12",
|
|
15
14
|
"Programming Language :: Python :: 3.13",
|
|
16
15
|
]
|
|
17
16
|
dependencies = [
|
|
18
17
|
"bleak==2.1.1",
|
|
19
|
-
"harp-
|
|
18
|
+
"harp-protocol==0.5.0",
|
|
19
|
+
"harp-serial==0.5.0",
|
|
20
20
|
]
|
|
21
21
|
|
|
22
22
|
[project.optional-dependencies]
|
|
@@ -1,44 +1,58 @@
|
|
|
1
|
-
from .
|
|
1
|
+
from .ble_dexter_device import BLEDexterDevice
|
|
2
2
|
from .calibration import (
|
|
3
3
|
DEFAULT_CALIBRATION,
|
|
4
|
-
DEFAULT_CALIBRATION_3CH,
|
|
5
4
|
CalibrationProfile,
|
|
5
|
+
ChannelCalibration,
|
|
6
6
|
LoadCellCalibration,
|
|
7
|
-
|
|
7
|
+
LoadCellCoefficients,
|
|
8
|
+
calibration_from_channel,
|
|
9
|
+
create_calibration,
|
|
8
10
|
)
|
|
9
11
|
from .data_recorder import DataRecorder
|
|
10
|
-
from .
|
|
12
|
+
from .dexter_device import (
|
|
13
|
+
DataMode,
|
|
14
|
+
DexterDevice,
|
|
15
|
+
ErrorStatus,
|
|
16
|
+
EventFlags,
|
|
17
|
+
HandSelection,
|
|
18
|
+
SamplingRate,
|
|
19
|
+
)
|
|
11
20
|
from .finger import Finger, FingerData
|
|
12
21
|
from .finger_orientation import FingerOrientation
|
|
13
22
|
from .finger_orientation import get_default as get_default_orientation
|
|
14
23
|
from .force_processor import ForceProcessor
|
|
15
|
-
from .loadcell_device import LoadCellDevice
|
|
16
24
|
from .recording import Recording
|
|
17
25
|
from .recording_format import RecordingFormat
|
|
18
26
|
from .recording_metadata import RecordingMetadata
|
|
19
27
|
from .recording_reader import RecordingReader
|
|
20
28
|
from .tare import TareState
|
|
29
|
+
from .uart_dexter_device import UartDexterDevice
|
|
21
30
|
|
|
22
31
|
__all__ = [
|
|
23
32
|
"DEFAULT_CALIBRATION",
|
|
24
|
-
"
|
|
25
|
-
"BLELoadCellDevice",
|
|
33
|
+
"BLEDexterDevice",
|
|
26
34
|
"CalibrationProfile",
|
|
35
|
+
"ChannelCalibration",
|
|
27
36
|
"DataMode",
|
|
28
37
|
"DataRecorder",
|
|
29
|
-
"
|
|
38
|
+
"DexterDevice",
|
|
39
|
+
"ErrorStatus",
|
|
40
|
+
"EventFlags",
|
|
30
41
|
"Finger",
|
|
31
42
|
"FingerData",
|
|
32
43
|
"FingerOrientation",
|
|
33
44
|
"ForceProcessor",
|
|
45
|
+
"HandSelection",
|
|
34
46
|
"LoadCellCalibration",
|
|
35
|
-
"
|
|
47
|
+
"LoadCellCoefficients",
|
|
36
48
|
"Recording",
|
|
37
49
|
"RecordingFormat",
|
|
38
50
|
"RecordingMetadata",
|
|
39
51
|
"RecordingReader",
|
|
40
52
|
"SamplingRate",
|
|
41
53
|
"TareState",
|
|
42
|
-
"
|
|
54
|
+
"UartDexterDevice",
|
|
55
|
+
"calibration_from_channel",
|
|
56
|
+
"create_calibration",
|
|
43
57
|
"get_default_orientation",
|
|
44
58
|
]
|