kmk 0.1.0__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.
- kmk-0.1.0/PKG-INFO +178 -0
- kmk-0.1.0/README.md +162 -0
- kmk-0.1.0/pyproject.toml +32 -0
- kmk-0.1.0/src/kmk/__init__.py +7 -0
- kmk-0.1.0/src/kmk/config/__init__.py +12 -0
- kmk-0.1.0/src/kmk/config/model.py +391 -0
- kmk-0.1.0/src/kmk/config/parse.py +61 -0
- kmk-0.1.0/src/kmk/hand_info.py +286 -0
- kmk-0.1.0/src/kmk/kinematics.py +263 -0
- kmk-0.1.0/src/kmk/pose.py +403 -0
- kmk-0.1.0/src/kmk/wizard/__init__.py +7 -0
- kmk-0.1.0/src/kmk/wizard/cli.py +53 -0
- kmk-0.1.0/src/kmk/wizard/gui.py +2669 -0
- kmk-0.1.0/src/kmk/wizard/session.py +304 -0
kmk-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: kmk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Keypoint-based multi-fingered hand kinematics and configuration tools.
|
|
5
|
+
Requires-Dist: numpy>=2.0.0
|
|
6
|
+
Requires-Dist: pyyaml>=6.0.1
|
|
7
|
+
Requires-Dist: scipy>=1.13.0
|
|
8
|
+
Requires-Dist: torch>=2.3.0
|
|
9
|
+
Requires-Dist: tyro>=0.8.12
|
|
10
|
+
Requires-Dist: viser>=1.0.24
|
|
11
|
+
Requires-Dist: yourdfpy>=0.0.60
|
|
12
|
+
Requires-Python: >=3.11
|
|
13
|
+
Project-URL: Homepage, https://github.com/kh11kim/kmk.git
|
|
14
|
+
Project-URL: Repository, https://github.com/kh11kim/kmk.git
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
# kmk
|
|
18
|
+
|
|
19
|
+
`kmk` is a utility repo for authoring and consuming keypoint-based multi-fingered hand kinematics data.
|
|
20
|
+
|
|
21
|
+
It has two main jobs:
|
|
22
|
+
|
|
23
|
+
- a staged GUI wizard that builds a hand config YAML
|
|
24
|
+
- runtime loaders and torch kinematics utilities that read that YAML
|
|
25
|
+
|
|
26
|
+
## What This Repo Provides
|
|
27
|
+
|
|
28
|
+
- `gripper_config_wizard`
|
|
29
|
+
- staged authoring flow for:
|
|
30
|
+
- global hand config
|
|
31
|
+
- per-link contact anchors
|
|
32
|
+
- grasp templates
|
|
33
|
+
- final preview/confirmation
|
|
34
|
+
- `HandInfo`
|
|
35
|
+
- read-only runtime wrapper around the authored YAML
|
|
36
|
+
- `PointedHandInfo`
|
|
37
|
+
- `HandInfo` plus precomputed surface/contact point samples
|
|
38
|
+
- `HandKinematics`
|
|
39
|
+
- torch forward kinematics for batched joint vectors and link-local point sets
|
|
40
|
+
|
|
41
|
+
## User Workflow
|
|
42
|
+
|
|
43
|
+
1. Prepare a gripper root directory containing at least a URDF.
|
|
44
|
+
2. Run the wizard.
|
|
45
|
+
3. Fill the global stage.
|
|
46
|
+
- palm pose
|
|
47
|
+
- palm points delta
|
|
48
|
+
- global `q_open`
|
|
49
|
+
- extra collision ignore pairs
|
|
50
|
+
4. Fill the keypoint stage.
|
|
51
|
+
- one contact anchor per link
|
|
52
|
+
- point, radius, tags
|
|
53
|
+
5. Fill the grasp template stage.
|
|
54
|
+
- `q_open`, `q_close`
|
|
55
|
+
- `grasp_target_point`
|
|
56
|
+
- active contact anchors
|
|
57
|
+
6. Check the final preview and press `Confirmed`.
|
|
58
|
+
7. Use the saved YAML through `HandInfo`, `PointedHandInfo`, or `HandKinematics`.
|
|
59
|
+
|
|
60
|
+
## Install
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
uv sync
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Wizard
|
|
67
|
+
|
|
68
|
+
Create a new config:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
uv run gripper_config_wizard --gripper-root /path/to/gripper_root
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Edit an existing config:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
uv run gripper_config_wizard \
|
|
78
|
+
--gripper-root /path/to/gripper_root \
|
|
79
|
+
--from-config existing.yaml
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Notes:
|
|
83
|
+
|
|
84
|
+
- `--from-config` relative paths are resolved from `gripper_root`.
|
|
85
|
+
- `urdf_path` and `xml_path` stored in YAML are typically relative paths.
|
|
86
|
+
|
|
87
|
+
## Visualization
|
|
88
|
+
|
|
89
|
+
Inspect a saved config and sampled points:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
uv run python visualize/pointed_hand_info.py --config-path /path/to/hand.yaml
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Inspect batched torch kinematics:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
uv run python visualize/hand_kinematics_batch.py --config-path /path/to/hand.yaml
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Runtime API
|
|
102
|
+
|
|
103
|
+
### `HandInfo`
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
from kmk import HandInfo
|
|
107
|
+
|
|
108
|
+
hand = HandInfo.from_config("hand.yaml")
|
|
109
|
+
q_open = hand.get_q_open()
|
|
110
|
+
q_close = hand.get_q_close("finger4_shallow")
|
|
111
|
+
palm_pose = hand.get_palm_pose()
|
|
112
|
+
anchor = hand.get_contact_anchor_by_link("right_1thumb_distal")
|
|
113
|
+
anchors = hand.get_contact_anchor_by_template("finger4_shallow")
|
|
114
|
+
target = hand.get_grasp_target_point("finger4_shallow")
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Main API:
|
|
118
|
+
|
|
119
|
+
- `HandInfo.from_config(config_path)`
|
|
120
|
+
- `joint_order`
|
|
121
|
+
- `template_names`
|
|
122
|
+
- `contact_anchor_links`
|
|
123
|
+
- `get_q_open(template="global")`
|
|
124
|
+
- `get_q_close(template_name)`
|
|
125
|
+
- `get_palm_pose()`
|
|
126
|
+
- `get_contact_anchor_by_link(link_name)`
|
|
127
|
+
- `get_contact_anchor_by_tag(includes=(), excludes=())`
|
|
128
|
+
- `get_contact_anchor_by_template(template_name)`
|
|
129
|
+
- `get_grasp_target_point(template_name)`
|
|
130
|
+
|
|
131
|
+
### `PointedHandInfo`
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
from kmk import PointedHandInfo
|
|
135
|
+
|
|
136
|
+
hand = PointedHandInfo.from_config("hand.yaml", seed=0)
|
|
137
|
+
surface_points = hand.surface_points
|
|
138
|
+
contact_points = hand.get_contact_points("finger4_shallow")
|
|
139
|
+
keypoints = hand.get_keypoints("finger4_shallow", palm_aligned_points=True)
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Main additions:
|
|
143
|
+
|
|
144
|
+
- `surface_points`
|
|
145
|
+
- `contact_points`
|
|
146
|
+
- `get_contact_points(template_name=None)`
|
|
147
|
+
- `get_keypoints(template_name=None, palm_aligned_points=True, palm_points_delta=...)`
|
|
148
|
+
|
|
149
|
+
### `HandKinematics`
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
import torch
|
|
153
|
+
from kmk import HandInfo, HandKinematics
|
|
154
|
+
|
|
155
|
+
hand = HandInfo.from_config("hand.yaml")
|
|
156
|
+
kin = HandKinematics(hand).to(device="cpu")
|
|
157
|
+
|
|
158
|
+
q = torch.zeros(16, len(hand.joint_order))
|
|
159
|
+
fk = kin.forward_kinematics(q)
|
|
160
|
+
world_points = kin.transform_link_points(
|
|
161
|
+
q,
|
|
162
|
+
{"right_1thumb_distal": torch.tensor([[0.0, 0.0, 0.02]])},
|
|
163
|
+
)
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Main API:
|
|
167
|
+
|
|
168
|
+
- `HandKinematics(hand_info_or_config_path)`
|
|
169
|
+
- `joint_order`
|
|
170
|
+
- `link_names`
|
|
171
|
+
- `dof`
|
|
172
|
+
- `forward_kinematics(q)`
|
|
173
|
+
- `transform_link_points(q, points_by_link)`
|
|
174
|
+
- `get_palm_pose(batch_shape=None)`
|
|
175
|
+
|
|
176
|
+
## Config Schema
|
|
177
|
+
|
|
178
|
+
The detailed spec lives in [`SPEC.md`](/Users/polde/ws/kmk/SPEC.md).
|
kmk-0.1.0/README.md
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# kmk
|
|
2
|
+
|
|
3
|
+
`kmk` is a utility repo for authoring and consuming keypoint-based multi-fingered hand kinematics data.
|
|
4
|
+
|
|
5
|
+
It has two main jobs:
|
|
6
|
+
|
|
7
|
+
- a staged GUI wizard that builds a hand config YAML
|
|
8
|
+
- runtime loaders and torch kinematics utilities that read that YAML
|
|
9
|
+
|
|
10
|
+
## What This Repo Provides
|
|
11
|
+
|
|
12
|
+
- `gripper_config_wizard`
|
|
13
|
+
- staged authoring flow for:
|
|
14
|
+
- global hand config
|
|
15
|
+
- per-link contact anchors
|
|
16
|
+
- grasp templates
|
|
17
|
+
- final preview/confirmation
|
|
18
|
+
- `HandInfo`
|
|
19
|
+
- read-only runtime wrapper around the authored YAML
|
|
20
|
+
- `PointedHandInfo`
|
|
21
|
+
- `HandInfo` plus precomputed surface/contact point samples
|
|
22
|
+
- `HandKinematics`
|
|
23
|
+
- torch forward kinematics for batched joint vectors and link-local point sets
|
|
24
|
+
|
|
25
|
+
## User Workflow
|
|
26
|
+
|
|
27
|
+
1. Prepare a gripper root directory containing at least a URDF.
|
|
28
|
+
2. Run the wizard.
|
|
29
|
+
3. Fill the global stage.
|
|
30
|
+
- palm pose
|
|
31
|
+
- palm points delta
|
|
32
|
+
- global `q_open`
|
|
33
|
+
- extra collision ignore pairs
|
|
34
|
+
4. Fill the keypoint stage.
|
|
35
|
+
- one contact anchor per link
|
|
36
|
+
- point, radius, tags
|
|
37
|
+
5. Fill the grasp template stage.
|
|
38
|
+
- `q_open`, `q_close`
|
|
39
|
+
- `grasp_target_point`
|
|
40
|
+
- active contact anchors
|
|
41
|
+
6. Check the final preview and press `Confirmed`.
|
|
42
|
+
7. Use the saved YAML through `HandInfo`, `PointedHandInfo`, or `HandKinematics`.
|
|
43
|
+
|
|
44
|
+
## Install
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
uv sync
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Wizard
|
|
51
|
+
|
|
52
|
+
Create a new config:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
uv run gripper_config_wizard --gripper-root /path/to/gripper_root
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Edit an existing config:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
uv run gripper_config_wizard \
|
|
62
|
+
--gripper-root /path/to/gripper_root \
|
|
63
|
+
--from-config existing.yaml
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Notes:
|
|
67
|
+
|
|
68
|
+
- `--from-config` relative paths are resolved from `gripper_root`.
|
|
69
|
+
- `urdf_path` and `xml_path` stored in YAML are typically relative paths.
|
|
70
|
+
|
|
71
|
+
## Visualization
|
|
72
|
+
|
|
73
|
+
Inspect a saved config and sampled points:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
uv run python visualize/pointed_hand_info.py --config-path /path/to/hand.yaml
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Inspect batched torch kinematics:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
uv run python visualize/hand_kinematics_batch.py --config-path /path/to/hand.yaml
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Runtime API
|
|
86
|
+
|
|
87
|
+
### `HandInfo`
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
from kmk import HandInfo
|
|
91
|
+
|
|
92
|
+
hand = HandInfo.from_config("hand.yaml")
|
|
93
|
+
q_open = hand.get_q_open()
|
|
94
|
+
q_close = hand.get_q_close("finger4_shallow")
|
|
95
|
+
palm_pose = hand.get_palm_pose()
|
|
96
|
+
anchor = hand.get_contact_anchor_by_link("right_1thumb_distal")
|
|
97
|
+
anchors = hand.get_contact_anchor_by_template("finger4_shallow")
|
|
98
|
+
target = hand.get_grasp_target_point("finger4_shallow")
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Main API:
|
|
102
|
+
|
|
103
|
+
- `HandInfo.from_config(config_path)`
|
|
104
|
+
- `joint_order`
|
|
105
|
+
- `template_names`
|
|
106
|
+
- `contact_anchor_links`
|
|
107
|
+
- `get_q_open(template="global")`
|
|
108
|
+
- `get_q_close(template_name)`
|
|
109
|
+
- `get_palm_pose()`
|
|
110
|
+
- `get_contact_anchor_by_link(link_name)`
|
|
111
|
+
- `get_contact_anchor_by_tag(includes=(), excludes=())`
|
|
112
|
+
- `get_contact_anchor_by_template(template_name)`
|
|
113
|
+
- `get_grasp_target_point(template_name)`
|
|
114
|
+
|
|
115
|
+
### `PointedHandInfo`
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
from kmk import PointedHandInfo
|
|
119
|
+
|
|
120
|
+
hand = PointedHandInfo.from_config("hand.yaml", seed=0)
|
|
121
|
+
surface_points = hand.surface_points
|
|
122
|
+
contact_points = hand.get_contact_points("finger4_shallow")
|
|
123
|
+
keypoints = hand.get_keypoints("finger4_shallow", palm_aligned_points=True)
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Main additions:
|
|
127
|
+
|
|
128
|
+
- `surface_points`
|
|
129
|
+
- `contact_points`
|
|
130
|
+
- `get_contact_points(template_name=None)`
|
|
131
|
+
- `get_keypoints(template_name=None, palm_aligned_points=True, palm_points_delta=...)`
|
|
132
|
+
|
|
133
|
+
### `HandKinematics`
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
import torch
|
|
137
|
+
from kmk import HandInfo, HandKinematics
|
|
138
|
+
|
|
139
|
+
hand = HandInfo.from_config("hand.yaml")
|
|
140
|
+
kin = HandKinematics(hand).to(device="cpu")
|
|
141
|
+
|
|
142
|
+
q = torch.zeros(16, len(hand.joint_order))
|
|
143
|
+
fk = kin.forward_kinematics(q)
|
|
144
|
+
world_points = kin.transform_link_points(
|
|
145
|
+
q,
|
|
146
|
+
{"right_1thumb_distal": torch.tensor([[0.0, 0.0, 0.02]])},
|
|
147
|
+
)
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Main API:
|
|
151
|
+
|
|
152
|
+
- `HandKinematics(hand_info_or_config_path)`
|
|
153
|
+
- `joint_order`
|
|
154
|
+
- `link_names`
|
|
155
|
+
- `dof`
|
|
156
|
+
- `forward_kinematics(q)`
|
|
157
|
+
- `transform_link_points(q, points_by_link)`
|
|
158
|
+
- `get_palm_pose(batch_shape=None)`
|
|
159
|
+
|
|
160
|
+
## Config Schema
|
|
161
|
+
|
|
162
|
+
The detailed spec lives in [`SPEC.md`](/Users/polde/ws/kmk/SPEC.md).
|
kmk-0.1.0/pyproject.toml
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "kmk"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Keypoint-based multi-fingered hand kinematics and configuration tools."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.11"
|
|
7
|
+
dependencies = [
|
|
8
|
+
"numpy>=2.0.0",
|
|
9
|
+
"pyyaml>=6.0.1",
|
|
10
|
+
"scipy>=1.13.0",
|
|
11
|
+
"torch>=2.3.0",
|
|
12
|
+
"tyro>=0.8.12",
|
|
13
|
+
"viser>=1.0.24",
|
|
14
|
+
"yourdfpy>=0.0.60",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
[project.urls]
|
|
18
|
+
Homepage = "https://github.com/kh11kim/kmk.git"
|
|
19
|
+
Repository = "https://github.com/kh11kim/kmk.git"
|
|
20
|
+
|
|
21
|
+
[dependency-groups]
|
|
22
|
+
dev = [
|
|
23
|
+
"playwright>=1.58.0",
|
|
24
|
+
"pytest>=8.2.0",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[build-system]
|
|
28
|
+
requires = ["uv_build>=0.9.6,<0.10.0"]
|
|
29
|
+
build-backend = "uv_build"
|
|
30
|
+
|
|
31
|
+
[project.scripts]
|
|
32
|
+
gripper_config_wizard = "kmk.wizard.cli:main"
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""Config helpers."""
|
|
2
|
+
|
|
3
|
+
from .model import GripperConfig
|
|
4
|
+
from .parse import ParsedUrdfNames, ParsedXmlNames, parse_urdf_names, parse_xml_names
|
|
5
|
+
|
|
6
|
+
__all__ = [
|
|
7
|
+
"GripperConfig",
|
|
8
|
+
"ParsedUrdfNames",
|
|
9
|
+
"ParsedXmlNames",
|
|
10
|
+
"parse_urdf_names",
|
|
11
|
+
"parse_xml_names",
|
|
12
|
+
]
|