| |
| |
| |
| |
|
|
| """ |
| Script to play a checkpoint of an RL agent from skrl. |
| |
| Visit the skrl documentation (https://skrl.readthedocs.io) to see the examples structured in |
| a more user-friendly way. |
| """ |
|
|
| """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 skrl.") |
| 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=None, |
| help=( |
| "Name of the RL agent configuration entry point. Defaults to None, in which case the argument " |
| "--algorithm is used to determine the default 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( |
| "--ml_framework", |
| type=str, |
| default="torch", |
| choices=["torch", "jax", "jax-numpy"], |
| help="The ML framework used for training the skrl agent.", |
| ) |
| parser.add_argument( |
| "--algorithm", |
| type=str, |
| default="PPO", |
| choices=["AMP", "PPO", "IPPO", "MAPPO"], |
| help="The RL algorithm used for training the skrl agent.", |
| ) |
| 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 os |
| import random |
| import time |
| import torch |
|
|
| import skrl |
| from packaging import version |
|
|
| |
| SKRL_VERSION = "1.4.3" |
| if version.parse(skrl.__version__) < version.parse(SKRL_VERSION): |
| skrl.logger.error( |
| f"Unsupported skrl version: {skrl.__version__}. " |
| f"Install supported version using 'pip install skrl>={SKRL_VERSION}'" |
| ) |
| exit() |
|
|
| if args_cli.ml_framework.startswith("torch"): |
| from skrl.utils.runner.torch import Runner |
| elif args_cli.ml_framework.startswith("jax"): |
| from skrl.utils.runner.jax import Runner |
|
|
| from isaaclab.envs import ( |
| DirectMARLEnv, |
| DirectMARLEnvCfg, |
| DirectRLEnvCfg, |
| ManagerBasedRLEnvCfg, |
| multi_agent_to_single_agent, |
| ) |
| from isaaclab.utils.dict import print_dict |
|
|
| from isaaclab_rl.skrl import SkrlVecEnvWrapper |
| 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 |
|
|
| |
|
|
| |
| if args_cli.agent is None: |
| algorithm = args_cli.algorithm.lower() |
| agent_cfg_entry_point = "skrl_cfg_entry_point" if algorithm in ["ppo"] else f"skrl_{algorithm}_cfg_entry_point" |
| else: |
| agent_cfg_entry_point = args_cli.agent |
| algorithm = agent_cfg_entry_point.split("_cfg")[0].split("skrl_")[-1].lower() |
|
|
|
|
| @hydra_task_config(args_cli.task, agent_cfg_entry_point) |
| def main(env_cfg: ManagerBasedRLEnvCfg | DirectRLEnvCfg | DirectMARLEnvCfg, experiment_cfg: dict): |
| """Play with skrl 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.ml_framework.startswith("jax"): |
| skrl.config.jax.backend = "jax" if args_cli.ml_framework == "jax" else "numpy" |
|
|
| |
| if args_cli.seed == -1: |
| args_cli.seed = random.randint(0, 10000) |
|
|
| |
| |
| experiment_cfg["seed"] = args_cli.seed if args_cli.seed is not None else experiment_cfg["seed"] |
| env_cfg.seed = experiment_cfg["seed"] |
|
|
| |
| log_root_path = os.path.join("logs", "skrl", experiment_cfg["agent"]["experiment"]["directory"]) |
| 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("skrl", 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: |
| resume_path = os.path.abspath(args_cli.checkpoint) |
| else: |
| resume_path = get_checkpoint_path( |
| log_root_path, run_dir=f".*_{algorithm}_{args_cli.ml_framework}", other_dirs=["checkpoints"] |
| ) |
| log_dir = os.path.dirname(os.path.dirname(resume_path)) |
|
|
| |
| env_cfg.log_dir = log_dir |
|
|
| |
| env = gym.make(args_cli.task, cfg=env_cfg, render_mode="rgb_array" if args_cli.video else None) |
|
|
| |
| if isinstance(env.unwrapped, DirectMARLEnv) and algorithm in ["ppo"]: |
| env = multi_agent_to_single_agent(env) |
|
|
| |
| try: |
| dt = env.step_dt |
| except AttributeError: |
| dt = env.unwrapped.step_dt |
|
|
| |
| if args_cli.video: |
| video_kwargs = { |
| "video_folder": os.path.join(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 = SkrlVecEnvWrapper(env, ml_framework=args_cli.ml_framework) |
|
|
| |
| |
| experiment_cfg["trainer"]["close_environment_at_exit"] = False |
| experiment_cfg["agent"]["experiment"]["write_interval"] = 0 |
| experiment_cfg["agent"]["experiment"]["checkpoint_interval"] = 0 |
| runner = Runner(env, experiment_cfg) |
|
|
| print(f"[INFO] Loading model checkpoint from: {resume_path}") |
| runner.agent.load(resume_path) |
| |
| runner.agent.set_running_mode("eval") |
|
|
| |
| obs, _ = env.reset() |
| timestep = 0 |
| |
| while simulation_app.is_running(): |
| start_time = time.time() |
|
|
| |
| with torch.inference_mode(): |
| |
| outputs = runner.agent.act(obs, timestep=0, timesteps=0) |
| |
| if hasattr(env, "possible_agents"): |
| actions = {a: outputs[-1][a].get("mean_actions", outputs[0][a]) for a in env.possible_agents} |
| |
| else: |
| actions = outputs[-1].get("mean_actions", outputs[0]) |
| |
| obs, _, _, _, _ = env.step(actions) |
| 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() |
|
|