litegrip-python 1.1.2__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.
- litegrip/__init__.py +298 -0
- litegrip/actions.py +1444 -0
- litegrip/calibration_normal.json +9 -0
- litegrip/calibration_reverse.json +9 -0
- litegrip/can/__init__.py +41 -0
- litegrip/can/controller.py +413 -0
- litegrip/can/motor.py +188 -0
- litegrip/can/protocol.py +380 -0
- litegrip/can/transport.py +365 -0
- litegrip/constants.py +146 -0
- litegrip/exceptions.py +47 -0
- litegrip/factory_calibration.json +16 -0
- litegrip/gripper.py +2678 -0
- litegrip/models.py +210 -0
- litegrip/protocols/__init__.py +10 -0
- litegrip/protocols/can_bus.py +621 -0
- litegrip/py.typed +0 -0
- litegrip/teleop.py +1469 -0
- litegrip/trajectory.py +985 -0
- litegrip/zenoh_link.py +400 -0
- litegrip_python-1.1.2.dist-info/METADATA +636 -0
- litegrip_python-1.1.2.dist-info/RECORD +25 -0
- litegrip_python-1.1.2.dist-info/WHEEL +5 -0
- litegrip_python-1.1.2.dist-info/licenses/LICENSE +202 -0
- litegrip_python-1.1.2.dist-info/top_level.txt +1 -0
litegrip/__init__.py
ADDED
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
"""LiteGrip SDK — self-contained gripper library for the LiteGrip adaptive
|
|
2
|
+
two-finger hand.
|
|
3
|
+
|
|
4
|
+
Built on the Damiao motor MIT protocol over SocketCAN. Zero dependencies
|
|
5
|
+
outside Python's standard library + Linux SocketCAN — no damiao_socketcan
|
|
6
|
+
or robot-arm libraries required.
|
|
7
|
+
|
|
8
|
+
Quick start::
|
|
9
|
+
|
|
10
|
+
from litegrip import LiteGrip
|
|
11
|
+
|
|
12
|
+
with LiteGrip(channel="can0", can_id=0x08) as gripper:
|
|
13
|
+
gripper.enable() # retries until the status frame says err == 1
|
|
14
|
+
gripper.open()
|
|
15
|
+
gripper.grasp(force_n=20.0, hold_s=3.0)
|
|
16
|
+
state = gripper.get_state()
|
|
17
|
+
print(state)
|
|
18
|
+
|
|
19
|
+
Subpackages
|
|
20
|
+
-----------
|
|
21
|
+
- ``litegrip.can`` — Raw SocketCAN transport + DM motor protocol codec.
|
|
22
|
+
Use directly if you need fine-grained control or multi-motor setups.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
# Version reported when no ``litegrip-python`` distribution is installed in reach at all —
|
|
26
|
+
# no wheel, no editable install, nothing in ``site-packages``/``dist-packages``.
|
|
27
|
+
# The ``+`` local segment keeps it valid PEP 440 and makes it obvious in a bug
|
|
28
|
+
# report that nobody is looking at an official build.
|
|
29
|
+
_VERSION_SOURCE_TREE = "0.0.0+source"
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _detect_version(dist_name: str = "litegrip-python") -> str:
|
|
33
|
+
"""Report the installed distribution's version, or a marker for a bare machine.
|
|
34
|
+
|
|
35
|
+
The repository never commits a version back (AGENTS.md §3): semantic-release
|
|
36
|
+
derives it from the commit prefixes and writes it only into the publish
|
|
37
|
+
workspace, so the git tag is the single source of truth. A literal
|
|
38
|
+
``__version__`` in this file would therefore be a second, permanently stale
|
|
39
|
+
copy of that number. Reading the installed metadata instead keeps whatever the
|
|
40
|
+
user actually installed in one place.
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
The installed distribution version, or ``"0.0.0+source"`` when no
|
|
44
|
+
``litegrip-python`` distribution is installed at all. The marker is about what
|
|
45
|
+
is installed, not about where this file came from: a module loaded out of
|
|
46
|
+
the source tree still reports an installed copy's version, and the two
|
|
47
|
+
spells of "not the released build" are told apart by the module path, not
|
|
48
|
+
by the number.
|
|
49
|
+
"""
|
|
50
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
51
|
+
|
|
52
|
+
try:
|
|
53
|
+
return version(dist_name)
|
|
54
|
+
except PackageNotFoundError:
|
|
55
|
+
return _VERSION_SOURCE_TREE
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
__version__ = _detect_version()
|
|
59
|
+
|
|
60
|
+
# This package deliberately installs no handler and does not call
|
|
61
|
+
# ``logging.disable()``: a WARNING such as "this calibration file belongs to
|
|
62
|
+
# another channel" is a safety signal, and must reach the user even when the
|
|
63
|
+
# embedding program never configured logging. With no handler, Python's
|
|
64
|
+
# ``logging.lastResort`` prints WARNING and above to stderr. Applications that
|
|
65
|
+
# want to capture the records can still attach their own handler to the
|
|
66
|
+
# ``litegrip`` logger.
|
|
67
|
+
|
|
68
|
+
# ── High-level API ──────────────────────────────────────────────────────
|
|
69
|
+
from .gripper import (LiteGrip, DEFAULT_CALIB, CALIB_TEMPLATES,
|
|
70
|
+
default_calib_path, list_templates)
|
|
71
|
+
|
|
72
|
+
# ── Motion actions ──────────────────────────────────────────────────────
|
|
73
|
+
from .actions import (
|
|
74
|
+
MotionConfig,
|
|
75
|
+
MoveProgress,
|
|
76
|
+
MoveResult,
|
|
77
|
+
GraspResult,
|
|
78
|
+
HoldResult,
|
|
79
|
+
EnableResult,
|
|
80
|
+
WriteZeroResult,
|
|
81
|
+
GripperActions,
|
|
82
|
+
closing_travel_excursion_rad,
|
|
83
|
+
limit_target,
|
|
84
|
+
press_target,
|
|
85
|
+
work_limit_target,
|
|
86
|
+
clamp_to_travel,
|
|
87
|
+
force_approach_terms,
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
# ── Data models ─────────────────────────────────────────────────────────
|
|
91
|
+
from .models import (
|
|
92
|
+
STALE_AFTER_S,
|
|
93
|
+
GripperState,
|
|
94
|
+
GripperConfig,
|
|
95
|
+
GripperInfo,
|
|
96
|
+
GripperStatus,
|
|
97
|
+
GripperMode,
|
|
98
|
+
CalibrationData,
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
# ── Constants & enums ───────────────────────────────────────────────────
|
|
102
|
+
from .constants import (
|
|
103
|
+
GripperGeometry,
|
|
104
|
+
GripperParams,
|
|
105
|
+
UnitConversion,
|
|
106
|
+
ErrorCode,
|
|
107
|
+
DefaultParams,
|
|
108
|
+
describe_error,
|
|
109
|
+
DM_Motor_Type,
|
|
110
|
+
Control_Mode,
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
# ── Exceptions ──────────────────────────────────────────────────────────
|
|
114
|
+
from .exceptions import (
|
|
115
|
+
LiteGripError,
|
|
116
|
+
CommError,
|
|
117
|
+
ConnectError,
|
|
118
|
+
CommandError,
|
|
119
|
+
CANTimeoutError,
|
|
120
|
+
HardwareError,
|
|
121
|
+
NotInitializedError,
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
# ── Teleoperation (leader / follower) ───────────────────────────────────
|
|
125
|
+
from .teleop import (
|
|
126
|
+
GripperTeleop,
|
|
127
|
+
TeleopTransport,
|
|
128
|
+
TeleopSubscription,
|
|
129
|
+
UdpTeleopTransport,
|
|
130
|
+
InProcTeleopTransport,
|
|
131
|
+
TeleopError,
|
|
132
|
+
TeleopBusyError,
|
|
133
|
+
TeleopNotActiveError,
|
|
134
|
+
TeleopNotReady,
|
|
135
|
+
check_ready,
|
|
136
|
+
clamp_to_calibrated,
|
|
137
|
+
DEFAULT_GRIP_ID,
|
|
138
|
+
DEFAULT_GRIP_PORT,
|
|
139
|
+
DEFAULT_DQ_MAX,
|
|
140
|
+
DEFAULT_ALIGN_SPEED_MM_S,
|
|
141
|
+
DEFAULT_LEAD_CAP_MM,
|
|
142
|
+
DEFAULT_TORQUE_LIMIT_NM,
|
|
143
|
+
DEFAULT_READY_TOLERANCE_MM,
|
|
144
|
+
DEFAULT_READY_PERIOD_S,
|
|
145
|
+
DEFAULT_READY_TIMEOUT_S,
|
|
146
|
+
FRAME_SIZE,
|
|
147
|
+
READY_FRAME_SIZE,
|
|
148
|
+
encode_frame,
|
|
149
|
+
decode_frame,
|
|
150
|
+
encode_ready_frame,
|
|
151
|
+
decode_ready_frame,
|
|
152
|
+
teleop_topic,
|
|
153
|
+
ready_topic,
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
# ── Trajectory record and replay ────────────────────────────────────────
|
|
157
|
+
from .trajectory import (
|
|
158
|
+
Trajectory,
|
|
159
|
+
TrajectorySample,
|
|
160
|
+
TrajectoryRecorder,
|
|
161
|
+
TrajectoryPlayer,
|
|
162
|
+
trajectory_dir,
|
|
163
|
+
resolve_path,
|
|
164
|
+
DEFAULT_RATE_HZ,
|
|
165
|
+
TrajectoryError,
|
|
166
|
+
TrajectoryBusyError,
|
|
167
|
+
TrajectoryNotActiveError,
|
|
168
|
+
TrajectoryEmptyError,
|
|
169
|
+
TrajectoryRecordingError,
|
|
170
|
+
TrajectoryFormatError,
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
# ── CAN subpackage (expert) ─────────────────────────────────────────────
|
|
174
|
+
from . import can
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
# The zenoh link needs the optional ``zenoh`` dependency, so it is resolved on
|
|
178
|
+
# first access rather than at import time: ``import litegrip`` must work on a
|
|
179
|
+
# bare robot controller that will never teleoperate. Install the extra with
|
|
180
|
+
# ``pip install litegrip-python[zenoh]``.
|
|
181
|
+
_ZENOH_EXPORTS = frozenset(
|
|
182
|
+
{"ZenohTeleopTransport", "Listener", "Connector", "LatestSlot"})
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def __getattr__(name: str):
|
|
186
|
+
if name in _ZENOH_EXPORTS:
|
|
187
|
+
try:
|
|
188
|
+
from . import zenoh_link
|
|
189
|
+
except ImportError as e:
|
|
190
|
+
raise ImportError(
|
|
191
|
+
f"litegrip.{name} needs the optional zenoh dependency — install "
|
|
192
|
+
"it with `pip install litegrip-python[zenoh]`") from e
|
|
193
|
+
return getattr(zenoh_link, name)
|
|
194
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def __dir__():
|
|
198
|
+
return sorted(set(globals()) | _ZENOH_EXPORTS)
|
|
199
|
+
|
|
200
|
+
__all__ = [
|
|
201
|
+
"__version__",
|
|
202
|
+
# High-level
|
|
203
|
+
"LiteGrip",
|
|
204
|
+
"DEFAULT_CALIB",
|
|
205
|
+
"CALIB_TEMPLATES",
|
|
206
|
+
"default_calib_path",
|
|
207
|
+
"list_templates",
|
|
208
|
+
# Motion actions
|
|
209
|
+
"MotionConfig",
|
|
210
|
+
"MoveProgress",
|
|
211
|
+
"MoveResult",
|
|
212
|
+
"GraspResult",
|
|
213
|
+
"HoldResult",
|
|
214
|
+
"EnableResult",
|
|
215
|
+
"WriteZeroResult",
|
|
216
|
+
"GripperActions",
|
|
217
|
+
"closing_travel_excursion_rad",
|
|
218
|
+
"limit_target",
|
|
219
|
+
"press_target",
|
|
220
|
+
"work_limit_target",
|
|
221
|
+
"clamp_to_travel",
|
|
222
|
+
"force_approach_terms",
|
|
223
|
+
# Models
|
|
224
|
+
"STALE_AFTER_S",
|
|
225
|
+
"GripperState",
|
|
226
|
+
"GripperConfig",
|
|
227
|
+
"GripperInfo",
|
|
228
|
+
"GripperStatus",
|
|
229
|
+
"GripperMode",
|
|
230
|
+
"CalibrationData",
|
|
231
|
+
# Constants
|
|
232
|
+
"GripperGeometry",
|
|
233
|
+
"GripperParams",
|
|
234
|
+
"UnitConversion",
|
|
235
|
+
"ErrorCode",
|
|
236
|
+
"DefaultParams",
|
|
237
|
+
"describe_error",
|
|
238
|
+
"DM_Motor_Type",
|
|
239
|
+
"Control_Mode",
|
|
240
|
+
# Exceptions
|
|
241
|
+
"LiteGripError",
|
|
242
|
+
"CommError",
|
|
243
|
+
"ConnectError",
|
|
244
|
+
"CommandError",
|
|
245
|
+
"CANTimeoutError",
|
|
246
|
+
"HardwareError",
|
|
247
|
+
"NotInitializedError",
|
|
248
|
+
# Teleoperation
|
|
249
|
+
"GripperTeleop",
|
|
250
|
+
"TeleopTransport",
|
|
251
|
+
"TeleopSubscription",
|
|
252
|
+
"UdpTeleopTransport",
|
|
253
|
+
"InProcTeleopTransport",
|
|
254
|
+
"TeleopError",
|
|
255
|
+
"TeleopBusyError",
|
|
256
|
+
"TeleopNotActiveError",
|
|
257
|
+
"TeleopNotReady",
|
|
258
|
+
"check_ready",
|
|
259
|
+
"clamp_to_calibrated",
|
|
260
|
+
"DEFAULT_GRIP_ID",
|
|
261
|
+
"DEFAULT_GRIP_PORT",
|
|
262
|
+
"DEFAULT_DQ_MAX",
|
|
263
|
+
"DEFAULT_ALIGN_SPEED_MM_S",
|
|
264
|
+
"DEFAULT_LEAD_CAP_MM",
|
|
265
|
+
"DEFAULT_TORQUE_LIMIT_NM",
|
|
266
|
+
"DEFAULT_READY_TOLERANCE_MM",
|
|
267
|
+
"DEFAULT_READY_PERIOD_S",
|
|
268
|
+
"DEFAULT_READY_TIMEOUT_S",
|
|
269
|
+
"FRAME_SIZE",
|
|
270
|
+
"READY_FRAME_SIZE",
|
|
271
|
+
"encode_frame",
|
|
272
|
+
"decode_frame",
|
|
273
|
+
"encode_ready_frame",
|
|
274
|
+
"decode_ready_frame",
|
|
275
|
+
"teleop_topic",
|
|
276
|
+
"ready_topic",
|
|
277
|
+
# Teleoperation — zenoh link (resolved lazily; needs litegrip-python[zenoh])
|
|
278
|
+
"ZenohTeleopTransport",
|
|
279
|
+
"Listener",
|
|
280
|
+
"Connector",
|
|
281
|
+
"LatestSlot",
|
|
282
|
+
# Trajectory record and replay
|
|
283
|
+
"Trajectory",
|
|
284
|
+
"TrajectorySample",
|
|
285
|
+
"TrajectoryRecorder",
|
|
286
|
+
"TrajectoryPlayer",
|
|
287
|
+
"trajectory_dir",
|
|
288
|
+
"resolve_path",
|
|
289
|
+
"DEFAULT_RATE_HZ",
|
|
290
|
+
"TrajectoryError",
|
|
291
|
+
"TrajectoryBusyError",
|
|
292
|
+
"TrajectoryNotActiveError",
|
|
293
|
+
"TrajectoryEmptyError",
|
|
294
|
+
"TrajectoryRecordingError",
|
|
295
|
+
"TrajectoryFormatError",
|
|
296
|
+
# Subpackages
|
|
297
|
+
"can",
|
|
298
|
+
]
|