ae28d55f81
Source: RGB-D -> Dyn-HaMR -> L20 retargeting -> FoundationPose -> reference repair -> SPIDER, documented in docs/PIPELINE_LATEST.md and docs/SETUP_AND_WEIGHTS.md. Adds FoundationPose and nvdiffrast upstream snapshots, requirements/pipeline_venv.txt and the FoundationPose weight manifest/downloader. Assets (Git LFS): weights/ (WiLoR detector, HandFlow denoiser, UniDepth-L), FoundationPose checkpoints, HaMeR checkpoint, Dyn-HaMR HMP model and BMC constraints, L20 URDF/meshes, the 20260915_171525 D405 recording and the two box CADs. MANO models are not redistributed (third_party/hamer/_DATA/data/mano/README.txt). Environments, caches and run outputs excluded. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
34 lines
2.2 KiB
Python
34 lines
2.2 KiB
Python
"""Download and verify the FoundationPose checkpoints listed in configs/foundationpose_weights_manifest.json.
|
|
|
|
Files go to third_party/FoundationPose/weights/<run>/{config.yml, model_best.pth}; resumable (Range requests), SHA-256 checked.
|
|
The manifest URLs point at a community Hugging Face mirror (official Google Drive quota was exceeded when the snapshot was made);
|
|
replace `url` entries with the official links if you have them. Usage: .venv/bin/python scripts/download_foundationpose_weights.py
|
|
"""
|
|
import hashlib, json, time
|
|
from pathlib import Path
|
|
import requests
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
manifest = json.loads((ROOT / 'configs/foundationpose_weights_manifest.json').read_text())
|
|
dest = ROOT / 'third_party/FoundationPose/weights'
|
|
for item in manifest['files']:
|
|
path = dest / item['path']; path.parent.mkdir(parents=True, exist_ok=True); tmp = path.with_suffix(path.suffix + '.part')
|
|
if path.exists() and path.stat().st_size == item['size'] and hashlib.sha256(path.read_bytes()).hexdigest() == item['sha256']:
|
|
print('ok ', item['path']); continue
|
|
for attempt in range(5):
|
|
try:
|
|
offset = tmp.stat().st_size if tmp.exists() else 0
|
|
print(f'download {item["path"]} from byte {offset}', flush=True)
|
|
with requests.get(item['url'], headers={'Range': f'bytes={offset}-{item["size"] - 1}'}, stream=True, timeout=(20, 60)) as r:
|
|
r.raise_for_status()
|
|
if offset and r.status_code != 206: offset = 0
|
|
with tmp.open('ab' if offset else 'wb') as f:
|
|
for chunk in r.iter_content(1024 * 1024): f.write(chunk)
|
|
if tmp.stat().st_size == item['size']: tmp.replace(path); break
|
|
except requests.RequestException as e:
|
|
print('retry:', type(e).__name__, flush=True); time.sleep(3)
|
|
assert path.exists() and path.stat().st_size == item['size'], f'incomplete: {path}'
|
|
digest = hashlib.sha256(path.read_bytes()).hexdigest(); assert digest == item['sha256'], f'sha256 mismatch: {path}'
|
|
print('verified', item['path'], flush=True)
|
|
(dest / 'download_manifest.json').write_text(json.dumps(manifest, indent=2)); print('all FoundationPose weights present in', dest)
|