|
11 | 11 | """Launch Isaac Sim Simulator first.""" |
12 | 12 |
|
13 | 13 | import argparse |
14 | | -import os |
15 | 14 | import sys |
16 | 15 |
|
17 | 16 | from isaaclab.app import AppLauncher |
18 | 17 |
|
19 | 18 | # local imports |
20 | 19 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) |
21 | | -import cli_args |
| 20 | +import cli_args # isort: skip |
22 | 21 | from rl_utils import camera_follow |
23 | 22 |
|
24 | 23 | # add argparse arguments |
|
62 | 61 | """Rest everything follows.""" |
63 | 62 |
|
64 | 63 | import gymnasium as gym |
| 64 | +import os |
65 | 65 | import time |
66 | 66 | import torch |
67 | 67 |
|
68 | | -from rsl_rl.runners import OnPolicyRunner |
| 68 | +from rsl_rl.runners import DistillationRunner, OnPolicyRunner |
69 | 69 |
|
70 | 70 | from isaaclab.devices import Se2Keyboard, Se2KeyboardCfg |
71 | 71 | from isaaclab.envs import ( |
|
80 | 80 | from isaaclab.utils.assets import retrieve_file_path |
81 | 81 | from isaaclab.utils.dict import print_dict |
82 | 82 | from isaaclab.utils.pretrained_checkpoint import get_published_pretrained_checkpoint |
83 | | -from isaaclab_rl.rsl_rl import RslRlOnPolicyRunnerCfg, RslRlVecEnvWrapper, export_policy_as_jit, export_policy_as_onnx |
| 83 | + |
| 84 | +from isaaclab_rl.rsl_rl import RslRlBaseRunnerCfg, RslRlVecEnvWrapper, export_policy_as_jit, export_policy_as_onnx |
| 85 | + |
84 | 86 | from isaaclab_tasks.utils import get_checkpoint_path |
85 | 87 | from isaaclab_tasks.utils.hydra import hydra_task_config |
86 | 88 |
|
87 | 89 | import robot_lab.tasks # noqa: F401 |
88 | 90 |
|
89 | 91 |
|
90 | 92 | @hydra_task_config(args_cli.task, args_cli.agent) |
91 | | -def main(env_cfg: ManagerBasedRLEnvCfg | DirectRLEnvCfg | DirectMARLEnvCfg, agent_cfg: RslRlOnPolicyRunnerCfg): |
| 93 | +def main(env_cfg: ManagerBasedRLEnvCfg | DirectRLEnvCfg | DirectMARLEnvCfg, agent_cfg: RslRlBaseRunnerCfg): |
92 | 94 | """Play with RSL-RL agent.""" |
| 95 | + # grab task name for checkpoint path |
93 | 96 | task_name = args_cli.task.split(":")[-1] |
| 97 | + |
94 | 98 | # override configurations with non-hydra CLI arguments |
95 | | - agent_cfg = cli_args.update_rsl_rl_cfg(agent_cfg, args_cli) |
96 | | - env_cfg.scene.num_envs = args_cli.num_envs if args_cli.num_envs is not None else env_cfg.scene.num_envs |
| 99 | + agent_cfg: RslRlBaseRunnerCfg = cli_args.update_rsl_rl_cfg(agent_cfg, args_cli) |
| 100 | + env_cfg.scene.num_envs = args_cli.num_envs if args_cli.num_envs is not None else 64 |
97 | 101 |
|
98 | 102 | # set the environment seed |
99 | 103 | # note: certain randomizations occur in the environment initialization so we set the seed here |
100 | 104 | env_cfg.seed = agent_cfg.seed |
101 | | - env_cfg.sim.device = args_cli.device if args_cli.device is not None else 50 |
| 105 | + env_cfg.sim.device = args_cli.device if args_cli.device is not None else env_cfg.sim.device |
102 | 106 |
|
103 | 107 | # cs map config |
104 | 108 | env_cfg.scene.terrain = TerrainImporterCfg( |
@@ -206,40 +210,43 @@ def main(env_cfg: ManagerBasedRLEnvCfg | DirectRLEnvCfg | DirectMARLEnvCfg, agen |
206 | 210 |
|
207 | 211 | print(f"[INFO]: Loading model checkpoint from: {resume_path}") |
208 | 212 | # load previously trained model |
209 | | - ppo_runner = OnPolicyRunner(env, agent_cfg.to_dict(), log_dir=None, device=agent_cfg.device) |
210 | | - ppo_runner.load(resume_path) |
| 213 | + if agent_cfg.class_name == "OnPolicyRunner": |
| 214 | + runner = OnPolicyRunner(env, agent_cfg.to_dict(), log_dir=None, device=agent_cfg.device) |
| 215 | + elif agent_cfg.class_name == "DistillationRunner": |
| 216 | + runner = DistillationRunner(env, agent_cfg.to_dict(), log_dir=None, device=agent_cfg.device) |
| 217 | + else: |
| 218 | + raise ValueError(f"Unsupported runner class: {agent_cfg.class_name}") |
| 219 | + runner.load(resume_path) |
211 | 220 |
|
212 | 221 | # obtain the trained policy for inference |
213 | | - policy = ppo_runner.get_inference_policy(device=env.unwrapped.device) |
| 222 | + policy = runner.get_inference_policy(device=env.unwrapped.device) |
214 | 223 |
|
215 | 224 | # extract the neural network module |
216 | 225 | # we do this in a try-except to maintain backwards compatibility. |
217 | 226 | try: |
218 | 227 | # version 2.3 onwards |
219 | | - policy_nn = ppo_runner.alg.policy |
| 228 | + policy_nn = runner.alg.policy |
220 | 229 | except AttributeError: |
221 | 230 | # version 2.2 and below |
222 | | - policy_nn = ppo_runner.alg.actor_critic |
| 231 | + policy_nn = runner.alg.actor_critic |
| 232 | + |
| 233 | + # extract the normalizer |
| 234 | + if hasattr(policy_nn, "actor_obs_normalizer"): |
| 235 | + normalizer = policy_nn.actor_obs_normalizer |
| 236 | + elif hasattr(policy_nn, "student_obs_normalizer"): |
| 237 | + normalizer = policy_nn.student_obs_normalizer |
| 238 | + else: |
| 239 | + normalizer = None |
223 | 240 |
|
224 | 241 | # export policy to onnx/jit |
225 | 242 | export_model_dir = os.path.join(os.path.dirname(resume_path), "exported") |
226 | | - export_policy_as_onnx( |
227 | | - policy=policy_nn, |
228 | | - normalizer=ppo_runner.obs_normalizer, |
229 | | - path=export_model_dir, |
230 | | - filename="policy.onnx", |
231 | | - ) |
232 | | - export_policy_as_jit( |
233 | | - policy=policy_nn, |
234 | | - normalizer=ppo_runner.obs_normalizer, |
235 | | - path=export_model_dir, |
236 | | - filename="policy.pt", |
237 | | - ) |
| 243 | + export_policy_as_jit(policy_nn, normalizer=normalizer, path=export_model_dir, filename="policy.pt") |
| 244 | + export_policy_as_onnx(policy_nn, normalizer=normalizer, path=export_model_dir, filename="policy.onnx") |
238 | 245 |
|
239 | 246 | dt = env.unwrapped.step_dt |
240 | 247 |
|
241 | 248 | # reset environment |
242 | | - obs, _ = env.get_observations() |
| 249 | + obs = env.get_observations() |
243 | 250 | timestep = 0 |
244 | 251 | # simulate environment |
245 | 252 | while simulation_app.is_running(): |
|
0 commit comments