mirror of
https://github.com/huggingface/lerobot.git
synced 2026-05-18 02:00:03 +00:00
more changes:
This commit is contained in:
Binary file not shown.
@@ -6,4 +6,3 @@ lerobot-eval \
|
|||||||
--eval.batch_size=1 \
|
--eval.batch_size=1 \
|
||||||
--eval.n_episodes=1 \
|
--eval.n_episodes=1 \
|
||||||
--seed=142
|
--seed=142
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -19,13 +19,13 @@ from typing import Any
|
|||||||
import gymnasium as gym
|
import gymnasium as gym
|
||||||
from gymnasium.envs.registration import registry as gym_registry
|
from gymnasium.envs.registration import registry as gym_registry
|
||||||
|
|
||||||
|
from lerobot.configs.policies import PreTrainedConfig
|
||||||
from lerobot.envs.configs import AlohaEnv, EnvConfig, LiberoEnv, PushtEnv
|
from lerobot.envs.configs import AlohaEnv, EnvConfig, LiberoEnv, PushtEnv
|
||||||
from lerobot.envs.utils import _call_make_env, _download_hub_file, _import_hub_module, _normalize_hub_result
|
from lerobot.envs.utils import _call_make_env, _download_hub_file, _import_hub_module, _normalize_hub_result
|
||||||
|
from lerobot.policies.xvla.configuration_xvla import XVLAConfig
|
||||||
from lerobot.processor import ProcessorStep
|
from lerobot.processor import ProcessorStep
|
||||||
from lerobot.processor.env_processor import LiberoProcessorStep
|
from lerobot.processor.env_processor import LiberoProcessorStep
|
||||||
from lerobot.processor.pipeline import PolicyProcessorPipeline
|
from lerobot.processor.pipeline import PolicyProcessorPipeline
|
||||||
from lerobot.policies.xvla.configuration_xvla import XVLAConfig
|
|
||||||
from lerobot.configs.policies import PreTrainedConfig
|
|
||||||
|
|
||||||
|
|
||||||
def make_env_config(env_type: str, **kwargs) -> EnvConfig:
|
def make_env_config(env_type: str, **kwargs) -> EnvConfig:
|
||||||
@@ -66,12 +66,12 @@ def make_env_pre_post_processors(
|
|||||||
postprocessor_steps: list[ProcessorStep] = []
|
postprocessor_steps: list[ProcessorStep] = []
|
||||||
if isinstance(policy_cfg, XVLAConfig):
|
if isinstance(policy_cfg, XVLAConfig):
|
||||||
from lerobot.policies.xvla.processor_xvla import make_xvla_libero_pre_post_processors
|
from lerobot.policies.xvla.processor_xvla import make_xvla_libero_pre_post_processors
|
||||||
|
|
||||||
return make_xvla_libero_pre_post_processors()
|
return make_xvla_libero_pre_post_processors()
|
||||||
|
|
||||||
# For LIBERO environments, add the LiberoProcessorStep to preprocessor
|
# For LIBERO environments, add the LiberoProcessorStep to preprocessor
|
||||||
if isinstance(env_cfg, LiberoEnv) or "libero" in env_cfg.type:
|
if isinstance(env_cfg, LiberoEnv) or "libero" in env_cfg.type:
|
||||||
preprocessor_steps.append(LiberoProcessorStep())
|
preprocessor_steps.append(LiberoProcessorStep())
|
||||||
|
|
||||||
|
|
||||||
preprocessor = PolicyProcessorPipeline(steps=preprocessor_steps)
|
preprocessor = PolicyProcessorPipeline(steps=preprocessor_steps)
|
||||||
postprocessor = PolicyProcessorPipeline(steps=postprocessor_steps)
|
postprocessor = PolicyProcessorPipeline(steps=postprocessor_steps)
|
||||||
|
|||||||
@@ -240,11 +240,11 @@ class LiberoEnv(gym.Env):
|
|||||||
image = raw_obs[camera_name]
|
image = raw_obs[camera_name]
|
||||||
images[self.camera_name_mapping[camera_name]] = image
|
images[self.camera_name_mapping[camera_name]] = image
|
||||||
|
|
||||||
eef_pos = self._env.robots[0].controller.ee_pos #raw_obs.get("robot0_eef_pos")
|
eef_pos = raw_obs.get("robot0_eef_pos")
|
||||||
eef_quat = raw_obs.get("robot0_eef_quat")
|
eef_quat = raw_obs.get("robot0_eef_quat")
|
||||||
|
|
||||||
# rotation matrix from controller
|
# rotation matrix from controller
|
||||||
eef_mat = self._env.robots[0].controller.ee_ori_mat
|
eef_mat = self._env.robots[0].controller.ee_ori_mat if eef_pos is not None else None
|
||||||
gripper_qpos = raw_obs.get("robot0_gripper_qpos")
|
gripper_qpos = raw_obs.get("robot0_gripper_qpos")
|
||||||
gripper_qvel = raw_obs.get("robot0_gripper_qvel")
|
gripper_qvel = raw_obs.get("robot0_gripper_qvel")
|
||||||
joint_pos = raw_obs.get("robot0_joint_pos")
|
joint_pos = raw_obs.get("robot0_joint_pos")
|
||||||
@@ -297,7 +297,7 @@ class LiberoEnv(gym.Env):
|
|||||||
# Increasing this value can improve determinism and reproducibility across resets.
|
# Increasing this value can improve determinism and reproducibility across resets.
|
||||||
for _ in range(self.num_steps_wait):
|
for _ in range(self.num_steps_wait):
|
||||||
raw_obs, _, _, _ = self._env.step(get_libero_dummy_action())
|
raw_obs, _, _, _ = self._env.step(get_libero_dummy_action())
|
||||||
|
|
||||||
if self.control_mode == "absolute":
|
if self.control_mode == "absolute":
|
||||||
for robot in self._env.robots:
|
for robot in self._env.robots:
|
||||||
robot.controller.use_delta = False
|
robot.controller.use_delta = False
|
||||||
@@ -422,7 +422,6 @@ def create_libero_envs(
|
|||||||
suite = _get_suite(suite_name)
|
suite = _get_suite(suite_name)
|
||||||
total = len(suite.tasks)
|
total = len(suite.tasks)
|
||||||
selected = _select_task_ids(total, task_ids_filter)
|
selected = _select_task_ids(total, task_ids_filter)
|
||||||
selected = [0]
|
|
||||||
if not selected:
|
if not selected:
|
||||||
raise ValueError(f"No tasks selected for suite '{suite_name}' (available: {total}).")
|
raise ValueError(f"No tasks selected for suite '{suite_name}' (available: {total}).")
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,2 @@
|
|||||||
from lerobot.policies.xvla.processor_xvla import (
|
# add domainid
|
||||||
XVLAAddDomainIdProcessorStep,
|
from lerobot.policies.xvla.processor_xvla import XVLAAddDomainIdProcessorStep
|
||||||
XVLAImageScaleProcessorStep,
|
|
||||||
XVLARotation6DToAxisAngleProcessorStep,
|
|
||||||
make_xvla_pre_post_processors,
|
|
||||||
)
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
import numpy as np
|
|
||||||
import os
|
|
||||||
|
|
||||||
# --- CHANGE THESE TWO PATHS ---
|
|
||||||
dir_a = "/home/jade_choghari/robot/lerobot"
|
|
||||||
dir_b = "/home/jade_choghari/robot/robot2/lerobot"
|
|
||||||
|
|
||||||
# keys = ["input_ids", "image_input", "image_mask", "domain_id", "proprio"]
|
|
||||||
keys = ["domain_id"]
|
|
||||||
|
|
||||||
def load_np(path, key):
|
|
||||||
file_path = os.path.join(path, f"{key}.npy")
|
|
||||||
if not os.path.exists(file_path):
|
|
||||||
raise FileNotFoundError(f"Missing file: {file_path}")
|
|
||||||
return np.load(file_path)
|
|
||||||
|
|
||||||
for k in keys:
|
|
||||||
print(f"\n===== {k} =====")
|
|
||||||
a = load_np(dir_a, k)
|
|
||||||
b = load_np(dir_b, k)
|
|
||||||
print(a)
|
|
||||||
print(b)
|
|
||||||
print("Shapes:", a.shape, b.shape)
|
|
||||||
same_shape = a.shape == b.shape
|
|
||||||
print("Same shape:", same_shape)
|
|
||||||
|
|
||||||
if not same_shape:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Allclose for numeric, array_equal for boolean
|
|
||||||
if a.dtype == bool or b.dtype == bool:
|
|
||||||
equal = np.array_equal(a, b)
|
|
||||||
print("Equal:", equal)
|
|
||||||
|
|
||||||
# For boolean arrays, diff = xor
|
|
||||||
diff = np.sum(a ^ b)
|
|
||||||
print("Num differing elements:", diff)
|
|
||||||
else:
|
|
||||||
close = np.allclose(a, b, atol=1e-6, rtol=1e-6)
|
|
||||||
print("Allclose:", close)
|
|
||||||
|
|
||||||
diff = np.max(np.abs(a - b))
|
|
||||||
print("Max difference:", diff)
|
|
||||||
@@ -20,15 +20,16 @@ from typing import Any
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
import torch
|
import torch
|
||||||
|
|
||||||
|
from lerobot.configs.types import PipelineFeatureType, PolicyFeature
|
||||||
from lerobot.policies.xvla.configuration_xvla import XVLAConfig
|
from lerobot.policies.xvla.configuration_xvla import XVLAConfig
|
||||||
from lerobot.policies.xvla.utils import rotate6d_to_axis_angle
|
from lerobot.policies.xvla.utils import rotate6d_to_axis_angle
|
||||||
from lerobot.processor import (
|
from lerobot.processor import (
|
||||||
AddBatchDimensionProcessorStep,
|
AddBatchDimensionProcessorStep,
|
||||||
DeviceProcessorStep,
|
DeviceProcessorStep,
|
||||||
NormalizerProcessorStep,
|
NormalizerProcessorStep,
|
||||||
|
ObservationProcessorStep,
|
||||||
PolicyAction,
|
PolicyAction,
|
||||||
PolicyProcessorPipeline,
|
PolicyProcessorPipeline,
|
||||||
ObservationProcessorStep,
|
|
||||||
ProcessorStep,
|
ProcessorStep,
|
||||||
ProcessorStepRegistry,
|
ProcessorStepRegistry,
|
||||||
RenameObservationsProcessorStep,
|
RenameObservationsProcessorStep,
|
||||||
@@ -37,8 +38,13 @@ from lerobot.processor import (
|
|||||||
)
|
)
|
||||||
from lerobot.processor.converters import policy_action_to_transition, transition_to_policy_action
|
from lerobot.processor.converters import policy_action_to_transition, transition_to_policy_action
|
||||||
from lerobot.processor.core import EnvTransition, TransitionKey
|
from lerobot.processor.core import EnvTransition, TransitionKey
|
||||||
from lerobot.utils.constants import POLICY_POSTPROCESSOR_DEFAULT_NAME, POLICY_PREPROCESSOR_DEFAULT_NAME, OBS_STATE, OBS_IMAGES
|
from lerobot.utils.constants import (
|
||||||
from lerobot.configs.types import PipelineFeatureType, PolicyFeature
|
OBS_IMAGES,
|
||||||
|
OBS_STATE,
|
||||||
|
POLICY_POSTPROCESSOR_DEFAULT_NAME,
|
||||||
|
POLICY_PREPROCESSOR_DEFAULT_NAME,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def make_xvla_pre_post_processors(
|
def make_xvla_pre_post_processors(
|
||||||
config: XVLAConfig,
|
config: XVLAConfig,
|
||||||
@@ -138,8 +144,8 @@ class LiberoProcessorStep(ObservationProcessorStep):
|
|||||||
|
|
||||||
extra = torch.zeros((eef_pos.shape[0], 1), dtype=torch.float32, device=eef_pos.device)
|
extra = torch.zeros((eef_pos.shape[0], 1), dtype=torch.float32, device=eef_pos.device)
|
||||||
|
|
||||||
proprio_state = torch.cat((eef_pos, eef_rot6d, extra), dim=-1) # (B, 10)
|
proprio_state = torch.cat((eef_pos, eef_rot6d, extra), dim=-1) # (B, 10)
|
||||||
state = torch.cat((proprio_state, torch.zeros_like(proprio_state)), dim=-1) # (B, 20)
|
state = torch.cat((proprio_state, torch.zeros_like(proprio_state)), dim=-1) # (B, 20)
|
||||||
# ensure float32
|
# ensure float32
|
||||||
state = state.float()
|
state = state.float()
|
||||||
if state.dim() == 1:
|
if state.dim() == 1:
|
||||||
@@ -178,7 +184,7 @@ class LiberoProcessorStep(ObservationProcessorStep):
|
|||||||
def _mat_to_rotate6d(self, rot_mats: torch.Tensor) -> torch.Tensor:
|
def _mat_to_rotate6d(self, rot_mats: torch.Tensor) -> torch.Tensor:
|
||||||
"""
|
"""
|
||||||
Convert batched rotation matrices (B, 3, 3) into 6D rotation representation (B, 6).
|
Convert batched rotation matrices (B, 3, 3) into 6D rotation representation (B, 6).
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
rot_mats (Tensor): Rotation matrices of shape (B, 3, 3)
|
rot_mats (Tensor): Rotation matrices of shape (B, 3, 3)
|
||||||
|
|
||||||
@@ -191,21 +197,17 @@ class LiberoProcessorStep(ObservationProcessorStep):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
if not isinstance(rot_mats, torch.Tensor):
|
if not isinstance(rot_mats, torch.Tensor):
|
||||||
raise TypeError(
|
raise TypeError(f"mat_to_rot6d expects a torch.Tensor, got {type(rot_mats)}")
|
||||||
f"mat_to_rot6d expects a torch.Tensor, got {type(rot_mats)}"
|
|
||||||
)
|
|
||||||
|
|
||||||
if rot_mats.ndim != 3 or rot_mats.shape[1:] != (3, 3):
|
if rot_mats.ndim != 3 or rot_mats.shape[1:] != (3, 3):
|
||||||
raise ValueError(
|
raise ValueError(f"mat_to_rot6d expects shape (B, 3, 3), got {tuple(rot_mats.shape)}")
|
||||||
f"mat_to_rot6d expects shape (B, 3, 3), got {tuple(rot_mats.shape)}"
|
|
||||||
)
|
|
||||||
|
|
||||||
rot_mats = rot_mats.to(torch.float32)
|
rot_mats = rot_mats.to(torch.float32)
|
||||||
|
|
||||||
col1 = rot_mats[:, :3, 0] # (B, 3)
|
col1 = rot_mats[:, :3, 0] # (B, 3)
|
||||||
col2 = rot_mats[:, :3, 1] # (B, 3)
|
col2 = rot_mats[:, :3, 1] # (B, 3)
|
||||||
|
|
||||||
rot6d = torch.cat([col1, col2], dim=-1) # (B, 6)
|
rot6d = torch.cat([col1, col2], dim=-1) # (B, 6)
|
||||||
|
|
||||||
return rot6d
|
return rot6d
|
||||||
|
|
||||||
@@ -213,7 +215,6 @@ class LiberoProcessorStep(ObservationProcessorStep):
|
|||||||
return self._process_observation(observation)
|
return self._process_observation(observation)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@ProcessorStepRegistry.register(name="xvla_image_scale")
|
@ProcessorStepRegistry.register(name="xvla_image_scale")
|
||||||
class XVLAImageScaleProcessorStep(ProcessorStep):
|
class XVLAImageScaleProcessorStep(ProcessorStep):
|
||||||
@@ -294,7 +295,7 @@ class XVLAAddDomainIdProcessorStep(ProcessorStep):
|
|||||||
if isinstance(v, torch.Tensor):
|
if isinstance(v, torch.Tensor):
|
||||||
batch_size = v.shape[0]
|
batch_size = v.shape[0]
|
||||||
break
|
break
|
||||||
|
|
||||||
# Add domain_id tensor
|
# Add domain_id tensor
|
||||||
comp["domain_id"] = torch.tensor([int(self.domain_id)] * batch_size, dtype=torch.long).to(self.device)
|
comp["domain_id"] = torch.tensor([int(self.domain_id)] * batch_size, dtype=torch.long).to(self.device)
|
||||||
|
|
||||||
@@ -378,8 +379,8 @@ class XVLARotation6DToAxisAngleProcessorStep(ProcessorStep):
|
|||||||
"expected_action_dim": self.expected_action_dim,
|
"expected_action_dim": self.expected_action_dim,
|
||||||
}
|
}
|
||||||
|
|
||||||
def make_xvla_libero_pre_post_processors(
|
|
||||||
) -> tuple[
|
def make_xvla_libero_pre_post_processors() -> tuple[
|
||||||
PolicyProcessorPipeline[dict[str, Any], dict[str, Any]],
|
PolicyProcessorPipeline[dict[str, Any], dict[str, Any]],
|
||||||
PolicyProcessorPipeline[PolicyAction, PolicyAction],
|
PolicyProcessorPipeline[PolicyAction, PolicyAction],
|
||||||
]:
|
]:
|
||||||
@@ -398,3 +399,7 @@ def make_xvla_libero_pre_post_processors(
|
|||||||
steps=post_processor_steps,
|
steps=post_processor_steps,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"XVLAAddDomainIdProcessorStep",
|
||||||
|
]
|
||||||
Reference in New Issue
Block a user