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 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).
@@ -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,7 @@
1
+ """kmk package."""
2
+
3
+ from .config.model import GripperConfig
4
+ from .hand_info import HandInfo, PointedHandInfo
5
+ from .kinematics import HandKinematics
6
+
7
+ __all__ = ["GripperConfig", "HandInfo", "PointedHandInfo", "HandKinematics"]
@@ -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
+ ]