wujihandpy 1.3.0a2.dev6__cp310-cp310-manylinux_2_28_x86_64.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.
wujihandpy/__init__.py ADDED
@@ -0,0 +1,6 @@
1
+ from __future__ import annotations
2
+
3
+ from ._core import *
4
+ from ._version import __version__
5
+
6
+ __all__ = ["__version__", 'Hand', 'Finger', 'Joint', 'IController', 'filter']
@@ -0,0 +1,529 @@
1
+ from __future__ import annotations
2
+ import numpy
3
+ import numpy.typing
4
+ import typing
5
+ from . import filter
6
+ from . import logging
7
+ __all__: list[str] = ['Finger', 'Hand', 'IController', 'Joint', 'filter', 'logging']
8
+ class Finger:
9
+ def get_joint_actual_position(self) -> numpy.typing.NDArray[numpy.float64]:
10
+ ...
11
+ def get_joint_bus_voltage(self) -> numpy.typing.NDArray[numpy.float32]:
12
+ ...
13
+ def get_joint_error_code(self) -> numpy.typing.NDArray[numpy.uint32]:
14
+ ...
15
+ def get_joint_firmware_date(self) -> numpy.typing.NDArray[numpy.uint32]:
16
+ ...
17
+ def get_joint_firmware_version(self) -> numpy.typing.NDArray[numpy.uint32]:
18
+ ...
19
+ def get_joint_lower_limit(self) -> numpy.typing.NDArray[numpy.float64]:
20
+ ...
21
+ def get_joint_temperature(self) -> numpy.typing.NDArray[numpy.float32]:
22
+ ...
23
+ def get_joint_upper_limit(self) -> numpy.typing.NDArray[numpy.float64]:
24
+ ...
25
+ def joint(self, index: typing.SupportsInt) -> Joint:
26
+ ...
27
+ def read_joint_actual_position(self, timeout: typing.SupportsFloat = 0.5) -> numpy.typing.NDArray[numpy.float64]:
28
+ ...
29
+ def read_joint_actual_position_async(self, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[numpy.typing.NDArray[numpy.float64]]:
30
+ ...
31
+ def read_joint_actual_position_unchecked(self, timeout: typing.SupportsFloat = 0.5) -> None:
32
+ ...
33
+ def read_joint_bus_voltage(self, timeout: typing.SupportsFloat = 0.5) -> numpy.typing.NDArray[numpy.float32]:
34
+ ...
35
+ def read_joint_bus_voltage_async(self, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[numpy.typing.NDArray[numpy.float32]]:
36
+ ...
37
+ def read_joint_bus_voltage_unchecked(self, timeout: typing.SupportsFloat = 0.5) -> None:
38
+ ...
39
+ def read_joint_error_code(self, timeout: typing.SupportsFloat = 0.5) -> numpy.typing.NDArray[numpy.uint32]:
40
+ ...
41
+ def read_joint_error_code_async(self, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[numpy.typing.NDArray[numpy.uint32]]:
42
+ ...
43
+ def read_joint_error_code_unchecked(self, timeout: typing.SupportsFloat = 0.5) -> None:
44
+ ...
45
+ def read_joint_firmware_date(self, timeout: typing.SupportsFloat = 0.5) -> numpy.typing.NDArray[numpy.uint32]:
46
+ ...
47
+ def read_joint_firmware_date_async(self, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[numpy.typing.NDArray[numpy.uint32]]:
48
+ ...
49
+ def read_joint_firmware_date_unchecked(self, timeout: typing.SupportsFloat = 0.5) -> None:
50
+ ...
51
+ def read_joint_firmware_version(self, timeout: typing.SupportsFloat = 0.5) -> numpy.typing.NDArray[numpy.uint32]:
52
+ ...
53
+ def read_joint_firmware_version_async(self, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[numpy.typing.NDArray[numpy.uint32]]:
54
+ ...
55
+ def read_joint_firmware_version_unchecked(self, timeout: typing.SupportsFloat = 0.5) -> None:
56
+ ...
57
+ def read_joint_lower_limit(self, timeout: typing.SupportsFloat = 0.5) -> numpy.typing.NDArray[numpy.float64]:
58
+ ...
59
+ def read_joint_lower_limit_async(self, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[numpy.typing.NDArray[numpy.float64]]:
60
+ ...
61
+ def read_joint_lower_limit_unchecked(self, timeout: typing.SupportsFloat = 0.5) -> None:
62
+ ...
63
+ def read_joint_temperature(self, timeout: typing.SupportsFloat = 0.5) -> numpy.typing.NDArray[numpy.float32]:
64
+ ...
65
+ def read_joint_temperature_async(self, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[numpy.typing.NDArray[numpy.float32]]:
66
+ ...
67
+ def read_joint_temperature_unchecked(self, timeout: typing.SupportsFloat = 0.5) -> None:
68
+ ...
69
+ def read_joint_upper_limit(self, timeout: typing.SupportsFloat = 0.5) -> numpy.typing.NDArray[numpy.float64]:
70
+ ...
71
+ def read_joint_upper_limit_async(self, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[numpy.typing.NDArray[numpy.float64]]:
72
+ ...
73
+ def read_joint_upper_limit_unchecked(self, timeout: typing.SupportsFloat = 0.5) -> None:
74
+ ...
75
+ @typing.overload
76
+ def write_joint_control_mode(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> None:
77
+ ...
78
+ @typing.overload
79
+ def write_joint_control_mode(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.uint16], timeout: typing.SupportsFloat = 0.5) -> None:
80
+ ...
81
+ @typing.overload
82
+ def write_joint_control_mode_async(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[None]:
83
+ ...
84
+ @typing.overload
85
+ def write_joint_control_mode_async(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.uint16], timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[None]:
86
+ ...
87
+ @typing.overload
88
+ def write_joint_control_mode_unchecked(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> None:
89
+ ...
90
+ @typing.overload
91
+ def write_joint_control_mode_unchecked(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.uint16], timeout: typing.SupportsFloat = 0.5) -> None:
92
+ ...
93
+ @typing.overload
94
+ def write_joint_current_limit(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> None:
95
+ ...
96
+ @typing.overload
97
+ def write_joint_current_limit(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.uint16], timeout: typing.SupportsFloat = 0.5) -> None:
98
+ ...
99
+ @typing.overload
100
+ def write_joint_current_limit_async(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[None]:
101
+ ...
102
+ @typing.overload
103
+ def write_joint_current_limit_async(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.uint16], timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[None]:
104
+ ...
105
+ @typing.overload
106
+ def write_joint_current_limit_unchecked(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> None:
107
+ ...
108
+ @typing.overload
109
+ def write_joint_current_limit_unchecked(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.uint16], timeout: typing.SupportsFloat = 0.5) -> None:
110
+ ...
111
+ @typing.overload
112
+ def write_joint_enabled(self, value: bool, timeout: typing.SupportsFloat = 0.5) -> None:
113
+ ...
114
+ @typing.overload
115
+ def write_joint_enabled(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.bool_], timeout: typing.SupportsFloat = 0.5) -> None:
116
+ ...
117
+ @typing.overload
118
+ def write_joint_enabled_async(self, value: bool, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[None]:
119
+ ...
120
+ @typing.overload
121
+ def write_joint_enabled_async(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.bool_], timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[None]:
122
+ ...
123
+ @typing.overload
124
+ def write_joint_enabled_unchecked(self, value: bool, timeout: typing.SupportsFloat = 0.5) -> None:
125
+ ...
126
+ @typing.overload
127
+ def write_joint_enabled_unchecked(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.bool_], timeout: typing.SupportsFloat = 0.5) -> None:
128
+ ...
129
+ @typing.overload
130
+ def write_joint_reset_error(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> None:
131
+ ...
132
+ @typing.overload
133
+ def write_joint_reset_error(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.uint16], timeout: typing.SupportsFloat = 0.5) -> None:
134
+ ...
135
+ @typing.overload
136
+ def write_joint_reset_error_async(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[None]:
137
+ ...
138
+ @typing.overload
139
+ def write_joint_reset_error_async(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.uint16], timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[None]:
140
+ ...
141
+ @typing.overload
142
+ def write_joint_reset_error_unchecked(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> None:
143
+ ...
144
+ @typing.overload
145
+ def write_joint_reset_error_unchecked(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.uint16], timeout: typing.SupportsFloat = 0.5) -> None:
146
+ ...
147
+ @typing.overload
148
+ def write_joint_sin_level(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> None:
149
+ ...
150
+ @typing.overload
151
+ def write_joint_sin_level(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.uint16], timeout: typing.SupportsFloat = 0.5) -> None:
152
+ ...
153
+ @typing.overload
154
+ def write_joint_sin_level_async(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[None]:
155
+ ...
156
+ @typing.overload
157
+ def write_joint_sin_level_async(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.uint16], timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[None]:
158
+ ...
159
+ @typing.overload
160
+ def write_joint_sin_level_unchecked(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> None:
161
+ ...
162
+ @typing.overload
163
+ def write_joint_sin_level_unchecked(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.uint16], timeout: typing.SupportsFloat = 0.5) -> None:
164
+ ...
165
+ @typing.overload
166
+ def write_joint_target_position(self, value: typing.SupportsFloat, timeout: typing.SupportsFloat = 0.5) -> None:
167
+ ...
168
+ @typing.overload
169
+ def write_joint_target_position(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.float64], timeout: typing.SupportsFloat = 0.5) -> None:
170
+ ...
171
+ @typing.overload
172
+ def write_joint_target_position_async(self, value: typing.SupportsFloat, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[None]:
173
+ ...
174
+ @typing.overload
175
+ def write_joint_target_position_async(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.float64], timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[None]:
176
+ ...
177
+ @typing.overload
178
+ def write_joint_target_position_unchecked(self, value: typing.SupportsFloat, timeout: typing.SupportsFloat = 0.5) -> None:
179
+ ...
180
+ @typing.overload
181
+ def write_joint_target_position_unchecked(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.float64], timeout: typing.SupportsFloat = 0.5) -> None:
182
+ ...
183
+ class Hand:
184
+ def __init__(self, serial_number: str | None = None, usb_pid: typing.SupportsInt = -1, usb_vid: typing.SupportsInt = 1155, mask: typing.Annotated[numpy.typing.ArrayLike, numpy.bool_] | None = None) -> None:
185
+ ...
186
+ def finger(self, index: typing.SupportsInt) -> Finger:
187
+ ...
188
+ def get_firmware_date(self) -> numpy.uint32:
189
+ ...
190
+ def get_firmware_version(self) -> numpy.uint32:
191
+ ...
192
+ def get_handedness(self) -> numpy.uint8:
193
+ ...
194
+ def get_input_voltage(self) -> numpy.float32:
195
+ ...
196
+ def get_joint_actual_position(self) -> numpy.typing.NDArray[numpy.float64]:
197
+ ...
198
+ def get_joint_bus_voltage(self) -> numpy.typing.NDArray[numpy.float32]:
199
+ ...
200
+ def get_joint_error_code(self) -> numpy.typing.NDArray[numpy.uint32]:
201
+ ...
202
+ def get_joint_firmware_date(self) -> numpy.typing.NDArray[numpy.uint32]:
203
+ ...
204
+ def get_joint_firmware_version(self) -> numpy.typing.NDArray[numpy.uint32]:
205
+ ...
206
+ def get_joint_lower_limit(self) -> numpy.typing.NDArray[numpy.float64]:
207
+ ...
208
+ def get_joint_temperature(self) -> numpy.typing.NDArray[numpy.float32]:
209
+ ...
210
+ def get_joint_upper_limit(self) -> numpy.typing.NDArray[numpy.float64]:
211
+ ...
212
+ def get_system_time(self) -> numpy.uint32:
213
+ ...
214
+ def get_temperature(self) -> numpy.float32:
215
+ ...
216
+ def raw_sdo_read(self, finger_id: typing.SupportsInt, joint_id: typing.SupportsInt, index: typing.SupportsInt, sub_index: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> bytes:
217
+ ...
218
+ def raw_sdo_write(self, finger_id: typing.SupportsInt, joint_id: typing.SupportsInt, index: typing.SupportsInt, sub_index: typing.SupportsInt, data: bytes, timeout: typing.SupportsFloat = 0.5) -> None:
219
+ ...
220
+ def read_firmware_date(self, timeout: typing.SupportsFloat = 0.5) -> numpy.uint32:
221
+ ...
222
+ def read_firmware_date_async(self, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[numpy.uint32]:
223
+ ...
224
+ def read_firmware_date_unchecked(self, timeout: typing.SupportsFloat = 0.5) -> None:
225
+ ...
226
+ def read_firmware_version(self, timeout: typing.SupportsFloat = 0.5) -> numpy.uint32:
227
+ ...
228
+ def read_firmware_version_async(self, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[numpy.uint32]:
229
+ ...
230
+ def read_firmware_version_unchecked(self, timeout: typing.SupportsFloat = 0.5) -> None:
231
+ ...
232
+ def read_handedness(self, timeout: typing.SupportsFloat = 0.5) -> numpy.uint8:
233
+ ...
234
+ def read_handedness_async(self, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[numpy.uint8]:
235
+ ...
236
+ def read_handedness_unchecked(self, timeout: typing.SupportsFloat = 0.5) -> None:
237
+ ...
238
+ def read_input_voltage(self, timeout: typing.SupportsFloat = 0.5) -> numpy.float32:
239
+ ...
240
+ def read_input_voltage_async(self, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[numpy.float32]:
241
+ ...
242
+ def read_input_voltage_unchecked(self, timeout: typing.SupportsFloat = 0.5) -> None:
243
+ ...
244
+ def read_joint_actual_position(self, timeout: typing.SupportsFloat = 0.5) -> numpy.typing.NDArray[numpy.float64]:
245
+ ...
246
+ def read_joint_actual_position_async(self, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[numpy.typing.NDArray[numpy.float64]]:
247
+ ...
248
+ def read_joint_actual_position_unchecked(self, timeout: typing.SupportsFloat = 0.5) -> None:
249
+ ...
250
+ def read_joint_bus_voltage(self, timeout: typing.SupportsFloat = 0.5) -> numpy.typing.NDArray[numpy.float32]:
251
+ ...
252
+ def read_joint_bus_voltage_async(self, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[numpy.typing.NDArray[numpy.float32]]:
253
+ ...
254
+ def read_joint_bus_voltage_unchecked(self, timeout: typing.SupportsFloat = 0.5) -> None:
255
+ ...
256
+ def read_joint_error_code(self, timeout: typing.SupportsFloat = 0.5) -> numpy.typing.NDArray[numpy.uint32]:
257
+ ...
258
+ def read_joint_error_code_async(self, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[numpy.typing.NDArray[numpy.uint32]]:
259
+ ...
260
+ def read_joint_error_code_unchecked(self, timeout: typing.SupportsFloat = 0.5) -> None:
261
+ ...
262
+ def read_joint_firmware_date(self, timeout: typing.SupportsFloat = 0.5) -> numpy.typing.NDArray[numpy.uint32]:
263
+ ...
264
+ def read_joint_firmware_date_async(self, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[numpy.typing.NDArray[numpy.uint32]]:
265
+ ...
266
+ def read_joint_firmware_date_unchecked(self, timeout: typing.SupportsFloat = 0.5) -> None:
267
+ ...
268
+ def read_joint_firmware_version(self, timeout: typing.SupportsFloat = 0.5) -> numpy.typing.NDArray[numpy.uint32]:
269
+ ...
270
+ def read_joint_firmware_version_async(self, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[numpy.typing.NDArray[numpy.uint32]]:
271
+ ...
272
+ def read_joint_firmware_version_unchecked(self, timeout: typing.SupportsFloat = 0.5) -> None:
273
+ ...
274
+ def read_joint_lower_limit(self, timeout: typing.SupportsFloat = 0.5) -> numpy.typing.NDArray[numpy.float64]:
275
+ ...
276
+ def read_joint_lower_limit_async(self, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[numpy.typing.NDArray[numpy.float64]]:
277
+ ...
278
+ def read_joint_lower_limit_unchecked(self, timeout: typing.SupportsFloat = 0.5) -> None:
279
+ ...
280
+ def read_joint_temperature(self, timeout: typing.SupportsFloat = 0.5) -> numpy.typing.NDArray[numpy.float32]:
281
+ ...
282
+ def read_joint_temperature_async(self, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[numpy.typing.NDArray[numpy.float32]]:
283
+ ...
284
+ def read_joint_temperature_unchecked(self, timeout: typing.SupportsFloat = 0.5) -> None:
285
+ ...
286
+ def read_joint_upper_limit(self, timeout: typing.SupportsFloat = 0.5) -> numpy.typing.NDArray[numpy.float64]:
287
+ ...
288
+ def read_joint_upper_limit_async(self, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[numpy.typing.NDArray[numpy.float64]]:
289
+ ...
290
+ def read_joint_upper_limit_unchecked(self, timeout: typing.SupportsFloat = 0.5) -> None:
291
+ ...
292
+ def read_system_time(self, timeout: typing.SupportsFloat = 0.5) -> numpy.uint32:
293
+ ...
294
+ def read_system_time_async(self, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[numpy.uint32]:
295
+ ...
296
+ def read_system_time_unchecked(self, timeout: typing.SupportsFloat = 0.5) -> None:
297
+ ...
298
+ def read_temperature(self, timeout: typing.SupportsFloat = 0.5) -> numpy.float32:
299
+ ...
300
+ def read_temperature_async(self, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[numpy.float32]:
301
+ ...
302
+ def read_temperature_unchecked(self, timeout: typing.SupportsFloat = 0.5) -> None:
303
+ ...
304
+ def realtime_controller(self, enable_upstream: bool, filter: filter.IFilter) -> IController:
305
+ ...
306
+ def start_latency_test(self) -> None:
307
+ ...
308
+ def stop_latency_test(self) -> None:
309
+ ...
310
+ @typing.overload
311
+ def write_joint_control_mode(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> None:
312
+ ...
313
+ @typing.overload
314
+ def write_joint_control_mode(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.uint16], timeout: typing.SupportsFloat = 0.5) -> None:
315
+ ...
316
+ @typing.overload
317
+ def write_joint_control_mode_async(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[None]:
318
+ ...
319
+ @typing.overload
320
+ def write_joint_control_mode_async(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.uint16], timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[None]:
321
+ ...
322
+ @typing.overload
323
+ def write_joint_control_mode_unchecked(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> None:
324
+ ...
325
+ @typing.overload
326
+ def write_joint_control_mode_unchecked(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.uint16], timeout: typing.SupportsFloat = 0.5) -> None:
327
+ ...
328
+ @typing.overload
329
+ def write_joint_current_limit(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> None:
330
+ ...
331
+ @typing.overload
332
+ def write_joint_current_limit(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.uint16], timeout: typing.SupportsFloat = 0.5) -> None:
333
+ ...
334
+ @typing.overload
335
+ def write_joint_current_limit_async(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[None]:
336
+ ...
337
+ @typing.overload
338
+ def write_joint_current_limit_async(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.uint16], timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[None]:
339
+ ...
340
+ @typing.overload
341
+ def write_joint_current_limit_unchecked(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> None:
342
+ ...
343
+ @typing.overload
344
+ def write_joint_current_limit_unchecked(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.uint16], timeout: typing.SupportsFloat = 0.5) -> None:
345
+ ...
346
+ @typing.overload
347
+ def write_joint_enabled(self, value: bool, timeout: typing.SupportsFloat = 0.5) -> None:
348
+ ...
349
+ @typing.overload
350
+ def write_joint_enabled(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.bool_], timeout: typing.SupportsFloat = 0.5) -> None:
351
+ ...
352
+ @typing.overload
353
+ def write_joint_enabled_async(self, value: bool, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[None]:
354
+ ...
355
+ @typing.overload
356
+ def write_joint_enabled_async(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.bool_], timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[None]:
357
+ ...
358
+ @typing.overload
359
+ def write_joint_enabled_unchecked(self, value: bool, timeout: typing.SupportsFloat = 0.5) -> None:
360
+ ...
361
+ @typing.overload
362
+ def write_joint_enabled_unchecked(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.bool_], timeout: typing.SupportsFloat = 0.5) -> None:
363
+ ...
364
+ @typing.overload
365
+ def write_joint_reset_error(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> None:
366
+ ...
367
+ @typing.overload
368
+ def write_joint_reset_error(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.uint16], timeout: typing.SupportsFloat = 0.5) -> None:
369
+ ...
370
+ @typing.overload
371
+ def write_joint_reset_error_async(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[None]:
372
+ ...
373
+ @typing.overload
374
+ def write_joint_reset_error_async(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.uint16], timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[None]:
375
+ ...
376
+ @typing.overload
377
+ def write_joint_reset_error_unchecked(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> None:
378
+ ...
379
+ @typing.overload
380
+ def write_joint_reset_error_unchecked(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.uint16], timeout: typing.SupportsFloat = 0.5) -> None:
381
+ ...
382
+ @typing.overload
383
+ def write_joint_sin_level(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> None:
384
+ ...
385
+ @typing.overload
386
+ def write_joint_sin_level(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.uint16], timeout: typing.SupportsFloat = 0.5) -> None:
387
+ ...
388
+ @typing.overload
389
+ def write_joint_sin_level_async(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[None]:
390
+ ...
391
+ @typing.overload
392
+ def write_joint_sin_level_async(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.uint16], timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[None]:
393
+ ...
394
+ @typing.overload
395
+ def write_joint_sin_level_unchecked(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> None:
396
+ ...
397
+ @typing.overload
398
+ def write_joint_sin_level_unchecked(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.uint16], timeout: typing.SupportsFloat = 0.5) -> None:
399
+ ...
400
+ @typing.overload
401
+ def write_joint_target_position(self, value: typing.SupportsFloat, timeout: typing.SupportsFloat = 0.5) -> None:
402
+ ...
403
+ @typing.overload
404
+ def write_joint_target_position(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.float64], timeout: typing.SupportsFloat = 0.5) -> None:
405
+ ...
406
+ @typing.overload
407
+ def write_joint_target_position_async(self, value: typing.SupportsFloat, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[None]:
408
+ ...
409
+ @typing.overload
410
+ def write_joint_target_position_async(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.float64], timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[None]:
411
+ ...
412
+ @typing.overload
413
+ def write_joint_target_position_unchecked(self, value: typing.SupportsFloat, timeout: typing.SupportsFloat = 0.5) -> None:
414
+ ...
415
+ @typing.overload
416
+ def write_joint_target_position_unchecked(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.float64], timeout: typing.SupportsFloat = 0.5) -> None:
417
+ ...
418
+ class IController:
419
+ def __enter__(self) -> IController:
420
+ ...
421
+ def __exit__(self, arg0: typing.Any, arg1: typing.Any, arg2: typing.Any) -> None:
422
+ ...
423
+ def close(self) -> None:
424
+ ...
425
+ def get_joint_actual_position(self) -> numpy.typing.NDArray[numpy.float64]:
426
+ ...
427
+ def set_joint_target_position(self, value_array: typing.Annotated[numpy.typing.ArrayLike, numpy.float64]) -> None:
428
+ ...
429
+ class Joint:
430
+ def get_joint_actual_position(self) -> numpy.float64:
431
+ ...
432
+ def get_joint_bus_voltage(self) -> numpy.float32:
433
+ ...
434
+ def get_joint_error_code(self) -> numpy.uint32:
435
+ ...
436
+ def get_joint_firmware_date(self) -> numpy.uint32:
437
+ ...
438
+ def get_joint_firmware_version(self) -> numpy.uint32:
439
+ ...
440
+ def get_joint_lower_limit(self) -> numpy.float64:
441
+ ...
442
+ def get_joint_temperature(self) -> numpy.float32:
443
+ ...
444
+ def get_joint_upper_limit(self) -> numpy.float64:
445
+ ...
446
+ def read_joint_actual_position(self, timeout: typing.SupportsFloat = 0.5) -> numpy.float64:
447
+ ...
448
+ def read_joint_actual_position_async(self, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[numpy.float64]:
449
+ ...
450
+ def read_joint_actual_position_unchecked(self, timeout: typing.SupportsFloat = 0.5) -> None:
451
+ ...
452
+ def read_joint_bus_voltage(self, timeout: typing.SupportsFloat = 0.5) -> numpy.float32:
453
+ ...
454
+ def read_joint_bus_voltage_async(self, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[numpy.float32]:
455
+ ...
456
+ def read_joint_bus_voltage_unchecked(self, timeout: typing.SupportsFloat = 0.5) -> None:
457
+ ...
458
+ def read_joint_error_code(self, timeout: typing.SupportsFloat = 0.5) -> numpy.uint32:
459
+ ...
460
+ def read_joint_error_code_async(self, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[numpy.uint32]:
461
+ ...
462
+ def read_joint_error_code_unchecked(self, timeout: typing.SupportsFloat = 0.5) -> None:
463
+ ...
464
+ def read_joint_firmware_date(self, timeout: typing.SupportsFloat = 0.5) -> numpy.uint32:
465
+ ...
466
+ def read_joint_firmware_date_async(self, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[numpy.uint32]:
467
+ ...
468
+ def read_joint_firmware_date_unchecked(self, timeout: typing.SupportsFloat = 0.5) -> None:
469
+ ...
470
+ def read_joint_firmware_version(self, timeout: typing.SupportsFloat = 0.5) -> numpy.uint32:
471
+ ...
472
+ def read_joint_firmware_version_async(self, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[numpy.uint32]:
473
+ ...
474
+ def read_joint_firmware_version_unchecked(self, timeout: typing.SupportsFloat = 0.5) -> None:
475
+ ...
476
+ def read_joint_lower_limit(self, timeout: typing.SupportsFloat = 0.5) -> numpy.float64:
477
+ ...
478
+ def read_joint_lower_limit_async(self, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[numpy.float64]:
479
+ ...
480
+ def read_joint_lower_limit_unchecked(self, timeout: typing.SupportsFloat = 0.5) -> None:
481
+ ...
482
+ def read_joint_temperature(self, timeout: typing.SupportsFloat = 0.5) -> numpy.float32:
483
+ ...
484
+ def read_joint_temperature_async(self, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[numpy.float32]:
485
+ ...
486
+ def read_joint_temperature_unchecked(self, timeout: typing.SupportsFloat = 0.5) -> None:
487
+ ...
488
+ def read_joint_upper_limit(self, timeout: typing.SupportsFloat = 0.5) -> numpy.float64:
489
+ ...
490
+ def read_joint_upper_limit_async(self, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[numpy.float64]:
491
+ ...
492
+ def read_joint_upper_limit_unchecked(self, timeout: typing.SupportsFloat = 0.5) -> None:
493
+ ...
494
+ def write_joint_control_mode(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> None:
495
+ ...
496
+ def write_joint_control_mode_async(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[None]:
497
+ ...
498
+ def write_joint_control_mode_unchecked(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> None:
499
+ ...
500
+ def write_joint_current_limit(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> None:
501
+ ...
502
+ def write_joint_current_limit_async(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[None]:
503
+ ...
504
+ def write_joint_current_limit_unchecked(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> None:
505
+ ...
506
+ def write_joint_enabled(self, value: bool, timeout: typing.SupportsFloat = 0.5) -> None:
507
+ ...
508
+ def write_joint_enabled_async(self, value: bool, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[None]:
509
+ ...
510
+ def write_joint_enabled_unchecked(self, value: bool, timeout: typing.SupportsFloat = 0.5) -> None:
511
+ ...
512
+ def write_joint_reset_error(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> None:
513
+ ...
514
+ def write_joint_reset_error_async(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[None]:
515
+ ...
516
+ def write_joint_reset_error_unchecked(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> None:
517
+ ...
518
+ def write_joint_sin_level(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> None:
519
+ ...
520
+ def write_joint_sin_level_async(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[None]:
521
+ ...
522
+ def write_joint_sin_level_unchecked(self, value: typing.SupportsInt, timeout: typing.SupportsFloat = 0.5) -> None:
523
+ ...
524
+ def write_joint_target_position(self, value: typing.SupportsFloat, timeout: typing.SupportsFloat = 0.5) -> None:
525
+ ...
526
+ def write_joint_target_position_async(self, value: typing.SupportsFloat, timeout: typing.SupportsFloat = 0.5) -> typing.Awaitable[None]:
527
+ ...
528
+ def write_joint_target_position_unchecked(self, value: typing.SupportsFloat, timeout: typing.SupportsFloat = 0.5) -> None:
529
+ ...
@@ -0,0 +1,8 @@
1
+ from __future__ import annotations
2
+ import typing
3
+ __all__: list[str] = ['IFilter', 'LowPass']
4
+ class IFilter:
5
+ pass
6
+ class LowPass(IFilter):
7
+ def __init__(self, cutoff_freq: typing.SupportsFloat = 10.0) -> None:
8
+ ...
@@ -0,0 +1,65 @@
1
+ from __future__ import annotations
2
+ import typing
3
+ __all__: list[str] = ['Level', 'flush', 'set_log_level', 'set_log_path', 'set_log_to_console', 'set_log_to_file']
4
+ class Level:
5
+ """
6
+ Members:
7
+
8
+ Trace
9
+
10
+ Debug
11
+
12
+ Info
13
+
14
+ Warn
15
+
16
+ Error
17
+
18
+ Critical
19
+
20
+ Off
21
+ """
22
+ Critical: typing.ClassVar[Level] # value = <Level.Critical: 5>
23
+ Debug: typing.ClassVar[Level] # value = <Level.Debug: 1>
24
+ Error: typing.ClassVar[Level] # value = <Level.Error: 4>
25
+ Info: typing.ClassVar[Level] # value = <Level.Info: 2>
26
+ Off: typing.ClassVar[Level] # value = <Level.Off: 6>
27
+ Trace: typing.ClassVar[Level] # value = <Level.Trace: 0>
28
+ Warn: typing.ClassVar[Level] # value = <Level.Warn: 3>
29
+ __members__: typing.ClassVar[dict[str, Level]] # value = {'Trace': <Level.Trace: 0>, 'Debug': <Level.Debug: 1>, 'Info': <Level.Info: 2>, 'Warn': <Level.Warn: 3>, 'Error': <Level.Error: 4>, 'Critical': <Level.Critical: 5>, 'Off': <Level.Off: 6>}
30
+ def __eq__(self, other: typing.Any) -> bool:
31
+ ...
32
+ def __getstate__(self) -> int:
33
+ ...
34
+ def __hash__(self) -> int:
35
+ ...
36
+ def __index__(self) -> int:
37
+ ...
38
+ def __init__(self, value: typing.SupportsInt) -> None:
39
+ ...
40
+ def __int__(self) -> int:
41
+ ...
42
+ def __ne__(self, other: typing.Any) -> bool:
43
+ ...
44
+ def __repr__(self) -> str:
45
+ ...
46
+ def __setstate__(self, state: typing.SupportsInt) -> None:
47
+ ...
48
+ def __str__(self) -> str:
49
+ ...
50
+ @property
51
+ def name(self) -> str:
52
+ ...
53
+ @property
54
+ def value(self) -> int:
55
+ ...
56
+ def flush() -> None:
57
+ ...
58
+ def set_log_level(value: Level) -> None:
59
+ ...
60
+ def set_log_path(value: str) -> None:
61
+ ...
62
+ def set_log_to_console(value: bool) -> None:
63
+ ...
64
+ def set_log_to_file(value: bool) -> None:
65
+ ...
wujihandpy/_version.py ADDED
@@ -0,0 +1,34 @@
1
+ # file generated by setuptools-scm
2
+ # don't change, don't track in version control
3
+
4
+ __all__ = [
5
+ "__version__",
6
+ "__version_tuple__",
7
+ "version",
8
+ "version_tuple",
9
+ "__commit_id__",
10
+ "commit_id",
11
+ ]
12
+
13
+ TYPE_CHECKING = False
14
+ if TYPE_CHECKING:
15
+ from typing import Tuple
16
+ from typing import Union
17
+
18
+ VERSION_TUPLE = Tuple[Union[int, str], ...]
19
+ COMMIT_ID = Union[str, None]
20
+ else:
21
+ VERSION_TUPLE = object
22
+ COMMIT_ID = object
23
+
24
+ version: str
25
+ __version__: str
26
+ __version_tuple__: VERSION_TUPLE
27
+ version_tuple: VERSION_TUPLE
28
+ commit_id: COMMIT_ID
29
+ __commit_id__: COMMIT_ID
30
+
31
+ __version__ = version = '1.3.0a2.dev6'
32
+ __version_tuple__ = version_tuple = (1, 3, 0, 'a2', 'dev6')
33
+
34
+ __commit_id__ = commit_id = 'ga0d907b41'
@@ -0,0 +1,268 @@
1
+ Metadata-Version: 2.2
2
+ Name: wujihandpy
3
+ Version: 1.3.0a2.dev6
4
+ Summary: Python bindings for WujiHandCpp
5
+ Author-Email: Zihan Qin <zihanqin2048@gmail.com>
6
+ Maintainer-Email: Wuji Technology <support@pan-motor.com>
7
+ License: MIT License
8
+
9
+ Copyright (c) 2025 Wuji Technology
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ of this software and associated documentation files (the "Software"), to deal
13
+ in the Software without restriction, including without limitation the rights
14
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ copies of the Software, and to permit persons to whom the Software is
16
+ furnished to do so, subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included in all
19
+ copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
+ SOFTWARE.
28
+
29
+ Project-URL: homepage, https://github.com/Wuji-Technology-Co-Ltd/wujihandpy
30
+ Project-URL: repository, https://github.com/Wuji-Technology-Co-Ltd/wujihandpy
31
+ Project-URL: Bug Tracker, https://github.com/Wuji-Technology-Co-Ltd/wujihandpy/issues
32
+ Requires-Python: >=3.8
33
+ Requires-Dist: numpy
34
+ Description-Content-Type: text/markdown
35
+
36
+ # WujihandPy: Python bindings for WujiHandCpp
37
+
38
+ WujihandPy 是 [WujiHandCpp](https://github.com/Wuji-Technology-Co-Ltd/wujihandcpp) 的 Python 绑定。
39
+
40
+ 提供更简洁、更高效、更易用的接口与灵巧手设备进行交互。
41
+
42
+ ## 安装
43
+
44
+ WujihandPy 支持 pip 一键安装:
45
+
46
+ ```bash
47
+ pip install wujihandpy
48
+ ```
49
+
50
+ 对于 Linux 用户,需要额外配置 udev 规则以允许非 root 用户访问 USB 设备,可在终端中输入:
51
+
52
+ ```bash
53
+ echo 'SUBSYSTEM=="usb", ATTR{idVendor}=="0483", MODE="0666"' |
54
+ sudo tee /etc/udev/rules.d/95-wujihand.rules &&
55
+ sudo udevadm control --reload-rules &&
56
+ sudo udevadm trigger
57
+ ```
58
+
59
+ ### 常见错误
60
+
61
+ 若遇到报错 `Could not find a version that satisfies the requirement`,请尝试升级 pip:
62
+
63
+ ```bash
64
+ python3 -m pip install --upgrade pip
65
+ ```
66
+
67
+ 然后使用新的pip重新安装:
68
+
69
+ ```bash
70
+ python3 -m pip install wujihandpy
71
+ ```
72
+
73
+ ## 支持的 CPU 架构
74
+
75
+ - x86_64
76
+ - ARM64
77
+
78
+ ## 最低系统要求 (Linux)
79
+
80
+ ### glibc 2.28+
81
+
82
+ 使用 glibc 2.28 或更高版本的 Linux 发行版:
83
+ - Debian 10+
84
+ - Ubuntu 18.10+
85
+ - Fedora 29+
86
+ - CentOS/RHEL 8+
87
+
88
+ ### Python 3.8+
89
+
90
+ 支持以下 Python 版本:
91
+
92
+ - Python 3.8-3.14
93
+
94
+ ## 最低系统要求 (Windows)
95
+
96
+ WujihandPy 目前暂不支持 Windows,我们会尽快推进相关支持。
97
+
98
+ ## 示例代码
99
+
100
+ 所有示例代码均位于 [example](example) 目录下。
101
+
102
+ ## 部分参考 API
103
+
104
+ ### 导入模块
105
+
106
+ ```python
107
+ import wujihandpy
108
+ import numpy as np
109
+ ```
110
+
111
+ ### 连接至灵巧手
112
+
113
+ ```python
114
+ hand = wujihandpy.Hand()
115
+ ```
116
+
117
+ ### 读数据
118
+
119
+ ```python
120
+ def read_<dataname>(self) -> datatype
121
+ def read_<dataname>(self) -> np.ndarray[datatype] # For bulk-read
122
+ ```
123
+
124
+ 所有可使用的数据均定义在 `wujihandpy/_core.pyi` 中。
125
+
126
+ 例如,读取灵巧手的上电运行时间(us):
127
+
128
+ ```python
129
+ time = hand.read_system_time()
130
+ ```
131
+
132
+ 除整手唯一的数据外,每个关节也有自己的数据,数据名称均以 `joint` 作为开头。
133
+
134
+ 例如,读取第1个手指(食指),第0个关节的当前位置数据:
135
+
136
+ ```python
137
+ position = hand.finger(1).joint(0).read_joint_actual_position()
138
+ ```
139
+
140
+ 关节角度为 `np.float64` 类型,单位为弧度,零点和正方向与 [URDF文件](https://github.com/Wuji-Technology-Co-Ltd/wujihand-urdf) 中定义的相同。
141
+
142
+ 用一条指令读取多个数据也是可行的,这被称为**批量读 (Bulk-Read)**。
143
+
144
+ 例如,以下指令读取整手所有(20个)关节的当前位置数据:
145
+
146
+ ```python
147
+ positions = hand.read_joint_actual_position()
148
+ ```
149
+
150
+ 进行批量读时,函数返回包含所有数据的 `np.ndarray[np.float64]`:
151
+
152
+ ```python
153
+ >>> print(positions)
154
+ [[ 0.975 0.523 0.271 -0.45 ]
155
+ [ 0.382 0.241 -0.003 -0.275]
156
+ [-0.299 0.329 0.067 -0.286]
157
+ [-0.122 0.228 0.315 -0.178]
158
+ [ 0.205 0.087 0.288 -0.149]]
159
+ ```
160
+
161
+ `read` 函数会阻塞,直到读取完成。保证当函数返回时,读取一定成功。
162
+
163
+ ### 写数据
164
+
165
+ 写数据拥有类似的 API,但多了一个参数用于传递目标值:
166
+
167
+ ```python
168
+ def write_<dataname>(self, datatype)
169
+ def write_<dataname>(self, np.ndarray[datatype]) # For bulk-write
170
+ ```
171
+
172
+ 例如,写入单个关节的目标位置数据:
173
+
174
+ ```python
175
+ hand.finger(1).joint(0).write_joint_target_position(0.8)
176
+ ```
177
+
178
+ 各关节的合法角度范围可通过以下 API 获取:
179
+
180
+ ```python
181
+ upper = < Hand / Finger / Joint >.read_joint_upper_limit()
182
+ lower = < Hand / Finger / Joint >.read_joint_lower_limit()
183
+ ```
184
+
185
+ 若写入的角度超出合法范围,会被自动限幅至最高/最低值。
186
+
187
+ **批量写**数据也是可行的,例如,批量为第一个手指写入目标位置数据:
188
+
189
+ ```python
190
+ hand.finger(1).write_joint_target_position(0.8)
191
+ ```
192
+
193
+ 如果每个关节的目标值不同,可以传入一个包含所有目标值的 `np.array`:
194
+
195
+ ```python
196
+ hand.finger(1).write_joint_target_position(
197
+ np.array(
198
+ # J1 J2 J3 J4
199
+ [0.8, 0.0, 0.8, 0.8],
200
+ dtype=np.float64,
201
+ )
202
+ )
203
+ ```
204
+
205
+ `write` 函数会阻塞,直到写入完成。保证当函数返回时,写入一定成功。
206
+
207
+ ### 异步读/写
208
+
209
+ 读写函数均有对应的异步版本,函数名以 `_async` 作为后缀。
210
+
211
+ ``` python
212
+ async def read_<dataname>_async(self) -> datatype
213
+ async def read_<dataname>_async(self) -> np.ndarray[datatype] # For bulk-read
214
+ async def write_<dataname>_async(self, datatype)
215
+ async def write_<dataname>_async(self, np.ndarray[datatype]) # For bulk-write
216
+ ```
217
+
218
+ 异步接口需 `await`;等待期间不阻塞线程/事件循环,返回时保证读/写已经成功。
219
+
220
+ ### Unchecked 读/写
221
+
222
+ 如果不关心读/写是否成功,可以使用 Unchecked 版本的读/写函数,函数名以 `_unchecked` 作为后缀。
223
+
224
+ ```python
225
+ def read_<dataname>_unchecked(self) -> None
226
+ def read_<dataname>_unchecked(self) -> None # For bulk-read
227
+ def write_<dataname>_unchecked(self, datatype)
228
+ def write_<dataname>_unchecked(self, np.ndarray[datatype]) # For bulk-write
229
+ ```
230
+
231
+ Unchecked 函数总是立即返回,不会阻塞,通常用于对实时性要求较高的场景。
232
+
233
+ ### Get
234
+
235
+ 如果希望获取以往读/写的结果,可以使用 `get` 系列函数:
236
+
237
+ ```python
238
+ def get_<dataname>(self) -> datatype
239
+ def get_<dataname>(self) -> np.ndarray[datatype] # For bulk-read
240
+ ```
241
+
242
+ `get` 系列函数同样不会阻塞,它总是立即返回最近一次读取到的数据,无论该数据来自 `read`、`async-read` 还是 `read-unchecked`。
243
+
244
+ 如果尚未请求过该数据,或请求尚未成功,`get` 函数的返回值是未定义的(通常为0)。
245
+
246
+ ### 实时控制
247
+
248
+ 默认的读/写方式均带有缓冲池,积攒一段时间数据后才进行传输,最高读/写频率无法超过 100Hz。
249
+
250
+ 对于需要流畅控制关节位置的场景,需使用 realtime_controller。
251
+
252
+ 具体的控制示例可见 [example](example) 目录:
253
+
254
+ 单向写:[realtime.py](example/4.realtime.py)
255
+
256
+ 双向读/写:[realtime_duplex.py](example/5.realtime_duplex.py)
257
+
258
+ ## 性能与优化
259
+
260
+ WujihandPy 在充分保证易用性的同时,尽可能优化了性能与效率。
261
+
262
+ 我们强烈建议优先使用批量读/写以最大限度地发挥性能。
263
+
264
+ 对于需要流畅控制关节位置的场景,请务必使用 realtime_controller。
265
+
266
+ ## 许可证
267
+
268
+ 本项目采用 MIT 许可证,详情见 [LICENSE](LICENSE) 文件。
@@ -0,0 +1,18 @@
1
+ wujihandpy/__init__.py,sha256=O6rhSCIkTvciLQraUMgmZjEaW7i5n40qQ6Z5oacN_rE,170
2
+ wujihandpy/_core.cpython-310-x86_64-linux-gnu.so,sha256=OuF3FLgZ__HS6nwliFc8K3CpUoBP9GN66oCAgIkeG9Q,1823761
3
+ wujihandpy/_version.py,sha256=HKq5W5VEWGF7KTFr-q__CzQ_9wBVSxCzLTv8IdZn9v8,733
4
+ wujihandpy/_core/__init__.pyi,sha256=UC13uXqh5pgejgetglgY0oT0XkbdKJ6jSk3jBzwempU,29817
5
+ wujihandpy/_core/filter.pyi,sha256=dAkrbcYtfcM10eOQumdIvIoHo5ay3oUVOqIqAhFMv24,227
6
+ wujihandpy/_core/logging.pyi,sha256=nM87F9rV0BcpyiqD50WNJfAWICSmc45obMj5T1ZZQW0,1868
7
+ wujihandpy.libs/libblkid-a9167753.so.1.1.0,sha256=XVspUZDmtSMamCgSYDrDYNC-g6agPQCkqrDE0yb8sdY,356897
8
+ wujihandpy.libs/libmount-ec61bd71.so.1.1.0,sha256=8EmOB9QqeXTyAh0aE20fn-QVuG3vsF66wBcgZ6aX2V4,393873
9
+ wujihandpy.libs/libpcre2-8-516f4c9d.so.0.7.1,sha256=IcbljW_oKuAVlrAwKz8qtRZxfi1sQH_iKxPSoNpzsmU,547745
10
+ wujihandpy.libs/libselinux-d0805dcb.so.1,sha256=iYGaLO-LIy5-WEihMiXHpeJUXyq56DDqGU49JbpfTu4,195097
11
+ wujihandpy.libs/libudev-0287888a.so.1.6.11,sha256=UHpPM8d0Fu4qUZx_gK6g8bokbVEGpo6Tr_6zHnIvTSc,677489
12
+ wujihandpy.libs/libusb-1-1b307d35.0.so.0.2.0,sha256=7zYJwEmBdI_irHvCc7aBOFGrDViG0KtwpKC5Xop-AjM,126777
13
+ wujihandpy.libs/libuuid-95b83d40.so.1.3.0,sha256=Bj-_E8XyWfgC65o6pTuT9qLNcuA97EYDyCUUOfDR2q0,38041
14
+ wujihandpy-1.3.0a2.dev6.dist-info/METADATA,sha256=Stp3eoD-DMsWznu8yzuJ1zDMx-ENkR-r5FY7zzMVvw8,8036
15
+ wujihandpy-1.3.0a2.dev6.dist-info/WHEEL,sha256=WfUIOrZZjmphW6XvWWOC-3zHgyiL7DZcrARpY3z4EcQ,118
16
+ wujihandpy-1.3.0a2.dev6.dist-info/RECORD,,
17
+ wujihandpy-1.3.0a2.dev6.dist-info/licenses/LICENSE,sha256=OLJ-MVXgwcjW8-kJ56ADWaMCCF39muljtSqRy74lr6M,1072
18
+ wujihandpy-1.3.0a2.dev6.dist-info/sboms/auditwheel.cdx.json,sha256=GfZ8du4yxG7wvB2vf3TKz_SH7lNqF1lG5h7Loy4Ep_0,4206
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: scikit-build-core 0.11.6
3
+ Root-Is-Purelib: false
4
+ Tag: cp310-cp310-manylinux_2_28_x86_64
5
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Wuji Technology
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ {"bomFormat": "CycloneDX", "specVersion": "1.4", "version": 1, "metadata": {"component": {"type": "library", "bom-ref": "pkg:pypi/wujihandpy@1.3.0a2.dev6?file_name=wujihandpy-1.3.0a2.dev6-cp310-cp310-manylinux_2_28_x86_64.whl", "name": "wujihandpy", "version": "1.3.0a2.dev6", "purl": "pkg:pypi/wujihandpy@1.3.0a2.dev6?file_name=wujihandpy-1.3.0a2.dev6-cp310-cp310-manylinux_2_28_x86_64.whl"}, "tools": [{"name": "auditwheel", "version": "6.5.0"}]}, "components": [{"type": "library", "bom-ref": "pkg:pypi/wujihandpy@1.3.0a2.dev6?file_name=wujihandpy-1.3.0a2.dev6-cp310-cp310-manylinux_2_28_x86_64.whl", "name": "wujihandpy", "version": "1.3.0a2.dev6", "purl": "pkg:pypi/wujihandpy@1.3.0a2.dev6?file_name=wujihandpy-1.3.0a2.dev6-cp310-cp310-manylinux_2_28_x86_64.whl"}, {"type": "library", "bom-ref": "pkg:rpm/almalinux/libselinux@2.9-10.el8_10#02193ff4a4eff6fcc27e9c3cf39839797d150f578de0826f36a41de8ede637ed", "name": "libselinux", "version": "2.9-10.el8_10", "purl": "pkg:rpm/almalinux/libselinux@2.9-10.el8_10"}, {"type": "library", "bom-ref": "pkg:rpm/almalinux/libmount@2.32.1-46.el8#8c34f32b04e5de4ef3af43db612850dcbaad84f066875114d42563ee6268ab77", "name": "libmount", "version": "2.32.1-46.el8", "purl": "pkg:rpm/almalinux/libmount@2.32.1-46.el8"}, {"type": "library", "bom-ref": "pkg:rpm/almalinux/systemd-libs@239-82.el8_10.8#e114e6e2fec909bba185a4f811730cef04dfd519389c56962726ea7d2edb5606", "name": "systemd-libs", "version": "239-82.el8_10.8", "purl": "pkg:rpm/almalinux/systemd-libs@239-82.el8_10.8"}, {"type": "library", "bom-ref": "pkg:rpm/almalinux/libusbx@1.0.23-4.el8#520370b69ccfbdbb4727fcff453ff768c2933cbcf1fb1b7be5d6fbc97ae7c3c6", "name": "libusbx", "version": "1.0.23-4.el8", "purl": "pkg:rpm/almalinux/libusbx@1.0.23-4.el8"}, {"type": "library", "bom-ref": "pkg:rpm/almalinux/libblkid@2.32.1-46.el8#a482bb7a54c08d7904729cc2e01651f0718ff20d65c8d55e9ee3528137458aa2", "name": "libblkid", "version": "2.32.1-46.el8", "purl": "pkg:rpm/almalinux/libblkid@2.32.1-46.el8"}, {"type": "library", "bom-ref": "pkg:rpm/almalinux/pcre2@10.32-3.el8_6#a35b63105b4e5063acbb565eac2487e082c8a1198a0a2880d42576898010fff7", "name": "pcre2", "version": "10.32-3.el8_6", "purl": "pkg:rpm/almalinux/pcre2@10.32-3.el8_6"}, {"type": "library", "bom-ref": "pkg:rpm/almalinux/libuuid@2.32.1-46.el8#d1eebdb5bf3fab16c11b91ed71781b39917e9e09ce155655bdb9f963f245cf72", "name": "libuuid", "version": "2.32.1-46.el8", "purl": "pkg:rpm/almalinux/libuuid@2.32.1-46.el8"}], "dependencies": [{"ref": "pkg:pypi/wujihandpy@1.3.0a2.dev6?file_name=wujihandpy-1.3.0a2.dev6-cp310-cp310-manylinux_2_28_x86_64.whl", "dependsOn": ["pkg:rpm/almalinux/libselinux@2.9-10.el8_10#02193ff4a4eff6fcc27e9c3cf39839797d150f578de0826f36a41de8ede637ed", "pkg:rpm/almalinux/libmount@2.32.1-46.el8#8c34f32b04e5de4ef3af43db612850dcbaad84f066875114d42563ee6268ab77", "pkg:rpm/almalinux/systemd-libs@239-82.el8_10.8#e114e6e2fec909bba185a4f811730cef04dfd519389c56962726ea7d2edb5606", "pkg:rpm/almalinux/libusbx@1.0.23-4.el8#520370b69ccfbdbb4727fcff453ff768c2933cbcf1fb1b7be5d6fbc97ae7c3c6", "pkg:rpm/almalinux/libblkid@2.32.1-46.el8#a482bb7a54c08d7904729cc2e01651f0718ff20d65c8d55e9ee3528137458aa2", "pkg:rpm/almalinux/pcre2@10.32-3.el8_6#a35b63105b4e5063acbb565eac2487e082c8a1198a0a2880d42576898010fff7", "pkg:rpm/almalinux/libuuid@2.32.1-46.el8#d1eebdb5bf3fab16c11b91ed71781b39917e9e09ce155655bdb9f963f245cf72"]}, {"ref": "pkg:rpm/almalinux/libselinux@2.9-10.el8_10#02193ff4a4eff6fcc27e9c3cf39839797d150f578de0826f36a41de8ede637ed"}, {"ref": "pkg:rpm/almalinux/libmount@2.32.1-46.el8#8c34f32b04e5de4ef3af43db612850dcbaad84f066875114d42563ee6268ab77"}, {"ref": "pkg:rpm/almalinux/systemd-libs@239-82.el8_10.8#e114e6e2fec909bba185a4f811730cef04dfd519389c56962726ea7d2edb5606"}, {"ref": "pkg:rpm/almalinux/libusbx@1.0.23-4.el8#520370b69ccfbdbb4727fcff453ff768c2933cbcf1fb1b7be5d6fbc97ae7c3c6"}, {"ref": "pkg:rpm/almalinux/libblkid@2.32.1-46.el8#a482bb7a54c08d7904729cc2e01651f0718ff20d65c8d55e9ee3528137458aa2"}, {"ref": "pkg:rpm/almalinux/pcre2@10.32-3.el8_6#a35b63105b4e5063acbb565eac2487e082c8a1198a0a2880d42576898010fff7"}, {"ref": "pkg:rpm/almalinux/libuuid@2.32.1-46.el8#d1eebdb5bf3fab16c11b91ed71781b39917e9e09ce155655bdb9f963f245cf72"}]}
Binary file