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>
13 lines
7.4 KiB
Python
13 lines
7.4 KiB
Python
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} rad,mimic 最大残差 {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)
|