| |
| |
| |
| |
|
|
| """Script to play a checkpoint if an RL agent from RL-Games.""" |
|
|
| """Launch Isaac Sim Simulator first.""" |
|
|
| import argparse |
| import sys |
|
|
| from isaaclab.app import AppLauncher |
|
|
| |
| parser = argparse.ArgumentParser(description="Play a checkpoint of an RL agent from RL-Games.") |
| parser.add_argument("--video", action="store_true", default=False, help="Record videos during training.") |
| parser.add_argument("--video_length", type=int, default=200, help="Length of the recorded video (in steps).") |
| parser.add_argument( |
| "--disable_fabric", action="store_true", default=False, help="Disable fabric and use USD I/O operations." |
| ) |
| parser.add_argument("--num_envs", type=int, default=None, help="Number of environments to simulate.") |
| parser.add_argument("--task", type=str, default=None, help="Name of the task.") |
| parser.add_argument( |
| "--agent", type=str, default="rl_games_cfg_entry_point", help="Name of the RL agent configuration entry point." |
| ) |
| parser.add_argument("--checkpoint", type=str, default=None, help="Path to model checkpoint.") |
| parser.add_argument("--seed", type=int, default=None, help="Seed used for the environment") |
| parser.add_argument( |
| "--use_pretrained_checkpoint", |
| action="store_true", |
| help="Use the pre-trained checkpoint from Nucleus.", |
| ) |
| parser.add_argument( |
| "--use_last_checkpoint", |
| action="store_true", |
| help="When no checkpoint provided, use the last saved model. Otherwise use the best saved model.", |
| ) |
| parser.add_argument("--real-time", action="store_true", default=False, help="Run in real-time, if possible.") |
| |
| AppLauncher.add_app_launcher_args(parser) |
| |
| args_cli, hydra_args = parser.parse_known_args() |
| |
| if args_cli.video: |
| args_cli.enable_cameras = True |
|
|
| |
| sys.argv = [sys.argv[0]] + hydra_args |
| |
| app_launcher = AppLauncher(args_cli) |
| simulation_app = app_launcher.app |
|
|
| """Rest everything follows.""" |
|
|
|
|
| import gymnasium as gym |
| import math |
| import os |
| import random |
| import time |
| import torch |
|
|
| from rl_games.common import env_configurations, vecenv |
| from rl_games.common.player import BasePlayer |
| from rl_games.torch_runner import Runner |
|
|
| from isaaclab.envs import ( |
| DirectMARLEnv, |
| DirectMARLEnvCfg, |
| DirectRLEnvCfg, |
| ManagerBasedRLEnvCfg, |
| multi_agent_to_single_agent, |
| ) |
| from isaaclab.utils.assets import retrieve_file_path |
| from isaaclab.utils.dict import print_dict |
|
|
| from isaaclab_rl.rl_games import RlGamesGpuEnv, RlGamesVecEnvWrapper |
| from isaaclab_rl.utils.pretrained_checkpoint import get_published_pretrained_checkpoint |
|
|
| import isaaclab_tasks |
| import uwlab_tasks |
| from isaaclab_tasks.utils import get_checkpoint_path |
| from uwlab_tasks.utils.hydra import hydra_task_config |
|
|
| |
|
|
|
|
| @hydra_task_config(args_cli.task, args_cli.agent) |
| def main(env_cfg: ManagerBasedRLEnvCfg | DirectRLEnvCfg | DirectMARLEnvCfg, agent_cfg: dict): |
| """Play with RL-Games agent.""" |
| |
| task_name = args_cli.task.split(":")[-1] |
| train_task_name = task_name.replace("-Play", "") |
|
|
| |
| env_cfg.scene.num_envs = args_cli.num_envs if args_cli.num_envs is not None else env_cfg.scene.num_envs |
| env_cfg.sim.device = args_cli.device if args_cli.device is not None else env_cfg.sim.device |
| |
| if args_cli.device is not None: |
| agent_cfg["params"]["config"]["device"] = args_cli.device |
| agent_cfg["params"]["config"]["device_name"] = args_cli.device |
|
|
| |
| if args_cli.seed == -1: |
| args_cli.seed = random.randint(0, 10000) |
|
|
| agent_cfg["params"]["seed"] = args_cli.seed if args_cli.seed is not None else agent_cfg["params"]["seed"] |
| |
| |
| env_cfg.seed = agent_cfg["params"]["seed"] |
|
|
| |
| log_root_path = os.path.join("logs", "rl_games", agent_cfg["params"]["config"]["name"]) |
| log_root_path = os.path.abspath(log_root_path) |
| print(f"[INFO] Loading experiment from directory: {log_root_path}") |
| |
| if args_cli.use_pretrained_checkpoint: |
| resume_path = get_published_pretrained_checkpoint("rl_games", train_task_name) |
| if not resume_path: |
| print("[INFO] Unfortunately a pre-trained checkpoint is currently unavailable for this task.") |
| return |
| elif args_cli.checkpoint is None: |
| |
| run_dir = agent_cfg["params"]["config"].get("full_experiment_name", ".*") |
| |
| if args_cli.use_last_checkpoint: |
| checkpoint_file = ".*" |
| else: |
| |
| checkpoint_file = f"{agent_cfg['params']['config']['name']}.pth" |
| |
| resume_path = get_checkpoint_path(log_root_path, run_dir, checkpoint_file, other_dirs=["nn"]) |
| else: |
| resume_path = retrieve_file_path(args_cli.checkpoint) |
| log_dir = os.path.dirname(os.path.dirname(resume_path)) |
|
|
| |
| env_cfg.log_dir = log_dir |
|
|
| |
| rl_device = agent_cfg["params"]["config"]["device"] |
| clip_obs = agent_cfg["params"]["env"].get("clip_observations", math.inf) |
| clip_actions = agent_cfg["params"]["env"].get("clip_actions", math.inf) |
| obs_groups = agent_cfg["params"]["env"].get("obs_groups") |
| concate_obs_groups = agent_cfg["params"]["env"].get("concate_obs_groups", True) |
|
|
| |
| env = gym.make(args_cli.task, cfg=env_cfg, render_mode="rgb_array" if args_cli.video else None) |
|
|
| |
| if isinstance(env.unwrapped, DirectMARLEnv): |
| env = multi_agent_to_single_agent(env) |
|
|
| |
| if args_cli.video: |
| video_kwargs = { |
| "video_folder": os.path.join(log_root_path, log_dir, "videos", "play"), |
| "step_trigger": lambda step: step == 0, |
| "video_length": args_cli.video_length, |
| "disable_logger": True, |
| } |
| print("[INFO] Recording videos during training.") |
| print_dict(video_kwargs, nesting=4) |
| env = gym.wrappers.RecordVideo(env, **video_kwargs) |
|
|
| |
| env = RlGamesVecEnvWrapper(env, rl_device, clip_obs, clip_actions, obs_groups, concate_obs_groups) |
|
|
| |
| |
| vecenv.register( |
| "IsaacRlgWrapper", lambda config_name, num_actors, **kwargs: RlGamesGpuEnv(config_name, num_actors, **kwargs) |
| ) |
| env_configurations.register("rlgpu", {"vecenv_type": "IsaacRlgWrapper", "env_creator": lambda **kwargs: env}) |
|
|
| |
| agent_cfg["params"]["load_checkpoint"] = True |
| agent_cfg["params"]["load_path"] = resume_path |
| print(f"[INFO]: Loading model checkpoint from: {agent_cfg['params']['load_path']}") |
|
|
| |
| agent_cfg["params"]["config"]["num_actors"] = env.unwrapped.num_envs |
| |
| runner = Runner() |
| runner.load(agent_cfg) |
| |
| agent: BasePlayer = runner.create_player() |
| agent.restore(resume_path) |
| agent.reset() |
|
|
| dt = env.unwrapped.step_dt |
|
|
| |
| obs = env.reset() |
| if isinstance(obs, dict): |
| obs = obs["obs"] |
| timestep = 0 |
| |
| _ = agent.get_batch_size(obs, 1) |
| |
| if agent.is_rnn: |
| agent.init_rnn() |
| |
| |
| |
| |
| while simulation_app.is_running(): |
| start_time = time.time() |
| |
| with torch.inference_mode(): |
| |
| obs = agent.obs_to_torch(obs) |
| |
| actions = agent.get_action(obs, is_deterministic=agent.is_deterministic) |
| |
| obs, _, dones, _ = env.step(actions) |
|
|
| |
| if len(dones) > 0: |
| |
| if agent.is_rnn and agent.states is not None: |
| for s in agent.states: |
| s[:, dones, :] = 0.0 |
| if args_cli.video: |
| timestep += 1 |
| |
| if timestep == args_cli.video_length: |
| break |
|
|
| |
| sleep_time = dt - (time.time() - start_time) |
| if args_cli.real_time and sleep_time > 0: |
| time.sleep(sleep_time) |
|
|
| |
| env.close() |
|
|
|
|
| if __name__ == "__main__": |
| |
| main() |
| |
| simulation_app.close() |
|
|