Description
Describe the bug
I recently upgraded to Isaac sim v4.2.0 and lab v1.2 from v4.0.0 and v1.0, I updated my rsl_rl train.py script to match the example provided in the workflows/rsl_rl directory.
I get multiple errors when running the train.py with --headless tag. They seem to be caused by the URDF importer when running headless:
the program seems to run without any issues when --headless is not used.
Testing:
- Running the updated play.py script also does not produce the error either, running it with --headless produces the error.
- Running the train.py script headless using a robot with a usd file instead of urdf does not produce the issue either.
so I concluded that is probably some weird interaction when running the urdf importer while headless. The program does not crash after the error is printed, the training process starts working as expected.
Another error that happens when using URDF + headless is this:
Which seems to happen because of double init of gpu driver cache manager. It seems to be related to the first error since I couldn't reproduce it on its own, but I am not sure how they are related.
I have attached the full terminal log as a .txt file.
Steps to reproduce
I am not exactly sure what is causing the error so I don't know how to reproduce it other than running the rsl_rl training headless using a robot from a urdf file. This is my train.py file
# Copyright (c) 2022-2024, The Isaac Lab Project Developers.
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
"""Script to train RL agent with RSL-RL."""
"""Launch Isaac Sim Simulator first."""
import argparse
import sys
from omni.isaac.lab.app import AppLauncher
# local imports
from cts_rl.utils import cli_args # isort: skip
# add argparse arguments
parser = argparse.ArgumentParser(description="Train an RL agent with RSL-RL.")
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("--video_interval", type=int, default=2000, help="Interval between video recordings (in steps).")
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("--seed", type=int, default=None, help="Seed used for the environment")
parser.add_argument("--max_iterations", type=int, default=None, help="RL Policy training iterations.")
# append RSL-RL cli arguments
cli_args.add_rsl_rl_args(parser)
# append AppLauncher cli args
AppLauncher.add_app_launcher_args(parser)
args_cli, hydra_args = parser.parse_known_args()
# always enable cameras to record video
if args_cli.video:
args_cli.enable_cameras = True
# clear out sys.argv for Hydra
sys.argv = [sys.argv[0]] + hydra_args
# launch omniverse app
app_launcher = AppLauncher(args_cli)
simulation_app = app_launcher.app
"""Rest everything follows."""
import gymnasium as gym # isort: skip
import os
import torch
from rsl_rl.runners import CTSOnPolicyRunner
from omni.isaac.lab.envs import (
DirectMARLEnv,
DirectMARLEnvCfg,
DirectRLEnvCfg,
ManagerBasedRLEnvCfg,
multi_agent_to_single_agent,
)
from omni.isaac.lab.utils.dict import print_dict
from omni.isaac.lab.utils.io import dump_pickle, dump_yaml
import omni.isaac.lab_tasks # noqa
from omni.isaac.lab_tasks.utils import get_checkpoint_path
from omni.isaac.lab_tasks.utils.hydra import hydra_task_config
from omni.isaac.lab_tasks.utils.wrappers.rsl_rl import RslRlOnPolicyRunnerCfg, RslRlVecEnvWrapper
from cts_rl.config import * #noqa
torch.backends.cuda.matmul.allow_tf32 = True
torch.backends.cudnn.allow_tf32 = True
torch.backends.cudnn.deterministic = False
torch.backends.cudnn.benchmark = False
@hydra_task_config(args_cli.task, "rsl_rl_cfg_entry_point")
def main(env_cfg: ManagerBasedRLEnvCfg | DirectRLEnvCfg | DirectMARLEnvCfg, agent_cfg: RslRlOnPolicyRunnerCfg):
"""Train with RSL-RL agent."""
# parse configuration
agent_cfg = cli_args.update_rsl_rl_cfg(agent_cfg,args_cli)
env_cfg.scene.num_envs = args_cli.num_envs if args_cli.num_envs is not None else env_cfg.scene.num_envs
agent_cfg.max_iterations = (
args_cli.max_iterations if args_cli.max_iterations is not None else agent_cfg.max_iterations
)
env_cfg.seed = agent_cfg.seed
env_cfg.sim.device = args_cli.device if args_cli.device is not None else env_cfg.sim.device
# specify directory for logging experiments
log_root_path = CTS_RL_ROOT_DIR + "/logs/{}/".format(agent_cfg.experiment_name)
log_dir = CTS_RL_ROOT_DIR + "/logs/{}/".format(agent_cfg.experiment_name) + args_cli.run_name
try:
os.makedirs(log_dir)
except Exception:
pass
# log_root_path = os.path.join("logs", "rsl_rl", agent_cfg.experiment_name)
# log_root_path = os.path.abspath(log_root_path)
# # print(f"[INFO] Logging experiment in directory: {log_root_path}")
# # specify directory for logging runs: {time-stamp}_{run_name}
# log_dir = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
# if agent_cfg.run_name:
# log_dir += f"_{agent_cfg.run_name}"
# log_dir = os.path.join(log_root_path, log_dir)
# max iterations for training
if args_cli.max_iterations:
agent_cfg.max_iterations = args_cli.max_iterations
# create isaac environment
env = gym.make(args_cli.task, cfg=env_cfg, render_mode="rgb_array" if args_cli.video else None)
# wrap for video recording
if args_cli.video:
video_kwargs = {
"video_folder": os.path.join(log_dir, "videos"),
"step_trigger": lambda step: step % args_cli.video_interval == 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)
# convert to single-agent instance if required by the RL algorithm
if isinstance(env.unwrapped, DirectMARLEnv):
env = multi_agent_to_single_agent(env)
# wrap around environment for rsl-rl
env = RslRlVecEnvWrapper(env)
# create runner from rsl-rl
runner = CTSOnPolicyRunner(env, agent_cfg.to_dict(), log_dir=log_dir, device=agent_cfg.device)
# write git state to logs
runner.add_git_repo_to_log(__file__)
# save resume path before creating a new log_dir
if agent_cfg.resume:
# get path to previous checkpoint
agent_cfg.load_run = agent_cfg.run_name
print(log_root_path)
resume_path = get_checkpoint_path(log_root_path, agent_cfg.load_run, agent_cfg.load_checkpoint)
print(f"[INFO]: Loading model checkpoint from: {resume_path}")
# load previously trained model
runner.load(resume_path)
# set seed of the environment
env.seed(agent_cfg.seed)
# dump the configuration into log-directory
dump_yaml(os.path.join(log_dir, "params", "env.yaml"), env_cfg)
dump_yaml(os.path.join(log_dir, "params", "agent.yaml"), agent_cfg)
dump_pickle(os.path.join(log_dir, "params", "env.pkl"), env_cfg)
dump_pickle(os.path.join(log_dir, "params", "agent.pkl"), agent_cfg)
# run training
runner.learn(num_learning_iterations=agent_cfg.max_iterations, init_at_random_ep_len=True)
# close the simulator
env.close()
if __name__ == "__main__":
# run the main function
main()
# close sim app
simulation_app.close()
System Info
Describe the characteristic of your environment:
- Commit: 4.2.0 release
- Isaac Sim Version: 4.2.0-rc.17+release.15988.c99988b1.gl%
- OS: Ubuntu 20.04
- GPU: RTX 4090
- CUDA: 11.8
- GPU Driver: 535.183.01
Checklist
- I have checked that there is no similar issue in the repo (required)
- I have checked that the issue is not in running Isaac Sim itself and is related to the repo
Acceptance Criteria
Add the criteria for which this task is considered done. If not known at issue creation time, you can add this once the issue is assigned.
- Cause of error is identified and error is explained, how to fix it.