lfz_lehome_v2 / scripts /utils /common.py
taikonauts's picture
Upload folder using huggingface_hub
1cc903b verified
Raw
History Blame Contribute Delete
4.05 kB
import argparse
from typing import TYPE_CHECKING
import numpy as np
import torch
from isaaclab.app import AppLauncher
from isaacsim.simulation_app import SimulationApp
if TYPE_CHECKING:
from isaaclab.envs import DirectRLEnv
SINGLE_ARM_HOME_POSITION = np.array(
[
-1.0363, # shoulder_pan
-1.7135, # shoulder_lift
1.4979, # elbow_flex
1.0534, # wrist_flex
-0.085, # wrist_roll
-0.01176, # gripper
],
dtype=np.float32,
)
# Left arm uses standard home position
LEFT_ARM_HOME_POSITION = np.array(
[
-1.2363, # shoulder_pan
-1.7135, # shoulder_lift
1.4979, # elbow_flex
1.0534, # wrist_flex
-0.085, # wrist_roll
-0.01176, # gripper
],
dtype=np.float32,
)
# Right arm with symmetric shoulder_pan
RIGHT_ARM_HOME_POSITION = np.array(
[
1.2363, # shoulder_pan
-1.7135, # shoulder_lift
1.4979, # elbow_flex
1.0534, # wrist_flex
-0.085, # wrist_roll
-0.01176, # gripper
],
dtype=np.float32,
)
DUAL_ARM_HOME_POSITION = np.concatenate(
[LEFT_ARM_HOME_POSITION, RIGHT_ARM_HOME_POSITION]
)
def launch_app(parser: argparse.ArgumentParser) -> SimulationApp:
"""Launch Isaac Sim app from parser (parses args internally).
Use this when you haven't parsed arguments yet.
"""
AppLauncher.add_app_launcher_args(parser)
args = parser.parse_args()
return launch_app_from_args(args)
def launch_app_from_args(args: argparse.Namespace) -> SimulationApp:
"""Launch Isaac Sim app from already parsed arguments.
Use this when arguments are already parsed (e.g., in subcommand handlers).
Args:
args: Already parsed command-line arguments (must include AppLauncher args).
Returns:
SimulationApp instance.
"""
args.kit_args = (
"--/log/level=error --/log/fileLogLevel=error --/log/outputStreamLevel=error"
)
app_launcher = AppLauncher(vars(args))
simulation_app = app_launcher.app
return simulation_app
def close_app(simulation_app: SimulationApp) -> None:
"""Close Isaac Sim app."""
simulation_app.close()
def stabilize_garment_after_reset(
env: "DirectRLEnv",
args: argparse.Namespace,
num_steps: int = 20,
) -> None:
"""Stabilize garment after environment reset by running physics steps.
Moves robot to home position and lets garment settle naturally after reset,
preventing floating or clipping. This is critical for garment physics to
initialize properly, especially when using CUDA device.
Args:
env: Environment instance.
args: Command-line arguments containing task name.
num_steps: Number of stabilization steps to run.
"""
if num_steps <= 0:
return
is_bimanual = "Bi" in args.task or "bi" in args.task.lower()
try:
initial_obs = env._get_observations()
action_dim = (
len(initial_obs["observation.state"])
if "observation.state" in initial_obs
else (12 if is_bimanual else 6)
)
except Exception:
action_dim = 12 if is_bimanual else 6
home_joints = DUAL_ARM_HOME_POSITION if is_bimanual else SINGLE_ARM_HOME_POSITION
if len(home_joints) != action_dim:
# Use warning from logger if available, otherwise print
try:
from lehome.utils.logger import get_logger
logger = get_logger(__name__)
logger.warning(
f"Home position dimension mismatch: got {len(home_joints)}, "
f"expected {action_dim}. Using zeros."
)
except Exception:
pass
home_action = torch.zeros(1, action_dim, dtype=torch.float32, device=env.device)
else:
home_action = torch.from_numpy(home_joints).float().to(env.device).unsqueeze(0)
for step_idx in range(num_steps):
env.step(home_action)
if (step_idx + 1) % 10 == 0 or step_idx == num_steps - 1:
env.render()