Add Wall-X serving and Turtle2 TCP WebSocket bridge
Pre-commit / pre-commit (push) Canceled after 0s

This commit is contained in:
2026-09-23 21:04:17 +08:00
parent 6764e8f12f
commit d1cc7d96ad
40 changed files with 8591 additions and 40 deletions
+30 -5
View File
@@ -1,8 +1,10 @@
"""Build action/proprio normalizers and resolve the effective norm key.
Public inference artifacts must carry their own normalization data. This module
uses checkpoint-local ``norm_stats.json`` first, then checkpoint-side normalizer
state dicts, and finally an explicit ``customized_action_statistic_dof`` path.
uses checkpoint-local ``norm_stats.json`` for the 7D Euler layout, and uses
checkpoint-side normalizer state dicts for checkpoints whose train config contains
6D rotation fields. It finally supports an explicit
``customized_action_statistic_dof`` path.
It does not fall back to internal default action statistics.
"""
@@ -59,6 +61,19 @@ def _missing_normalizer_error(checkpoint_path: str, train_config: dict) -> FileN
)
def _uses_rotation_6d(train_config: dict) -> bool:
"""Return whether the checkpoint was trained with 6D rotation fields."""
for layout_name in ("dof_config", "agent_pos_config", "ar_dof_config"):
layout = train_config.get(layout_name)
if layout is None and isinstance(train_config.get("task"), dict):
layout = train_config["task"].get(layout_name)
if isinstance(layout, dict) and any(
"rotation_6d" in str(key).lower() for key in layout
):
return True
return False
def build_normalizers(
checkpoint_path: str,
train_config: dict,
@@ -66,14 +81,24 @@ def build_normalizers(
) -> tuple[Normalizer, Normalizer, str]:
"""Return action/proprio normalizers and the resolved norm key."""
norm_stats_path = os.path.join(checkpoint_path, "norm_stats.json")
if os.path.exists(norm_stats_path):
action_pth = os.path.join(checkpoint_path, "normalizer_action.pth")
propri_pth = os.path.join(checkpoint_path, "normalizer_propri.pth")
prefer_checkpoint_pth = (
os.path.exists(action_pth)
and os.path.exists(propri_pth)
and _uses_rotation_6d(train_config)
)
if os.path.exists(norm_stats_path) and not prefer_checkpoint_pth:
propri_stats = _load_norm_stats(norm_stats_path, "observation.state")
action_stats = _load_norm_stats(norm_stats_path, "action")
normalizer_propri = Normalizer.from_lerobot_norm_stats(propri_stats, norm_key)
normalizer_action = Normalizer.from_lerobot_norm_stats(action_stats, norm_key)
else:
action_pth = os.path.join(checkpoint_path, "normalizer_action.pth")
propri_pth = os.path.join(checkpoint_path, "normalizer_propri.pth")
if prefer_checkpoint_pth:
logger.info(
"Using checkpoint normalizer .pth files because train config "
"contains rotation_6D; ignoring 7D norm_stats.json"
)
custom_stats = _load_custom_action_stats(train_config)
if custom_stats is None and (not os.path.exists(action_pth) or not os.path.exists(propri_pth)):
raise _missing_normalizer_error(checkpoint_path, train_config)