dhb-xr 0.2.1__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.
Files changed (82) hide show
  1. dhb_xr/__init__.py +61 -0
  2. dhb_xr/cli.py +206 -0
  3. dhb_xr/core/__init__.py +28 -0
  4. dhb_xr/core/geometry.py +167 -0
  5. dhb_xr/core/geometry_torch.py +77 -0
  6. dhb_xr/core/types.py +113 -0
  7. dhb_xr/database/__init__.py +10 -0
  8. dhb_xr/database/motion_db.py +79 -0
  9. dhb_xr/database/retrieval.py +6 -0
  10. dhb_xr/database/similarity.py +71 -0
  11. dhb_xr/decoder/__init__.py +13 -0
  12. dhb_xr/decoder/decoder_torch.py +52 -0
  13. dhb_xr/decoder/dhb_dr.py +261 -0
  14. dhb_xr/decoder/dhb_qr.py +89 -0
  15. dhb_xr/encoder/__init__.py +27 -0
  16. dhb_xr/encoder/dhb_dr.py +418 -0
  17. dhb_xr/encoder/dhb_qr.py +129 -0
  18. dhb_xr/encoder/dhb_ti.py +204 -0
  19. dhb_xr/encoder/encoder_torch.py +54 -0
  20. dhb_xr/encoder/padding.py +82 -0
  21. dhb_xr/generative/__init__.py +78 -0
  22. dhb_xr/generative/flow_matching.py +705 -0
  23. dhb_xr/generative/latent_encoder.py +536 -0
  24. dhb_xr/generative/sampling.py +203 -0
  25. dhb_xr/generative/training.py +475 -0
  26. dhb_xr/generative/vfm_tokenizer.py +485 -0
  27. dhb_xr/integration/__init__.py +13 -0
  28. dhb_xr/integration/vla/__init__.py +11 -0
  29. dhb_xr/integration/vla/libero.py +132 -0
  30. dhb_xr/integration/vla/pipeline.py +85 -0
  31. dhb_xr/integration/vla/robocasa.py +85 -0
  32. dhb_xr/losses/__init__.py +16 -0
  33. dhb_xr/losses/geodesic_loss.py +91 -0
  34. dhb_xr/losses/hybrid_loss.py +36 -0
  35. dhb_xr/losses/invariant_loss.py +73 -0
  36. dhb_xr/optimization/__init__.py +72 -0
  37. dhb_xr/optimization/casadi_solver.py +342 -0
  38. dhb_xr/optimization/constraints.py +32 -0
  39. dhb_xr/optimization/cusadi_solver.py +311 -0
  40. dhb_xr/optimization/export_casadi_decode.py +111 -0
  41. dhb_xr/optimization/fatrop_solver.py +477 -0
  42. dhb_xr/optimization/torch_solver.py +85 -0
  43. dhb_xr/preprocessing/__init__.py +42 -0
  44. dhb_xr/preprocessing/diagnostics.py +330 -0
  45. dhb_xr/preprocessing/trajectory_cleaner.py +485 -0
  46. dhb_xr/tokenization/__init__.py +56 -0
  47. dhb_xr/tokenization/causal_encoder.py +54 -0
  48. dhb_xr/tokenization/compression.py +749 -0
  49. dhb_xr/tokenization/hierarchical.py +359 -0
  50. dhb_xr/tokenization/rvq.py +178 -0
  51. dhb_xr/tokenization/vqvae.py +155 -0
  52. dhb_xr/utils/__init__.py +24 -0
  53. dhb_xr/utils/io.py +59 -0
  54. dhb_xr/utils/resampling.py +66 -0
  55. dhb_xr/utils/xdof_loader.py +89 -0
  56. dhb_xr/visualization/__init__.py +5 -0
  57. dhb_xr/visualization/plot.py +242 -0
  58. dhb_xr-0.2.1.dist-info/METADATA +784 -0
  59. dhb_xr-0.2.1.dist-info/RECORD +82 -0
  60. dhb_xr-0.2.1.dist-info/WHEEL +5 -0
  61. dhb_xr-0.2.1.dist-info/entry_points.txt +2 -0
  62. dhb_xr-0.2.1.dist-info/top_level.txt +3 -0
  63. examples/__init__.py +54 -0
  64. examples/basic_encoding.py +82 -0
  65. examples/benchmark_backends.py +37 -0
  66. examples/dhb_qr_comparison.py +79 -0
  67. examples/dhb_ti_time_invariant.py +72 -0
  68. examples/gpu_batch_optimization.py +102 -0
  69. examples/imitation_learning.py +53 -0
  70. examples/integration/__init__.py +19 -0
  71. examples/integration/libero_full_demo.py +692 -0
  72. examples/integration/libero_pro_dhb_demo.py +1063 -0
  73. examples/integration/libero_simulation_demo.py +286 -0
  74. examples/integration/libero_swap_demo.py +534 -0
  75. examples/integration/robocasa_libero_dhb_pipeline.py +56 -0
  76. examples/integration/test_libero_adapter.py +47 -0
  77. examples/integration/test_libero_encoding.py +75 -0
  78. examples/integration/test_libero_retrieval.py +105 -0
  79. examples/motion_database.py +88 -0
  80. examples/trajectory_adaptation.py +85 -0
  81. examples/vla_tokenization.py +107 -0
  82. notebooks/__init__.py +24 -0
