Files
liyang ae28d55f81 Update to 2026-09-17 pipeline snapshot; add weights, L20 assets and recording via Git LFS
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>
2026-09-17 11:43:37 +08:00

13 lines
7.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from pathlib import Path
import json,numpy as np,mujoco,cv2
R=Path(__file__).resolve().parents[1];O=R/'output/collision_fix_20260915';T=O/'datasets/processed/current/l20/bimanual/boxes';v=json.loads((O/'validation.json').read_text());phys=json.loads((O/'physics_validation.json').read_text()) if (O/'physics_validation.json').exists() else None
m=mujoco.MjModel.from_xml_path(str(T/'scene_act.xml'));ref=np.load(T/'0/trajectory_kinematic_act.npz');np.savetxt(O/'reference_trajectory.csv',np.c_[ref['time'],ref['qpos'],ref['ctrl']],delimiter=',',header=','.join(['time_s']+[m.joint(i).name for i in range(m.njnt)]+['ctrl_'+m.actuator(i).name for i in range(m.nu)]),comments='')
c=cv2.VideoCapture(str(O/'hand_collision_before_after.mp4'));n=0
while c.read()[0]:n+=1
c.release();assert n==352;(O/'video_integrity.json').write_text(json.dumps({'decoded_frames':n,'expected':352,'passed':True},indent=2))
b=v['before_same_new_collision_model'];a=v['corrected_reference'];lines=['# 双手与红/蓝盒碰撞修复','', '**状态:参考轨迹的手物碰撞修复已通过;Spider 自由物体动态抓取验证仍失败,仍有短时穿透和明显物体偏离。**','', '输入仍为 `docs/20260915_171525`。FoundationPose 物体位姿及有效标记沿用上一轮。修复输出独立保存,旧结果未覆盖。','', '## 修复内容','', '- 两个 CAD 的 T 形网格连接修复:只拆分共线三角形边,顶点、表面积与体积不变;两个模型均闭合。','- 红/蓝盒碰撞由各 20 个凸块改为 94/96 个有效凸块;手掌与拇指根部分离视觉网格和分块碰撞网格。它们仍是碰撞近似。','- 逐连杆检测碰撞,用解析接触法向与运动学雅可比构造分离约束;保持关节限位及原 URDF 线性 mimic。','- 接触时沿物体运动延续上一帧手姿,加相邻帧运动限制,避免从盒子一侧突然跳到另一侧。','- 手腕及物体旋转使用四元数 SLERP 插值,再选择连续欧拉角分支供 Spider 使用。逐个检查并修正全部 400 Hz 插值状态。','- 增加 2.5 mm 碰撞安全间隙,覆盖凸分解与原始表面的部分误差。','- 物理接触参数从较软的时间常数改为 5 ms,阻抗 `.999 .9999 .0001`,接触求解迭代提高到 80 次;手腕平移最大推力 20 N、旋转最大力矩 2 Nm、手指最大力矩 0.1 Nm(仿真假设);初始桌面向下校正 9.84 mm,消除盒子初态与桌面的重叠。这是仿真对齐假设,不是新观测。','', '## 参考轨迹验证','', '以下前后对比使用同一套新碰撞几何,避免把更换模型本身算作轨迹改善。','', '| 指标 | 修复前 | 修复后 |','|---|---:|---:|',f'| 全 352 帧最大手物穿透/mm | {b["max_hand_object_penetration_mm"]:.2f} | {a["max_hand_object_penetration_mm"]:.2f} |',f'| 穿透超过 0.5 mm 的帧数 | {b["frames_over_0_5mm"]} | {a["frames_over_0_5mm"]} |',f'| 推断接触目标平均间隙/mm | {b["inferred_contact_gap_mean_mm"]:.2f} | {a["inferred_contact_gap_mean_mm"]:.2f} |', '',f'全部 4,681 个高频状态:最大手物穿透 **{v["interpolation"]["max_penetration_after_mm"]:.3f} mm**。状态均有限;物体坐标未更改。关节限位最大超出 {a["max_joint_limit_violation_rad"]:.3g} radmimic 最大残差 {a["max_mimic_error_rad"]:.3g} rad。','',f'独立使用原始手部视觉网格的 {v["cad_probe_scope"].split()[0]} 个表面采样点/帧,对闭合原始 CAD 检查:红盒最大侵入 **{v["upper_exact_CAD_surface_probes"]["max_inside_mm"]:.2f} mm**,蓝盒 **{v["lower_exact_CAD_surface_probes"]["max_inside_mm"]:.2f} mm**,超过 1 mm 的帧数均为零。采样检查不是完整网格相交证明。','', '## 代价与边界','', '- 本次修复范围是双手与两个盒子的碰撞,不包含手部自碰撞或手与桌面的完整验证。','- 原始手—物体配准偏差较大,修复有明显手腕位移;右/左手相对旧接触参考的修正中位数分别为 '+f'{v["wrist_correction_mm"]["right"]["median"]:.1f}/{v["wrist_correction_mm"]["left"]["median"]:.1f} mm。这不能当作已校准的人手绝对位姿。','- 指尖接触目标来自距离推断,平均间隙仍约 '+f'{a["inferred_contact_gap_mean_mm"]:.1f} mm。防穿透通过不等于稳定抓取通过。','- 蓝盒第 177 帧起被遮挡,仍保持最后可靠参考位姿;这部分没有新增观测。','']
if phys:
lines+=['## SPIDER 实际物理滚动','',f'完整 {phys["steps"]} 步 / {phys["duration_s"]:.2f} 秒,全部有限值:{phys["all_finite"]};物体真实执行器增益为零:{phys["zero_object_actuator_gains"]}。', '',f'独立 CPU 碰撞检测检查每个保存的 GPU 状态:最大穿透 **{phys["max_penetration_mm"]:.2f} mm**,逐步最大穿透中位数 **{phys["median_step_max_penetration_mm"]:.2f} mm**,超过 1 mm 的步数 {phys["steps_over_1mm"]}。', '',f'物体中心最大误差(仅可观测段):红盒 {phys["upper"]["observed_centroid_error_max_mm"]:.1f} mm,蓝盒 {phys["lower"]["observed_centroid_error_max_mm"]:.1f} mm;20 mm 抓取跟踪门槛通过:**{phys["grasp_tracking_20mm_passed"]}**。','', f'实际发生手物接近/接触的物理步数 {phys["steps_with_hand_object_contact"]}/{phys["steps"]};最大物理关节限位超出 {phys["max_joint_limit_violation_rad"]:.4f} rad。碰撞变少也可能来自接触丢失,不能独立证明抓取成功。','参考轨迹修复和真实物理结果分开保存;没有通过强制写回物体位姿制造成功抓取。','']
lines+=['## 文件','', '- `hand_collision_before_after.mp4`:原视频 / 修复前参考 / 修复后参考。视频明确标为运动学对比。','- `reference_video_rate.npz`、`reference_trajectory.csv`:修复后的手与物体参考及高频关节/控制数据。','- `validation.json`:同模型前后碰撞、关节限位、mimic、原 CAD 表面探针。','- `interpolation_validation.json`:全部高频状态检查。开启 buffer 时,`max_penetration_before_mm` 字段表示距所要求间隙的不足,见 `before_metric`after 字段始终表示实际穿透。','- `spider_collision_rollout.mp4`:修复参考与实际 Spider 自由物体滚动对比。','- `physics_validation.json`、`physics_motion.npz`:实际 Spider 物理结果(失败验证,不能视为可用抓取控制)。','- `dynamics_probe.json`:同一组保存控制量的 CPU 参数对比;CPU 中小于 1 mm 的结果未在本次 GPU 优化中完整复现。','- `collision_v2/`、`hand_collision/`:新碰撞几何;`datasets/processed/current/l20/bimanual/boxes/scene_act.xml` 为完整场景。','', '## 复现','', '```bash','.venv/bin/python scripts/build_box_collision_v2.py','.venv/bin/python scripts/build_palm_collision_v2.py','.venv/bin/python scripts/fix_yesterday_hand_collision.py','.venv/bin/python scripts/verify_fix_interpolation.py --video --buffer','.venv/bin/python scripts/interpolate_collision_reference.py','.venv/bin/python scripts/verify_fix_interpolation.py --buffer','.venv/bin/python scripts/align_collision_floor.py','.venv/bin/python scripts/configure_collision_physics.py','SPIDER_TASK_OUT=$PWD/output/collision_fix_20260915 .spider/bin/python scripts/run_yesterday_spider.py','.venv/bin/python scripts/audit_collision_fix.py','.venv/bin/python scripts/audit_collision_physics.py','.venv/bin/python scripts/render_collision_fix.py','.venv/bin/python scripts/report_collision_fix.py','```','', '旧几何探索碎片在 `collision/` 中,仅供排查,不由新场景使用。']
(O/'README.md').write_text('\n'.join(lines)+'\n');print('REPORT_COMPLETE',n)