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>
This commit is contained in:
+4
-1
@@ -118,7 +118,10 @@ def _assert_object_actuator_gains_zero(
|
||||
if biasprm.ndim == 3:
|
||||
biasprm = biasprm[0]
|
||||
kp = gainprm[actuator_ids, 0]
|
||||
kd = -biasprm[actuator_ids, 1]
|
||||
kd = -biasprm[actuator_ids, 2]
|
||||
assert np.allclose(biasprm[actuator_ids], 0.0, atol=atol), (
|
||||
f"Object actuator affine bias not zero at {stage}"
|
||||
)
|
||||
assert np.allclose(kp, 0.0, atol=atol), (
|
||||
f"Object actuator Kp not near zero at {stage}: max={np.max(np.abs(kp))}"
|
||||
)
|
||||
|
||||
+3
-1
@@ -172,7 +172,9 @@ def make_rollout_fn(
|
||||
copy_sample_state(config, env, good_indices, bad_indices)
|
||||
|
||||
# Replace bad samples control with good samples (for initial control and current timestep only)
|
||||
ctrls[bad_indices, :t] = ctrls[good_indices, :t]
|
||||
# State has already advanced through t; its causal prefix must
|
||||
# include this control too, otherwise replay is inconsistent.
|
||||
ctrls[bad_indices, : t + 1] = ctrls[good_indices, : t + 1]
|
||||
|
||||
# Replace bad samples cumulative reward with good samples reward
|
||||
cum_rew[bad_indices] = cum_rew[good_indices]
|
||||
|
||||
+16
-5
@@ -172,13 +172,14 @@ def setup_env(config: Config, ref_data: tuple[torch.Tensor, ...]) -> MJWPEnv:
|
||||
def _weight_diff_qpos(config: Config) -> torch.Tensor:
|
||||
w = torch.ones(config.nv, device=config.device)
|
||||
if config.embodiment_type == "bimanual":
|
||||
half_dof = int(config.nu // 2)
|
||||
# The state includes passive joints, unlike the actuator vector.
|
||||
half_dof = int((config.nv - 12) // 2)
|
||||
w[:3] = config.base_pos_rew_scale
|
||||
w[3:6] = config.base_rot_rew_scale
|
||||
w[6:half_dof] = config.joint_rew_scale
|
||||
w[half_dof : half_dof + 3] = config.base_pos_rew_scale
|
||||
w[half_dof + 3 : half_dof + 6] = config.base_rot_rew_scale
|
||||
w[half_dof + 6 : config.nu] = config.joint_rew_scale
|
||||
w[half_dof + 6 : -12] = config.joint_rew_scale
|
||||
# object: weights live in nv-space (6-dim per freejoint), regardless of nq_obj
|
||||
w[-12:-9] = config.pos_rew_scale
|
||||
w[-9:-6] = config.rot_rew_scale
|
||||
@@ -648,7 +649,7 @@ def get_reward(
|
||||
contact_pos = site_xpos_torch[:, config.contact_site_ids]
|
||||
contact_dist = torch.norm(contact_pos - contact_pos_ref, p=2, dim=-1)
|
||||
contact_dist_masked = contact_dist * contact_ref.unsqueeze(0)
|
||||
contact_rew = -contact_dist_masked.sum(dim=1)
|
||||
contact_rew = -config.contact_rew_scale * contact_dist_masked.sum(dim=1)
|
||||
else:
|
||||
contact_rew = 0.0
|
||||
|
||||
@@ -990,7 +991,12 @@ def save_env_params(config: Config, env: MJWPEnv):
|
||||
# convert it to torch would lead to OOM
|
||||
pair_margin = 0.0
|
||||
xy_offset = 0.0
|
||||
return {"pair_margin": pair_margin, "xy_offset": xy_offset}
|
||||
params = {"pair_margin": pair_margin, "xy_offset": xy_offset}
|
||||
if config.object_actuator_ids:
|
||||
ids = config.object_actuator_ids
|
||||
params["kp"] = env.model_cpu.actuator_gainprm[ids, 0].copy()
|
||||
params["kd"] = -env.model_cpu.actuator_biasprm[ids, 2].copy()
|
||||
return params
|
||||
|
||||
|
||||
def load_env_params(config: Config, env: MJWPEnv, env_param: dict):
|
||||
@@ -1071,7 +1077,9 @@ def load_env_params(config: Config, env: MJWPEnv, env_param: dict):
|
||||
|
||||
# Update CPU model (used for viewer and as source of truth)
|
||||
env.model_cpu.actuator_gainprm[actuator_ids, 0] = kp_np
|
||||
env.model_cpu.actuator_biasprm[actuator_ids, 1] = -kd_np
|
||||
# Affine servo force: kp * ctrl - kp * length - kd * velocity.
|
||||
env.model_cpu.actuator_biasprm[actuator_ids, 1] = -kp_np
|
||||
env.model_cpu.actuator_biasprm[actuator_ids, 2] = -kd_np
|
||||
|
||||
# Propagate to MJWarp model if available
|
||||
if hasattr(env.model_wp, "actuator_gainprm") and hasattr(
|
||||
@@ -1132,6 +1140,9 @@ def _broadcast_state(data_wp, num_worlds: int):
|
||||
# Additional core state variables
|
||||
qacc0 = wp.to_torch(data_wp.qacc)[:1]
|
||||
wp.copy(data_wp.qacc, wp.from_torch(qacc0.repeat(num_worlds, 1)))
|
||||
# A new MPC batch must not inherit warmstarts from failed candidate worlds.
|
||||
warmstart0 = wp.to_torch(data_wp.qacc_warmstart)[:1]
|
||||
wp.copy(data_wp.qacc_warmstart, wp.from_torch(warmstart0.repeat(num_worlds, 1)))
|
||||
|
||||
act0 = wp.to_torch(data_wp.act)[:1]
|
||||
wp.copy(data_wp.act, wp.from_torch(act0.repeat(num_worlds, 1)))
|
||||
|
||||
Reference in New Issue
Block a user