robot-keyframe-kit 0.3.0__tar.gz → 0.3.2__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.
Files changed (19) hide show
  1. {robot_keyframe_kit-0.3.0/src/robot_keyframe_kit.egg-info → robot_keyframe_kit-0.3.2}/PKG-INFO +1 -1
  2. {robot_keyframe_kit-0.3.0 → robot_keyframe_kit-0.3.2}/pyproject.toml +4 -4
  3. {robot_keyframe_kit-0.3.0 → robot_keyframe_kit-0.3.2}/src/robot_keyframe_kit/__init__.py +0 -6
  4. {robot_keyframe_kit-0.3.0 → robot_keyframe_kit-0.3.2}/src/robot_keyframe_kit/config.py +10 -30
  5. {robot_keyframe_kit-0.3.0 → robot_keyframe_kit-0.3.2}/src/robot_keyframe_kit/editor.py +160 -543
  6. {robot_keyframe_kit-0.3.0 → robot_keyframe_kit-0.3.2}/src/robot_keyframe_kit/keyframe.py +2 -7
  7. robot_keyframe_kit-0.3.2/src/robot_keyframe_kit/math_utils.py +196 -0
  8. {robot_keyframe_kit-0.3.0 → robot_keyframe_kit-0.3.2}/src/robot_keyframe_kit/sim_worker.py +46 -108
  9. {robot_keyframe_kit-0.3.0 → robot_keyframe_kit-0.3.2/src/robot_keyframe_kit.egg-info}/PKG-INFO +1 -1
  10. robot_keyframe_kit-0.3.0/src/robot_keyframe_kit/math_utils.py +0 -111
  11. {robot_keyframe_kit-0.3.0 → robot_keyframe_kit-0.3.2}/LICENSE +0 -0
  12. {robot_keyframe_kit-0.3.0 → robot_keyframe_kit-0.3.2}/MANIFEST.in +0 -0
  13. {robot_keyframe_kit-0.3.0 → robot_keyframe_kit-0.3.2}/README.md +0 -0
  14. {robot_keyframe_kit-0.3.0 → robot_keyframe_kit-0.3.2}/setup.cfg +0 -0
  15. {robot_keyframe_kit-0.3.0 → robot_keyframe_kit-0.3.2}/src/robot_keyframe_kit.egg-info/SOURCES.txt +0 -0
  16. {robot_keyframe_kit-0.3.0 → robot_keyframe_kit-0.3.2}/src/robot_keyframe_kit.egg-info/dependency_links.txt +0 -0
  17. {robot_keyframe_kit-0.3.0 → robot_keyframe_kit-0.3.2}/src/robot_keyframe_kit.egg-info/entry_points.txt +0 -0
  18. {robot_keyframe_kit-0.3.0 → robot_keyframe_kit-0.3.2}/src/robot_keyframe_kit.egg-info/requires.txt +0 -0
  19. {robot_keyframe_kit-0.3.0 → robot_keyframe_kit-0.3.2}/src/robot_keyframe_kit.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: robot-keyframe-kit
3
- Version: 0.3.0
3
+ Version: 0.3.2
4
4
  Summary: A generalizable Viser-based keyframe editor for any MuJoCo robot
5
5
  Author-email: Stanford TML <yuming29@stanford.edu>
6
6
  Maintainer-email: Stanford TML <yuming29@stanford.edu>
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "robot-keyframe-kit"
7
- version = "0.3.0"
7
+ version = "0.3.2"
8
8
  description = "A generalizable Viser-based keyframe editor for any MuJoCo robot"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -64,9 +64,9 @@ robot_keyframe_kit = ["py.typed"]
64
64
  "*" = ["examples/*", "keyframes/*", "*.lz4", "*.stl", "*.dae"]
65
65
 
66
66
  [tool.black]
67
- line-length = 88
67
+ line-length = 120
68
68
  target-version = ["py310"]
69
69
 
70
70
  [tool.ruff]
71
- line-length = 88
72
- select = ["E", "F", "I"]
71
+ line-length = 120
72
+ lint.select = ["E", "F", "I"]
@@ -6,9 +6,3 @@ from .keyframe import Keyframe
6
6
 
7
7
  __version__ = "0.1.0"
8
8
  __all__ = ["ViserKeyframeEditor", "EditorConfig", "Keyframe"]
9
-
10
-
11
-
12
-
13
-
14
-
@@ -3,7 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import os
6
- from dataclasses import dataclass, field
6
+ from dataclasses import dataclass
7
7
  from typing import Dict, List, Optional
8
8
 
9
9
  try:
@@ -48,9 +48,7 @@ class EditorConfig:
48
48
  # Note: Position-type actuators (like Unitree G1) use MuJoCo's built-in PD.
