Upload opentrack.ipynb
Browse files- samples/opentrack.ipynb +148 -38
samples/opentrack.ipynb
CHANGED
|
@@ -33,7 +33,19 @@
|
|
| 33 |
"import threading\n",
|
| 34 |
"import queue\n",
|
| 35 |
"\n",
|
| 36 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
]
|
| 38 |
},
|
| 39 |
{
|
|
@@ -50,14 +62,19 @@
|
|
| 50 |
"outputs": [],
|
| 51 |
"source": [
|
| 52 |
"# Clone the repository if not already cloned\n",
|
| 53 |
-
"if not
|
| 54 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 55 |
" print(\"β Repository cloned successfully\")\n",
|
| 56 |
"else:\n",
|
| 57 |
-
" print(\"β Repository already exists\")\n",
|
| 58 |
"\n",
|
| 59 |
-
"
|
| 60 |
-
"
|
|
|
|
| 61 |
]
|
| 62 |
},
|
| 63 |
{
|
|
@@ -100,23 +117,23 @@
|
|
| 100 |
"source": [
|
| 101 |
"from huggingface_hub import snapshot_download\n",
|
| 102 |
"\n",
|
| 103 |
-
"#
|
| 104 |
-
"mocap_dir =
|
| 105 |
"mocap_dir.mkdir(parents=True, exist_ok=True)\n",
|
| 106 |
"\n",
|
| 107 |
"repo_id = \"robfiras/loco-mujoco-datasets\"\n",
|
| 108 |
"\n",
|
| 109 |
"print(\"Downloading all mocap data from Lafan1/mocap/UnitreeG1...\")\n",
|
|
|
|
| 110 |
"print(\"This will download all .npz files concurrently.\\n\")\n",
|
| 111 |
"\n",
|
| 112 |
"try:\n",
|
| 113 |
" # Use snapshot_download with allow_patterns to download only the files we need\n",
|
| 114 |
-
" # This is much more efficient than downloading files one by one\n",
|
| 115 |
" snapshot_path = snapshot_download(\n",
|
| 116 |
" repo_id=repo_id,\n",
|
| 117 |
" repo_type=\"dataset\",\n",
|
| 118 |
" allow_patterns=\"Lafan1/mocap/UnitreeG1/*.npz\",\n",
|
| 119 |
-
" local_dir
|
| 120 |
" local_dir_use_symlinks=False\n",
|
| 121 |
" )\n",
|
| 122 |
" \n",
|
|
@@ -133,6 +150,22 @@
|
|
| 133 |
" if len(npz_files) > 10:\n",
|
| 134 |
" print(f\" ... and {len(npz_files) - 10} more files\")\n",
|
| 135 |
" \n",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 136 |
"except Exception as e:\n",
|
| 137 |
" print(f\"β Error downloading mocap data: {e}\")\n",
|
| 138 |
" print(\"\\nYou may need to download manually from:\")\n",
|
|
@@ -190,38 +223,76 @@
|
|
| 190 |
" \"\"\"\n",
|
| 191 |
" Find the latest experiment folder matching the pattern\n",
|
| 192 |
" \"\"\"\n",
|
| 193 |
-
"
|
| 194 |
-
"
|
| 195 |
-
" return None\n",
|
| 196 |
" \n",
|
| 197 |
-
"
|
| 198 |
-
"
|
| 199 |
-
"
|
| 200 |
-
"
|
| 201 |
-
"
|
| 202 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 203 |
" \n",
|
| 204 |
-
"
|
|
|
|
|
|
|
| 205 |
"\n",
|
| 206 |
"\n",
|
| 207 |
-
"def find_generated_videos(output_dir
|
| 208 |
" \"\"\"\n",
|
| 209 |
" Find all generated video files\n",
|
| 210 |
" \"\"\"\n",
|
| 211 |
-
"
|
| 212 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 213 |
" # Try alternative locations\n",
|
| 214 |
-
" alternative_dirs = [
|
| 215 |
" for alt_dir in alternative_dirs:\n",
|
| 216 |
-
"
|
| 217 |
-
"
|
| 218 |
-
"
|
| 219 |
-
" return sorted(videos, key=lambda x: x.stat().st_mtime, reverse=True)\n",
|
| 220 |
-
" return []\n",
|
| 221 |
" \n",
|
| 222 |
-
" videos = list(video_dir.glob(\"*.mp4\")) + list(video_dir.glob(\"*.gif\"))\n",
|
| 223 |
" return sorted(videos, key=lambda x: x.stat().st_mtime, reverse=True)\n",
|
| 224 |
"\n",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 225 |
"print(\"β Helper functions loaded\")"
|
| 226 |
]
|
| 227 |
},
|
|
@@ -240,6 +311,11 @@
|
|
| 240 |
"metadata": {},
|
| 241 |
"outputs": [],
|
| 242 |
"source": [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 243 |
"# Run quick training\n",
|
| 244 |
"cmd = [\n",
|
| 245 |
" 'python', 'train_policy.py',\n",
|
|
@@ -253,6 +329,7 @@
|
|
| 253 |
"exp_folder = find_latest_experiment('debug')\n",
|
| 254 |
"if exp_folder:\n",
|
| 255 |
" print(f\"\\nβ Training completed! Experiment: {exp_folder}\")\n",
|
|
|
|
| 256 |
"else:\n",
|
| 257 |
" print(\"\\nβ Could not find experiment folder\")"
|
| 258 |
]
|
|
@@ -306,6 +383,7 @@
|
|
| 306 |
"\n",
|
| 307 |
"if exp_folder:\n",
|
| 308 |
" print(f\"Generating videos for: {exp_folder}\")\n",
|
|
|
|
| 309 |
" \n",
|
| 310 |
" # Use --use_renderer for headless video generation (NOT --use_viewer)\n",
|
| 311 |
" cmd = [\n",
|
|
@@ -327,14 +405,28 @@
|
|
| 327 |
" # Find generated videos\n",
|
| 328 |
" videos = find_generated_videos()\n",
|
| 329 |
" \n",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 330 |
" if videos:\n",
|
| 331 |
-
" print(f\"\\nβ Found {len(videos)} video(s):\")\n",
|
| 332 |
" for video in videos:\n",
|
| 333 |
" print(f\" - {video}\")\n",
|
| 334 |
" else:\n",
|
| 335 |
" print(\"\\nβ No videos found. Checking alternative locations...\")\n",
|
| 336 |
" # Search more broadly\n",
|
| 337 |
-
" all_videos = list(
|
| 338 |
" if all_videos:\n",
|
| 339 |
" print(f\"Found {len(all_videos)} video(s) in project:\")\n",
|
| 340 |
" for video in all_videos[:10]: # Show first 10\n",
|
|
@@ -356,19 +448,20 @@
|
|
| 356 |
"metadata": {},
|
| 357 |
"outputs": [],
|
| 358 |
"source": [
|
| 359 |
-
"# Find and display all generated videos\n",
|
| 360 |
"videos = find_generated_videos()\n",
|
| 361 |
"\n",
|
| 362 |
"if not videos:\n",
|
| 363 |
-
" # Try alternative search\n",
|
| 364 |
-
" videos = list(
|
| 365 |
"\n",
|
| 366 |
"if videos:\n",
|
| 367 |
-
" print(f\"Displaying {len(videos)} video(s):\\n\")\n",
|
| 368 |
" \n",
|
| 369 |
" for i, video_path in enumerate(videos[:5]): # Display first 5 videos\n",
|
| 370 |
" print(f\"\\n{'='*60}\")\n",
|
| 371 |
" print(f\"Video {i+1}: {video_path.name}\")\n",
|
|
|
|
| 372 |
" print(f\"{'='*60}\")\n",
|
| 373 |
" \n",
|
| 374 |
" try:\n",
|
|
@@ -456,16 +549,33 @@
|
|
| 456 |
"4. β
Generating videos using headless MuJoCo renderer\n",
|
| 457 |
"5. β
Displaying videos in the notebook\n",
|
| 458 |
"\n",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 459 |
"**Next Steps:**\n",
|
| 460 |
-
"-
|
| 461 |
"- Run full training with GPU support\n",
|
| 462 |
"- Test on rough terrain\n",
|
| 463 |
"- Experiment with reference motion playback\n",
|
|
|
|
|
|
|
| 464 |
"\n",
|
| 465 |
"**Troubleshooting:**\n",
|
| 466 |
"- If videos aren't generated, check that `--use_renderer` flag is used (not `--use_viewer`)\n",
|
| 467 |
"- Ensure MuJoCo can run headless (may need `xvfb` on some systems)\n",
|
| 468 |
-
"- Check
|
|
|
|
| 469 |
]
|
| 470 |
}
|
| 471 |
],
|
|
|
|
| 33 |
"import threading\n",
|
| 34 |
"import queue\n",
|
| 35 |
"\n",
|
| 36 |
+
"# Define project directory structure\n",
|
| 37 |
+
"PROJECT_BASE = Path(\"/data/workspaces/opentrack\")\n",
|
| 38 |
+
"DATASETS_DIR = PROJECT_BASE / \"datasets\"\n",
|
| 39 |
+
"MODELS_DIR = PROJECT_BASE / \"models\"\n",
|
| 40 |
+
"VIDEOS_DIR = PROJECT_BASE / \"videos\"\n",
|
| 41 |
+
"REPO_DIR = PROJECT_BASE / \"OpenTrack\"\n",
|
| 42 |
+
"\n",
|
| 43 |
+
"# Create directories\n",
|
| 44 |
+
"for dir_path in [PROJECT_BASE, DATASETS_DIR, MODELS_DIR, VIDEOS_DIR]:\n",
|
| 45 |
+
" dir_path.mkdir(parents=True, exist_ok=True)\n",
|
| 46 |
+
" print(f\"β {dir_path}\")\n",
|
| 47 |
+
"\n",
|
| 48 |
+
"print(\"\\nβ Environment setup complete!\")"
|
| 49 |
]
|
| 50 |
},
|
| 51 |
{
|
|
|
|
| 62 |
"outputs": [],
|
| 63 |
"source": [
|
| 64 |
"# Clone the repository if not already cloned\n",
|
| 65 |
+
"if not REPO_DIR.exists():\n",
|
| 66 |
+
" print(f\"Cloning OpenTrack to {REPO_DIR}...\")\n",
|
| 67 |
+
" subprocess.run(\n",
|
| 68 |
+
" ['git', 'clone', 'https://github.com/GalaxyGeneralRobotics/OpenTrack.git', str(REPO_DIR)],\n",
|
| 69 |
+
" check=True\n",
|
| 70 |
+
" )\n",
|
| 71 |
" print(\"β Repository cloned successfully\")\n",
|
| 72 |
"else:\n",
|
| 73 |
+
" print(f\"β Repository already exists at {REPO_DIR}\")\n",
|
| 74 |
"\n",
|
| 75 |
+
"# Change to repository directory\n",
|
| 76 |
+
"os.chdir(REPO_DIR)\n",
|
| 77 |
+
"print(f\"\\nβ Working directory: {os.getcwd()}\")"
|
| 78 |
]
|
| 79 |
},
|
| 80 |
{
|
|
|
|
| 117 |
"source": [
|
| 118 |
"from huggingface_hub import snapshot_download\n",
|
| 119 |
"\n",
|
| 120 |
+
"# Define mocap directory in our datasets folder\n",
|
| 121 |
+
"mocap_dir = DATASETS_DIR / \"lafan1\" / \"UnitreeG1\"\n",
|
| 122 |
"mocap_dir.mkdir(parents=True, exist_ok=True)\n",
|
| 123 |
"\n",
|
| 124 |
"repo_id = \"robfiras/loco-mujoco-datasets\"\n",
|
| 125 |
"\n",
|
| 126 |
"print(\"Downloading all mocap data from Lafan1/mocap/UnitreeG1...\")\n",
|
| 127 |
+
"print(f\"Target directory: {mocap_dir}\")\n",
|
| 128 |
"print(\"This will download all .npz files concurrently.\\n\")\n",
|
| 129 |
"\n",
|
| 130 |
"try:\n",
|
| 131 |
" # Use snapshot_download with allow_patterns to download only the files we need\n",
|
|
|
|
| 132 |
" snapshot_path = snapshot_download(\n",
|
| 133 |
" repo_id=repo_id,\n",
|
| 134 |
" repo_type=\"dataset\",\n",
|
| 135 |
" allow_patterns=\"Lafan1/mocap/UnitreeG1/*.npz\",\n",
|
| 136 |
+
" local_dir=str(DATASETS_DIR),\n",
|
| 137 |
" local_dir_use_symlinks=False\n",
|
| 138 |
" )\n",
|
| 139 |
" \n",
|
|
|
|
| 150 |
" if len(npz_files) > 10:\n",
|
| 151 |
" print(f\" ... and {len(npz_files) - 10} more files\")\n",
|
| 152 |
" \n",
|
| 153 |
+
" # Create symlink from OpenTrack's expected data directory to our datasets\n",
|
| 154 |
+
" opentrack_data_dir = REPO_DIR / \"data\" / \"mocap\"\n",
|
| 155 |
+
" opentrack_data_dir.parent.mkdir(parents=True, exist_ok=True)\n",
|
| 156 |
+
" \n",
|
| 157 |
+
" # Remove old symlink/directory if it exists\n",
|
| 158 |
+
" if opentrack_data_dir.exists() or opentrack_data_dir.is_symlink():\n",
|
| 159 |
+
" if opentrack_data_dir.is_symlink():\n",
|
| 160 |
+
" opentrack_data_dir.unlink()\n",
|
| 161 |
+
" else:\n",
|
| 162 |
+
" import shutil\n",
|
| 163 |
+
" shutil.rmtree(opentrack_data_dir)\n",
|
| 164 |
+
" \n",
|
| 165 |
+
" # Create symlink\n",
|
| 166 |
+
" opentrack_data_dir.symlink_to(DATASETS_DIR, target_is_directory=True)\n",
|
| 167 |
+
" print(f\"\\nβ Created symlink: {opentrack_data_dir} -> {DATASETS_DIR}\")\n",
|
| 168 |
+
" \n",
|
| 169 |
"except Exception as e:\n",
|
| 170 |
" print(f\"β Error downloading mocap data: {e}\")\n",
|
| 171 |
" print(\"\\nYou may need to download manually from:\")\n",
|
|
|
|
| 223 |
" \"\"\"\n",
|
| 224 |
" Find the latest experiment folder matching the pattern\n",
|
| 225 |
" \"\"\"\n",
|
| 226 |
+
" # Check both MODELS_DIR and REPO_DIR/logs\n",
|
| 227 |
+
" search_dirs = [MODELS_DIR, REPO_DIR / \"logs\"]\n",
|
|
|
|
| 228 |
" \n",
|
| 229 |
+
" all_experiments = []\n",
|
| 230 |
+
" for logs_dir in search_dirs:\n",
|
| 231 |
+
" if not logs_dir.exists():\n",
|
| 232 |
+
" continue\n",
|
| 233 |
+
" \n",
|
| 234 |
+
" # Find all matching experiments\n",
|
| 235 |
+
" experiments = [\n",
|
| 236 |
+
" d for d in logs_dir.iterdir() \n",
|
| 237 |
+
" if d.is_dir() and exp_name_pattern in d.name\n",
|
| 238 |
+
" ]\n",
|
| 239 |
+
" all_experiments.extend(experiments)\n",
|
| 240 |
+
" \n",
|
| 241 |
+
" if not all_experiments:\n",
|
| 242 |
+
" return None\n",
|
| 243 |
" \n",
|
| 244 |
+
" # Sort by modification time and return latest\n",
|
| 245 |
+
" latest = sorted(all_experiments, key=lambda x: x.stat().st_mtime, reverse=True)[0]\n",
|
| 246 |
+
" return latest.name\n",
|
| 247 |
"\n",
|
| 248 |
"\n",
|
| 249 |
+
"def find_generated_videos(output_dir=None):\n",
|
| 250 |
" \"\"\"\n",
|
| 251 |
" Find all generated video files\n",
|
| 252 |
" \"\"\"\n",
|
| 253 |
+
" if output_dir is None:\n",
|
| 254 |
+
" output_dir = VIDEOS_DIR\n",
|
| 255 |
+
" else:\n",
|
| 256 |
+
" output_dir = Path(output_dir)\n",
|
| 257 |
+
" \n",
|
| 258 |
+
" videos = []\n",
|
| 259 |
+
" \n",
|
| 260 |
+
" if output_dir.exists():\n",
|
| 261 |
+
" videos = list(output_dir.glob(\"*.mp4\")) + list(output_dir.glob(\"*.gif\"))\n",
|
| 262 |
+
" \n",
|
| 263 |
+
" if not videos:\n",
|
| 264 |
" # Try alternative locations\n",
|
| 265 |
+
" alternative_dirs = [REPO_DIR, REPO_DIR / \"logs\", MODELS_DIR]\n",
|
| 266 |
" for alt_dir in alternative_dirs:\n",
|
| 267 |
+
" if alt_dir.exists():\n",
|
| 268 |
+
" found = list(alt_dir.glob(\"**/*.mp4\")) + list(alt_dir.glob(\"**/*.gif\"))\n",
|
| 269 |
+
" videos.extend(found)\n",
|
|
|
|
|
|
|
| 270 |
" \n",
|
|
|
|
| 271 |
" return sorted(videos, key=lambda x: x.stat().st_mtime, reverse=True)\n",
|
| 272 |
"\n",
|
| 273 |
+
"\n",
|
| 274 |
+
"def setup_model_output_symlink():\n",
|
| 275 |
+
" \"\"\"\n",
|
| 276 |
+
" Create symlink from OpenTrack's logs directory to our models directory\n",
|
| 277 |
+
" \"\"\"\n",
|
| 278 |
+
" opentrack_logs_dir = REPO_DIR / \"logs\"\n",
|
| 279 |
+
" \n",
|
| 280 |
+
" # Remove old symlink/directory if it exists\n",
|
| 281 |
+
" if opentrack_logs_dir.exists() or opentrack_logs_dir.is_symlink():\n",
|
| 282 |
+
" if opentrack_logs_dir.is_symlink():\n",
|
| 283 |
+
" opentrack_logs_dir.unlink()\n",
|
| 284 |
+
" else:\n",
|
| 285 |
+
" import shutil\n",
|
| 286 |
+
" # Move existing logs to MODELS_DIR first\n",
|
| 287 |
+
" if opentrack_logs_dir.is_dir():\n",
|
| 288 |
+
" for item in opentrack_logs_dir.iterdir():\n",
|
| 289 |
+
" shutil.move(str(item), str(MODELS_DIR))\n",
|
| 290 |
+
" shutil.rmtree(opentrack_logs_dir)\n",
|
| 291 |
+
" \n",
|
| 292 |
+
" # Create symlink\n",
|
| 293 |
+
" opentrack_logs_dir.symlink_to(MODELS_DIR, target_is_directory=True)\n",
|
| 294 |
+
" print(f\"β Created symlink: {opentrack_logs_dir} -> {MODELS_DIR}\")\n",
|
| 295 |
+
"\n",
|
| 296 |
"print(\"β Helper functions loaded\")"
|
| 297 |
]
|
| 298 |
},
|
|
|
|
| 311 |
"metadata": {},
|
| 312 |
"outputs": [],
|
| 313 |
"source": [
|
| 314 |
+
"# Setup symlink for model outputs\n",
|
| 315 |
+
"setup_model_output_symlink()\n",
|
| 316 |
+
"\n",
|
| 317 |
+
"print(f\"\\nModels will be saved to: {MODELS_DIR}\\n\")\n",
|
| 318 |
+
"\n",
|
| 319 |
"# Run quick training\n",
|
| 320 |
"cmd = [\n",
|
| 321 |
" 'python', 'train_policy.py',\n",
|
|
|
|
| 329 |
"exp_folder = find_latest_experiment('debug')\n",
|
| 330 |
"if exp_folder:\n",
|
| 331 |
" print(f\"\\nβ Training completed! Experiment: {exp_folder}\")\n",
|
| 332 |
+
" print(f\"β Model saved in: {MODELS_DIR / exp_folder}\")\n",
|
| 333 |
"else:\n",
|
| 334 |
" print(\"\\nβ Could not find experiment folder\")"
|
| 335 |
]
|
|
|
|
| 383 |
"\n",
|
| 384 |
"if exp_folder:\n",
|
| 385 |
" print(f\"Generating videos for: {exp_folder}\")\n",
|
| 386 |
+
" print(f\"Videos will be saved to: {VIDEOS_DIR}\\n\")\n",
|
| 387 |
" \n",
|
| 388 |
" # Use --use_renderer for headless video generation (NOT --use_viewer)\n",
|
| 389 |
" cmd = [\n",
|
|
|
|
| 405 |
" # Find generated videos\n",
|
| 406 |
" videos = find_generated_videos()\n",
|
| 407 |
" \n",
|
| 408 |
+
" # Move videos to VIDEOS_DIR if they're not already there\n",
|
| 409 |
+
" if videos:\n",
|
| 410 |
+
" import shutil\n",
|
| 411 |
+
" moved_videos = []\n",
|
| 412 |
+
" for video in videos:\n",
|
| 413 |
+
" if not video.is_relative_to(VIDEOS_DIR):\n",
|
| 414 |
+
" dest = VIDEOS_DIR / video.name\n",
|
| 415 |
+
" shutil.copy2(video, dest)\n",
|
| 416 |
+
" moved_videos.append(dest)\n",
|
| 417 |
+
" print(f\"Moved: {video.name} -> {dest}\")\n",
|
| 418 |
+
" else:\n",
|
| 419 |
+
" moved_videos.append(video)\n",
|
| 420 |
+
" videos = moved_videos\n",
|
| 421 |
+
" \n",
|
| 422 |
" if videos:\n",
|
| 423 |
+
" print(f\"\\nβ Found {len(videos)} video(s) in {VIDEOS_DIR}:\")\n",
|
| 424 |
" for video in videos:\n",
|
| 425 |
" print(f\" - {video}\")\n",
|
| 426 |
" else:\n",
|
| 427 |
" print(\"\\nβ No videos found. Checking alternative locations...\")\n",
|
| 428 |
" # Search more broadly\n",
|
| 429 |
+
" all_videos = list(REPO_DIR.rglob(\"*.mp4\")) + list(REPO_DIR.rglob(\"*.gif\"))\n",
|
| 430 |
" if all_videos:\n",
|
| 431 |
" print(f\"Found {len(all_videos)} video(s) in project:\")\n",
|
| 432 |
" for video in all_videos[:10]: # Show first 10\n",
|
|
|
|
| 448 |
"metadata": {},
|
| 449 |
"outputs": [],
|
| 450 |
"source": [
|
| 451 |
+
"# Find and display all generated videos from our videos directory\n",
|
| 452 |
"videos = find_generated_videos()\n",
|
| 453 |
"\n",
|
| 454 |
"if not videos:\n",
|
| 455 |
+
" # Try alternative search in the whole project\n",
|
| 456 |
+
" videos = list(REPO_DIR.rglob(\"*.mp4\")) + list(REPO_DIR.rglob(\"*.gif\"))\n",
|
| 457 |
"\n",
|
| 458 |
"if videos:\n",
|
| 459 |
+
" print(f\"Displaying {len(videos)} video(s) from {VIDEOS_DIR}:\\n\")\n",
|
| 460 |
" \n",
|
| 461 |
" for i, video_path in enumerate(videos[:5]): # Display first 5 videos\n",
|
| 462 |
" print(f\"\\n{'='*60}\")\n",
|
| 463 |
" print(f\"Video {i+1}: {video_path.name}\")\n",
|
| 464 |
+
" print(f\"Location: {video_path}\")\n",
|
| 465 |
" print(f\"{'='*60}\")\n",
|
| 466 |
" \n",
|
| 467 |
" try:\n",
|
|
|
|
| 549 |
"4. β
Generating videos using headless MuJoCo renderer\n",
|
| 550 |
"5. β
Displaying videos in the notebook\n",
|
| 551 |
"\n",
|
| 552 |
+
"**Project Structure:**\n",
|
| 553 |
+
"```\n",
|
| 554 |
+
"/data/workspaces/opentrack/\n",
|
| 555 |
+
"βββ datasets/ # Motion capture data (.npz files)\n",
|
| 556 |
+
"β βββ lafan1/\n",
|
| 557 |
+
"β βββ UnitreeG1/\n",
|
| 558 |
+
"βββ models/ # Trained models and checkpoints\n",
|
| 559 |
+
"β βββ <timestamp>_<exp_name>/\n",
|
| 560 |
+
"βββ videos/ # Generated videos (.mp4, .gif)\n",
|
| 561 |
+
"βββ OpenTrack/ # Cloned repository\n",
|
| 562 |
+
" βββ data/mocap -> ../datasets/ (symlink)\n",
|
| 563 |
+
" βββ logs -> ../models/ (symlink)\n",
|
| 564 |
+
"```\n",
|
| 565 |
+
"\n",
|
| 566 |
"**Next Steps:**\n",
|
| 567 |
+
"- All mocap data is in `/data/workspaces/opentrack/datasets/`\n",
|
| 568 |
"- Run full training with GPU support\n",
|
| 569 |
"- Test on rough terrain\n",
|
| 570 |
"- Experiment with reference motion playback\n",
|
| 571 |
+
"- Trained models are saved in `/data/workspaces/opentrack/models/`\n",
|
| 572 |
+
"- Generated videos are in `/data/workspaces/opentrack/videos/`\n",
|
| 573 |
"\n",
|
| 574 |
"**Troubleshooting:**\n",
|
| 575 |
"- If videos aren't generated, check that `--use_renderer` flag is used (not `--use_viewer`)\n",
|
| 576 |
"- Ensure MuJoCo can run headless (may need `xvfb` on some systems)\n",
|
| 577 |
+
"- Check `/data/workspaces/opentrack/models/` directory for experiment outputs\n",
|
| 578 |
+
"- All data persists in `/data/workspaces/opentrack/` across notebook sessions"
|
| 579 |
]
|
| 580 |
}
|
| 581 |
],
|