@@ -0,0 +1,286 @@
1
+ #!/usr/bin/env python
2
+ """LIBERO Simulation Demo with DHB-XR.
3
+
4
+ This script demonstrates:
5
+ 1. Setting up a LIBERO environment
6
+ 2. Loading a demo trajectory from HDF5
7
+ 3. Encoding/decoding with DHB invariants
8
+ 4. Replaying the trajectory in simulation
9
+
10
+ Requirements:
11
+ conda create -n libero python=3.10
12
+ conda activate libero
13
+ pip install robosuite mujoco h5py numpy
14
+ git clone https://github.com/Lifelong-Robot-Learning/LIBERO.git
15
+ cd LIBERO && pip install -e .
16
+ pip install dhb_xr
17
+
18
+ Usage:
19
+ python examples/integration/libero_simulation_demo.py --task_id 0 --render
20
+
21
+ Author: Andy Park
22
+ """
23
+
24
+ import argparse
25
+ import os
26
+ import sys
27
+ from pathlib import Path
28
+
29
+ # Add src to path for development
30
+ sys.path.insert(0, str(Path(__file__).parent.parent.parent / "src"))
31
+
32
+ import numpy as np
33
+
34
+ # Check for LIBERO installation
35
+ try:
36
+ from libero.libero import benchmark, get_libero_path
37
+ from libero.libero.envs import OffScreenRenderEnv
38
+ HAS_LIBERO = True
39
+ except ImportError:
40
+ HAS_LIBERO = False
41
+ print("LIBERO not installed. Install with:")
42
+ print(" git clone https://github.com/Lifelong-Robot-Learning/LIBERO.git")
43
+ print(" cd LIBERO && pip install -e .")
44
+
45
+ # Check for robosuite
46
+ try:
47
+ import robosuite
48
+ HAS_ROBOSUITE = True
49
+ except ImportError:
50
+ HAS_ROBOSUITE = False
51
+ print("robosuite not installed. Install with: pip install robosuite mujoco")
52
+
53
+
54
+ def load_demo_from_hdf5(dataset_path: str, demo_id: int = 0):
55
+ """Load a demo trajectory from LIBERO HDF5 dataset."""
56
+ import h5py
57
+
58
+ with h5py.File(dataset_path, "r") as f:
59
+ demo_key = f"demo_{demo_id}"
60
+ if demo_key not in f["data"]:
61
+ raise ValueError(f"Demo {demo_id} not found in {dataset_path}")
62
+
63
+ demo = f["data"][demo_key]
64
+
65
+ # Extract actions
66
+ actions = np.array(demo["actions"])
67
+
68
+ # Extract end-effector pose from robot_states
69
+ robot_states = np.array(demo["robot_states"])
70
+ ee_pos = robot_states[:, 2:5] # columns 2-4
71
+ ee_quat_wxyz = robot_states[:, 5:9] # columns 5-8 (w, x, y, z)
72
+
73
+ # Convert to (x, y, z, w) format
74
+ ee_quat = ee_quat_wxyz[:, [1, 2, 3, 0]]
75
+
76
+ return {
77
+ "actions": actions,
78
+ "positions": ee_pos,
79
+ "quaternions": ee_quat,
80
+ "num_frames": len(actions),
81
+ }
82
+
83
+
84
+ def encode_demo_with_dhb(positions: np.ndarray, quaternions: np.ndarray):
85
+ """Encode trajectory with DHB-DR."""
86
+ from dhb_xr.encoder.dhb_dr import encode_dhb_dr
87
+ from dhb_xr.core.types import EncodingMethod, DHBMethod
88
+
89
+ result = encode_dhb_dr(
90
+ positions, quaternions,
91
+ method=EncodingMethod.POSITION,
92
+ dhb_method=DHBMethod.DOUBLE_REFLECTION,
93
+ )
94
+
95
+ return {
96
+ "linear_invariants": result["linear_motion_invariants"],
97
+ "angular_invariants": result["angular_motion_invariants"],
98
+ "initial_pose": result["initial_pose"],
99
+ }
100
+
101
+
102
+ def decode_demo_with_dhb(
103
+ linear_inv: np.ndarray,
104
+ angular_inv: np.ndarray,
105
+ initial_pose: dict,
106
+ ):
107
+ """Decode DHB invariants back to trajectory."""
108
+ from dhb_xr.decoder.dhb_dr import decode_dhb_dr
109
+ from dhb_xr.core.types import EncodingMethod, DHBMethod
110
+
111
+ result = decode_dhb_dr(
112
+ linear_inv, angular_inv,
113
+ initial_pose,
114
+ method=EncodingMethod.POSITION,
115
+ dhb_method=DHBMethod.DOUBLE_REFLECTION,
116
+ drop_padded=True,
117
+ )
118
+
119
+ return {
120
+ "positions": result["positions"],
121
+ "quaternions": result["quaternions"],
122
+ }
123
+
124
+
125
+ def run_libero_demo(task_id: int = 0, demo_id: int = 0, render: bool = False):
126
+ """Run a LIBERO task with a demo trajectory."""
127
+
128
+ if not HAS_LIBERO or not HAS_ROBOSUITE:
129
+ print("\nCannot run simulation without LIBERO and robosuite.")
130
+ print("Running DHB encoding/decoding demo only...\n")
131
+
132
+ # Use our downloaded dataset for DHB demo
133
+ dataset_dir = Path(os.environ.get(
134
+ "LIBERO_DATA_DIR",
135
+ "/home/andypark/Projects/data/libero/libero_spatial"
136
+ ))
137
+
138
+ if not dataset_dir.exists():
139
+ print(f"Dataset not found at {dataset_dir}")
140
+ print("Download with:")
141
+ print(" wget -O libero_spatial.zip 'https://utexas.box.com/shared/static/04k94hyizn4huhbv5sz4ev9p2h1p6s7f.zip'")
142
+ return
143
+
144
+ # Find first HDF5 file
145
+ hdf5_files = list(dataset_dir.glob("*.hdf5"))
146
+ if not hdf5_files:
147
+ print(f"No HDF5 files found in {dataset_dir}")
148
+ return
149
+
150
+ dataset_path = str(hdf5_files[0])
151
+ print(f"Loading demo from: {dataset_path}")
152
+
153
+ demo = load_demo_from_hdf5(dataset_path, demo_id)
154
+ print(f"Loaded demo with {demo['num_frames']} frames")
155
+ print(f" Positions shape: {demo['positions'].shape}")
156
+ print(f" Quaternions shape: {demo['quaternions'].shape}")
157
+
158
+ # Encode with DHB
159
+ print("\nEncoding with DHB-DR...")
160
+ encoded = encode_demo_with_dhb(demo["positions"], demo["quaternions"])
161
+ print(f" Linear invariants: {encoded['linear_invariants'].shape}")
162
+ print(f" Angular invariants: {encoded['angular_invariants'].shape}")
163
+
164
+ # Decode back
165
+ print("\nDecoding back to trajectory...")
166
+ decoded = decode_demo_with_dhb(
167
+ encoded["linear_invariants"],
168
+ encoded["angular_invariants"],
169
+ encoded["initial_pose"],
170
+ )
171
+ print(f" Decoded positions: {decoded['positions'].shape}")
172
+ print(f" Decoded quaternions: {decoded['quaternions'].shape}")
173
+
174
+ # Compute reconstruction error
175
+ pos_error = np.linalg.norm(demo["positions"] - decoded["positions"][:len(demo["positions"])], axis=1)
176
+ print(f"\nReconstruction error:")
177
+ print(f" Position: mean={pos_error.mean():.6f}m, max={pos_error.max():.6f}m")
178
+
179
+ print("\n=== DHB encoding/decoding successful! ===")
180
+ print("\nTo run full simulation, install LIBERO:")
181
+ print(" conda create -n libero python=3.10")
182
+ print(" conda activate libero")
183
+ print(" pip install robosuite mujoco")
184
+ print(" git clone https://github.com/Lifelong-Robot-Learning/LIBERO.git")
185
+ print(" cd LIBERO && pip install -e .")
186
+ return
187
+
188
+ # ========== Full LIBERO simulation ==========
189
+ print(f"Setting up LIBERO task {task_id}...")
190
+
191
+ # Get benchmark and task
192
+ benchmark_dict = benchmark.get_benchmark_dict()
193
+ task_suite = benchmark_dict["libero_spatial"]()
194
+
195
+ task = task_suite.get_task(task_id)
196
+ print(f"Task: {task.name}")
197
+ print(f"Description: {task.language}")
198
+
199
+ # Get BDDL file for environment setup
200
+ task_bddl_file = os.path.join(
201
+ get_libero_path("bddl_files"),
202
+ task.problem_folder,
203
+ task.bddl_file
204
+ )
205
+
206
+ # Create environment
207
+ env_args = {
208
+ "bddl_file_name": task_bddl_file,
209
+ "camera_heights": 128,
210
+ "camera_widths": 128,
211
+ }
212
+
213
+ if render:
214
+ env_args["has_renderer"] = True
215
+ env_args["has_offscreen_renderer"] = False
216
+
217
+ env = OffScreenRenderEnv(**env_args)
218
+ env.seed(0)
219
+
220
+ # Get initial states for benchmarking
221
+ init_states = task_suite.get_task_init_states(task_id)
222
+ init_state_id = 0
223
+
224
+ # Reset and set initial state
225
+ env.reset()
226
+ env.set_init_state(init_states[init_state_id])
227
+
228
+ # Load demo actions from dataset
229
+ dataset_path = os.path.join(
230
+ get_libero_path("datasets"),
231
+ "libero_spatial",
232
+ f"{task.name}_demo.hdf5"
233
+ )
234
+
235
+ print(f"Loading demo from: {dataset_path}")
236
+ demo = load_demo_from_hdf5(dataset_path, demo_id)
237
+
238
+ # Encode with DHB
239
+ print("Encoding demo with DHB-DR...")
240
+ encoded = encode_demo_with_dhb(demo["positions"], demo["quaternions"])
241
+
242
+ print(f"Running {demo['num_frames']} steps in simulation...")
243
+
244
+ # Execute demo actions
245
+ for step in range(demo["num_frames"]):
246
+ action = demo["actions"][step]
247
+ obs, reward, done, info = env.step(action)
248
+
249
+ if render:
250
+ env.render()
251
+
252
+ if done:
253
+ print(f"Task completed at step {step}!")
254
+ break
255
+
256
+ # Check final reward
257
+ if reward > 0:
258
+ print("SUCCESS: Task completed!")
259
+ else:
260
+ print("Task not completed within demo length.")
261
+
262
+ env.close()
263
+ print("\nSimulation finished.")
264
+
265
+
266
+ def main():
267
+ parser = argparse.ArgumentParser(description="LIBERO + DHB-XR Demo")
268
+ parser.add_argument("--task_id", type=int, default=0, help="LIBERO task ID")
269
+ parser.add_argument("--demo_id", type=int, default=0, help="Demo ID within task")
270
+ parser.add_argument("--render", action="store_true", help="Render simulation")
271
+ args = parser.parse_args()
272
+
273
+ print("=" * 60)
274
+ print("LIBERO Simulation Demo with DHB-XR")
275
+ print("=" * 60)
276
+ print()
277
+
278
+ run_libero_demo(
279
+ task_id=args.task_id,
280
+ demo_id=args.demo_id,
281
+ render=args.render,
282
+ )
283
+
284
+
285
+ if __name__ == "__main__":
286
+ main()