49
49
  kp: float = 12.0 # Position gain (proportional) - matches typical Dynamixel motors
50
50
  kd: float = 0.5 # Velocity gain (derivative) - light damping
51
- motor_tau_limit: float = (
52
- 1.0 # Fallback |tau| clamp for torque actuators without model limits
53
- )
51
+ motor_tau_limit: float = 1.0 # Fallback |tau| clamp for torque actuators without model limits
54
52
 
55
53
  # UI settings
56
54
  show_com: bool = True # Show center of mass marker
@@ -59,12 +57,8 @@ class EditorConfig:
59
57
  root_pose_gizmo_scale: float = 0.35 # Base scale for root pose transform gizmo
60
58
  ik_target_gizmo_scale: float = 0.18 # Base scale for IK target transform gizmos
61
59
  auto_scale_gizmos: bool = True # Scale gizmos based on robot model size
62
- gizmo_scale_ratio: float = (
63
- 1.0 # Optional global multiplier applied after auto-scaling
64
- )
65
- gizmo_reference_height: float = (
66
- 1.28 # Height (m) where base gizmo scales are unchanged
67
- )
60
+ gizmo_scale_ratio: float = 1.0 # Optional global multiplier applied after auto-scaling
61
+ gizmo_reference_height: float = 1.28 # Height (m) where base gizmo scales are unchanged
68
62
 
69
63
  # Scene generation settings
70
64
  auto_inject_floor: bool = True # Whether to auto-inject floor for robot-only XMLs
@@ -85,10 +79,7 @@ class EditorConfig:
85
79
  FileNotFoundError: If the config file doesn't exist.
86
80
  """
87
81
  if yaml is None:
88
- raise ImportError(
89
- "PyYAML is required to load YAML config files. "
90
- "Install with: pip install pyyaml"
91
- )
82
+ raise ImportError("PyYAML is required to load YAML config files. Install with: pip install pyyaml")
92
83
 
93
84
  if not os.path.exists(path):
94
85
  raise FileNotFoundError(f"Config file not found: {path}")
@@ -174,10 +165,7 @@ class EditorConfig:
174
165
  ImportError: If PyYAML is not installed.
175
166
  """
176
167
  if yaml is None:
177
- raise ImportError(
178
- "PyYAML is required to save YAML config files. "
179
- "Install with: pip install pyyaml"
180
- )
168
+ raise ImportError("PyYAML is required to save YAML config files. Install with: pip install pyyaml")
181
169
 
182
170
  data = {
183
171
  "name": self.name,
@@ -212,16 +200,12 @@ class EditorConfig:
212
200
  # Remove None values
213
201
  data = {k: v for k, v in data.items() if v is not None}
214
202
 
215
- os.makedirs(
216
- os.path.dirname(path) if os.path.dirname(path) else ".", exist_ok=True
217
- )
203
+ os.makedirs(os.path.dirname(path) if os.path.dirname(path) else ".", exist_ok=True)
218
204
  with open(path, "w") as f:
219
205
  yaml.dump(data, f, default_flow_style=False, sort_keys=False)
220
206
 
221
207
  @classmethod
222
- def generate_from_model(
223
- cls, xml_path: str, name: Optional[str] = None
224
- ) -> "EditorConfig":
208
+ def generate_from_model(cls, xml_path: str, name: Optional[str] = None) -> "EditorConfig":
225
209
  """Generate a configuration file from a MuJoCo model by auto-detecting settings.
226
210
 
227
211
  This creates a config with auto-detected values that can be manually edited.
@@ -262,9 +246,7 @@ class EditorConfig:
262
246
  for body_id in leaf_body_ids:
263
247
  for site_id in range(model.nsite):
264
248
  if model.site_bodyid[site_id] == body_id:
265
- site_name = mujoco.mj_id2name(
266
- model, mujoco.mjtObj.mjOBJ_SITE, site_id
267
- )
249
+ site_name = mujoco.mj_id2name(model, mujoco.mjtObj.mjOBJ_SITE, site_id)
268
250
  if site_name:
269
251
  end_effectors.append(site_name)
270
252
 
@@ -289,9 +271,7 @@ class EditorConfig:
289
271
  for joint_name in joint_names:
290
272
  if "left" in joint_name.lower() or "_l_" in joint_name.lower():
291
273
  # Try to find corresponding right joint
292
- right_name = joint_name.replace("left", "right").replace(
293
- "Left", "Right"
294
- )
274
+ right_name = joint_name.replace("left", "right").replace("Left", "Right")
295
275
  right_name_alt = joint_name.replace("_l_", "_r_").replace("_L_", "_R_")
296
276
 
297
277
  if right_name in joint_names: