diff --git a/.vscode/tools/setup_vscode.py b/.vscode/tools/setup_vscode.py index 8156a1a943..0543766e9d 100644 --- a/.vscode/tools/setup_vscode.py +++ b/.vscode/tools/setup_vscode.py @@ -27,15 +27,20 @@ isaacsim_dir = os.environ.get("ISAAC_PATH", "") except ModuleNotFoundError or ImportError: isaacsim_dir = os.path.join(ISAACLAB_DIR, "_isaac_sim") +except EOFError: + print("Unable to trigger EULA acceptance. This is likely due to the script being run in a non-interactive shell.") + print("Please run the script in an interactive shell to accept the EULA.") + print("Skipping the setup of the VSCode settings...") + sys.exit(0) # check if the isaac-sim directory exists if not os.path.exists(isaacsim_dir): raise FileNotFoundError( - f"Could not find the isaac-sim directory: {isaacsim_dir}. There are two possible reasons for this:\n" - "\t1. The Isaac Sim directory does not exist as a symlink in the Isaac Lab directory.\n" - "\t2. The script could import the 'isaacsim' package. This could be due to the 'isaacsim' package not being " + f"Could not find the isaac-sim directory: {isaacsim_dir}. There are two possible reasons for this:" + f"\n\t1. The Isaac Sim directory does not exist as a symlink at: {os.path.join(ISAACLAB_DIR, '_isaac_sim')}" + "\n\t2. The script could import the 'isaacsim' package. This could be due to the 'isaacsim' package not being " "installed in the Python environment.\n" - "Please make sure that the Isaac Sim directory exists or that the 'isaacsim' package is installed." + "\nPlease make sure that the Isaac Sim directory exists or that the 'isaacsim' package is installed." ) ISAACSIM_DIR = isaacsim_dir @@ -48,39 +53,49 @@ def overwrite_python_analysis_extra_paths(isaaclab_settings: str) -> str: The extraPaths are replaced with the path names from the isaac-sim settings file that exists in the "{ISAACSIM_DIR}/.vscode/settings.json" file. + If the isaac-sim settings file does not exist, the extraPaths are not overwritten. + Args: isaaclab_settings: The settings string to use as template. Returns: The settings string with overwritten python analysis extra paths. - - Raises: - FileNotFoundError: If the isaac-sim settings file does not exist. """ # isaac-sim settings isaacsim_vscode_filename = os.path.join(ISAACSIM_DIR, ".vscode", "settings.json") - # make sure the isaac-sim settings file exists - if not os.path.exists(isaacsim_vscode_filename): - raise FileNotFoundError(f"Could not find the isaac-sim settings file: {isaacsim_vscode_filename}") - - # read the path names from the isaac-sim settings file - with open(isaacsim_vscode_filename) as f: - vscode_settings = f.read() - # extract the path names - # search for the python.analysis.extraPaths section and extract the contents - settings = re.search(r"\"python.analysis.extraPaths\": \[.*?\]", vscode_settings, flags=re.MULTILINE | re.DOTALL) - settings = settings.group(0) - settings = settings.split('"python.analysis.extraPaths": [')[-1] - settings = settings.split("]")[0] - - # read the path names from the isaac-sim settings file - path_names = settings.split(",") - path_names = [path_name.strip().strip('"') for path_name in path_names] - path_names = [path_name for path_name in path_names if len(path_name) > 0] - - # change the path names to be relative to the Isaac Lab directory - rel_path = os.path.relpath(ISAACSIM_DIR, ISAACLAB_DIR) - path_names = ['"${workspaceFolder}/' + rel_path + "/" + path_name + '"' for path_name in path_names] + + # we use the isaac-sim settings file to get the python.analysis.extraPaths for kit extensions + # if this file does not exist, we will not add any extra paths + if os.path.exists(isaacsim_vscode_filename): + # read the path names from the isaac-sim settings file + with open(isaacsim_vscode_filename) as f: + vscode_settings = f.read() + # extract the path names + # search for the python.analysis.extraPaths section and extract the contents + settings = re.search( + r"\"python.analysis.extraPaths\": \[.*?\]", vscode_settings, flags=re.MULTILINE | re.DOTALL + ) + settings = settings.group(0) + settings = settings.split('"python.analysis.extraPaths": [')[-1] + settings = settings.split("]")[0] + + # read the path names from the isaac-sim settings file + path_names = settings.split(",") + path_names = [path_name.strip().strip('"') for path_name in path_names] + path_names = [path_name for path_name in path_names if len(path_name) > 0] + + # change the path names to be relative to the Isaac Lab directory + rel_path = os.path.relpath(ISAACSIM_DIR, ISAACLAB_DIR) + path_names = ['"${workspaceFolder}/' + rel_path + "/" + path_name + '"' for path_name in path_names] + else: + path_names = [] + print( + f"[WARN] Could not find Isaac Sim VSCode settings: {isaacsim_vscode_filename}." + "\n\tThis will result in missing 'python.analysis.extraPaths' in the VSCode" + "\n\tsettings, which limits the functionality of the Python language server." + "\n\tHowever, it does not affect the functionality of the Isaac Lab project." + "\n\tWe are working on a fix for this issue with the Isaac Sim team." + ) # add the path names that are in the Isaac Lab extensions directory isaaclab_extensions = os.listdir(os.path.join(ISAACLAB_DIR, "source", "extensions")) @@ -89,9 +104,9 @@ def overwrite_python_analysis_extra_paths(isaaclab_settings: str) -> str: # combine them into a single string path_names = ",\n\t\t".expandtabs(4).join(path_names) # deal with the path separator being different on Windows and Unix - path_names = path_names.replace("/", os.sep) + path_names = path_names.replace("\\", "/") - # replace the path names in the Isaac Lab settings file with the path names from the isaac-sim settings file + # replace the path names in the Isaac Lab settings file with the path names parsed isaaclab_settings = re.sub( r"\"python.analysis.extraPaths\": \[.*?\]", '"python.analysis.extraPaths": [\n\t\t'.expandtabs(4) + path_names + "\n\t]".expandtabs(4), @@ -116,10 +131,7 @@ def overwrite_default_python_interpreter(isaaclab_settings: str) -> str: The settings string with overwritten default python interpreter. """ # read executable name - python_exe = sys.executable - # if python interpreter is from conda, use that. Otherwise, use the template. - if "conda" not in python_exe: - return isaaclab_settings + python_exe = sys.executable.replace("\\", "/") # replace the default python interpreter in the Isaac Lab settings file with the path to the # python interpreter in the Isaac Lab directory isaaclab_settings = re.sub( @@ -146,9 +158,9 @@ def main(): # overwrite the python.analysis.extraPaths in the Isaac Lab settings file with the path names isaaclab_settings = overwrite_python_analysis_extra_paths(isaaclab_template_settings) - # overwrite the default python interpreter in the Isaac Lab settings file - # NOTE: thisis disabled since we don't need it. The default interpreter should always be the one from isaac-sim - # isaaclab_settings = overwrite_default_python_interpreter(isaaclab_settings) + # overwrite the default python interpreter in the Isaac Lab settings file with the path to the + # python interpreter used to call this script + isaaclab_settings = overwrite_default_python_interpreter(isaaclab_settings) # add template notice to the top of the file header_message = ( diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 630f33afd8..166bfaf43b 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -53,6 +53,7 @@ Guidelines for modifications: * Shafeef Omar * Vladimir Fokow * Zhengyu Zhang +* Ziqi Fan ## Acknowledgements diff --git a/docker/Dockerfile.pip b/docker/Dockerfile.pip new file mode 100644 index 0000000000..21d9bb3e90 --- /dev/null +++ b/docker/Dockerfile.pip @@ -0,0 +1,100 @@ +# Copyright (c) 2022-2024, The Isaac Lab Project Developers. +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause + +# This Dockerfile is used to build a Docker image for the Isaac Lab framework. +# +# It uses the pip package manager to install Isaac Sim and the Isaac Lab framework. +# +# To build the Docker image and run the Docker container, follow the steps below: +# +# 1. Build the Docker image: +# docker build -t isaac-lab-pip:latest -f docker/Dockerfile.pip . +# 2. Run the Docker container: +# docker run -it --gpus all --rm --network=host --name isaac-lab -v $(pwd):/root/isaaclab isaac-lab-pip:latest + +# Base image: Ubuntu 22.04 +FROM ubuntu:22.04 AS base + +# Set default RUN shell to bash +SHELL ["/bin/bash", "-c"] + +# Adds labels to the Dockerfile +LABEL version="1.0" +LABEL description="Dockerfile for building and running the Isaac Lab framework in Ubuntu 22.04 container image." + +# Arguments +# Path to the Isaac Lab directory +ENV ISAACLAB_PATH=/root/isaaclab +# Home dir of docker user, typically '/root' +ENV DOCKER_USER_HOME=/root + +# Set environment variables +ENV LANG=C.UTF-8 +ENV DEBIAN_FRONTEND=noninteractive + +USER root + +# Install dependencies and remove cache +RUN --mount=type=cache,target=/var/cache/apt \ + apt-get update && apt-get install -y --no-install-recommends \ + build-essential \ + cmake \ + git \ + libglib2.0-0 \ + ncurses-term && \ + apt -y autoremove && apt clean autoclean && \ + rm -rf /var/lib/apt/lists/* + +# for singularity usage, have to create the directories that will binded +RUN mkdir -p ${DOCKER_USER_HOME}/.cache/ov && \ + mkdir -p ${DOCKER_USER_HOME}/.cache/pip && \ + mkdir -p ${DOCKER_USER_HOME}/.cache/nvidia/GLCache && \ + mkdir -p ${DOCKER_USER_HOME}/.nv/ComputeCache && \ + mkdir -p ${DOCKER_USER_HOME}/.nvidia-omniverse/logs && \ + mkdir -p ${DOCKER_USER_HOME}/.local/share/ov/data && \ + mkdir -p ${DOCKER_USER_HOME}/Documents + +# for singularity usage, create NVIDIA binary placeholders +RUN touch /bin/nvidia-smi && \ + touch /bin/nvidia-debugdump && \ + touch /bin/nvidia-persistenced && \ + touch /bin/nvidia-cuda-mps-control && \ + touch /bin/nvidia-cuda-mps-server && \ + touch /etc/localtime && \ + mkdir -p /var/run/nvidia-persistenced && \ + touch /var/run/nvidia-persistenced/socket + +# Install python3 and pip +RUN apt-get update && apt-get install -y --no-install-recommends \ + python3 \ + python3-pip && \ + apt -y autoremove && apt clean autoclean && \ + rm -rf /var/lib/apt/lists/* +# Maintain python3 as the default python version +RUN update-alternatives --install /usr/bin/python python /usr/bin/python3 1 +RUN update-alternatives --install /usr/bin/pip pip /usr/bin/pip3 1 + +# Install python packages +RUN pip3 install --no-cache-dir --upgrade pip && \ + pip install torch==2.2.2 --index-url https://download.pytorch.org/whl/cu118 + +RUN pip install isaacsim-rl isaacsim-replicator isaacsim-extscache-physics isaacsim-extscache-kit-sdk isaacsim-extscache-kit isaacsim-app --extra-index-url https://pypi.nvidia.com + +# Mount the Isaac Lab directory (files to exclude are defined in .dockerignore) +COPY ../ ${ISAACLAB_PATH} + +# installing Isaac Lab dependencies +# use pip caching to avoid reinstalling large packages +RUN --mount=type=cache,target=${DOCKER_USER_HOME}/.cache/pip \ + ${ISAACLAB_PATH}/isaaclab.sh --install + +# aliasing isaaclab.sh and python for convenience +RUN echo "export ISAACLAB_PATH=${ISAACLAB_PATH}" >> ${HOME}/.bashrc && \ + echo "alias isaaclab=${ISAACLAB_PATH}/isaaclab.sh" >> ${HOME}/.bashrc && \ + echo "export TZ=$(date +%Z)" >> ${HOME}/.bashrc + +# make working directory as the Isaac Lab directory +# this is the default directory when the container is run +WORKDIR ${ISAACLAB_PATH} diff --git a/docker/container.sh b/docker/container.sh index cde4fd69ca..c8789bb36f 100755 --- a/docker/container.sh +++ b/docker/container.sh @@ -25,7 +25,7 @@ fi # print the usage description print_help () { - echo -e "\nusage: $(basename "$0") [-h] [run] [start] [stop] -- Utility for handling docker in Isaac Lab." + echo -e "\nusage: $(basename "$0") [-h] [...] -- Utility for handling Docker in Isaac Lab." echo -e "\noptional arguments:" echo -e "\t-h, --help Display the help content." echo -e "\tstart [profile] Build the docker image and create the container in detached mode." @@ -36,8 +36,9 @@ print_help () { echo -e "\tjob [profile] [job_args] Submit a job to the cluster." echo -e "\tconfig [profile] Parse, resolve and render compose file in canonical format." echo -e "\n" - echo -e "[profile] is the optional container profile specification and [job_args] optional arguments specific" - echo -e "to the executed script" + echo -e "where: " + echo -e "\t[profile] is the optional container profile specification. Example: 'isaaclab', 'base', 'ros2'." + echo -e "\t[job_args] are optional arguments specific to the executed script." echo -e "\n" >&2 } @@ -56,8 +57,8 @@ install_apptainer() { install_yq() { # Installing yq to handle file parsing - # Installation procedure from here: https://github.com/mikefarah/yq - read -p "[INFO] Required 'yq' package could not be found. Would you like to install it via wget? (y/N)" yq_answer + # Installation procedure from here: https://github.com/mikefarah/yq?tab=readme-ov-file#linux-via-snap + read -p "[INFO] Required 'yq' package could not be found. Would you like to install it via snap? (y/N)" yq_answer if [ "$yq_answer" != "${yq_answer#[Yy]}" ]; then sudo snap install yq else @@ -67,17 +68,29 @@ install_yq() { } set_statefile_variable() { + # Check if yq is installed + if ! command -v yq &> /dev/null; then + install_yq + fi # Stores key $1 with value $2 in yaml $STATEFILE yq -i '.["'"$1"'"] = "'"$2"'"' $STATEFILE } load_statefile_variable() { + # Check if yq is installed + if ! command -v yq &> /dev/null; then + install_yq + fi # Loads key $1 from yaml $STATEFILE as an envvar # If key does not exist, the loaded var will equal "null" eval $1="$(yq ".$1" $STATEFILE)" } delete_statefile_variable() { + # Check if yq is installed + if ! command -v yq &> /dev/null; then + install_yq + fi # Deletes key $1 from yaml $STATEFILE yq -i "del(.$1)" $STATEFILE } @@ -270,10 +283,6 @@ if ! command -v docker &> /dev/null; then exit 1 fi -if ! command -v yq &> /dev/null; then - install_yq -fi - # parse arguments mode="$1" profile_arg="$2" # Capture the second argument as the potential profile argument diff --git a/docs/source/deployment/docker.rst b/docs/source/deployment/docker.rst index 77a994c2a6..8bda6ab920 100644 --- a/docs/source/deployment/docker.rst +++ b/docs/source/deployment/docker.rst @@ -156,18 +156,18 @@ Understanding the mounted volumes The ``docker-compose.yaml`` file creates several named volumes that are mounted to the container. These are summarized below: -* ``isaac-cache-kit``: This volume is used to store cached Kit resources (`/isaac-sim/kit/cache` in container) -* ``isaac-cache-ov``: This volume is used to store cached OV resources (`/root/.cache/ov` in container) -* ``isaac-cache-pip``: This volume is used to store cached pip resources (`/root/.cache/pip`` in container) -* ``isaac-cache-gl``: This volume is used to store cached GLCache resources (`/root/.cache/nvidia/GLCache` in container) -* ``isaac-cache-compute``: This volume is used to store cached compute resources (`/root/.nv/ComputeCache` in container) -* ``isaac-logs``: This volume is used to store logs generated by Omniverse. (`/root/.nvidia-omniverse/logs` in container) -* ``isaac-carb-logs``: This volume is used to store logs generated by carb. (`/isaac-sim/kit/logs/Kit/Isaac-Sim` in container) -* ``isaac-data``: This volume is used to store data generated by Omniverse. (`/root/.local/share/ov/data` in container) -* ``isaac-docs``: This volume is used to store documents generated by Omniverse. (`/root/Documents` in container) -* ``isaac-lab-docs``: This volume is used to store documentation of Isaac Lab when built inside the container. (`/workspace/isaaclab/docs/_build` in container) -* ``isaac-lab-logs``: This volume is used to store logs generated by Isaac Lab workflows when run inside the container. (`/workspace/isaaclab/logs` in container) -* ``isaac-lab-data``: This volume is used to store whatever data users may want to preserve between container runs. (`/workspace/isaaclab/data_storage` in container) +* ``isaac-cache-kit``: This volume is used to store cached Kit resources (``/isaac-sim/kit/cache`` in container) +* ``isaac-cache-ov``: This volume is used to store cached OV resources (``/root/.cache/ov`` in container) +* ``isaac-cache-pip``: This volume is used to store cached pip resources (``/root/.cache/pip`` in container) +* ``isaac-cache-gl``: This volume is used to store cached GLCache resources (``/root/.cache/nvidia/GLCache`` in container) +* ``isaac-cache-compute``: This volume is used to store cached compute resources (``/root/.nv/ComputeCache`` in container) +* ``isaac-logs``: This volume is used to store logs generated by Omniverse. (``/root/.nvidia-omniverse/logs`` in container) +* ``isaac-carb-logs``: This volume is used to store logs generated by carb. (``/isaac-sim/kit/logs/Kit/Isaac-Sim`` in container) +* ``isaac-data``: This volume is used to store data generated by Omniverse. (``/root/.local/share/ov/data`` in container) +* ``isaac-docs``: This volume is used to store documents generated by Omniverse. (``/root/Documents`` in container) +* ``isaac-lab-docs``: This volume is used to store documentation of Isaac Lab when built inside the container. (``/workspace/isaaclab/docs/_build`` in container) +* ``isaac-lab-logs``: This volume is used to store logs generated by Isaac Lab workflows when run inside the container. (``/workspace/isaaclab/logs`` in container) +* ``isaac-lab-data``: This volume is used to store whatever data users may want to preserve between container runs. (``/workspace/isaaclab/data_storage`` in container) To view the contents of these volumes, you can use the following command: diff --git a/docs/source/deployment/run_docker_example.rst b/docs/source/deployment/run_docker_example.rst index b38b5b3226..de16cc0c15 100644 --- a/docs/source/deployment/run_docker_example.rst +++ b/docs/source/deployment/run_docker_example.rst @@ -131,7 +131,7 @@ the build process when we next run ``./container.sh start``, we may enter the fo docker image rm isaaclab -A subsequent run of ``docker image ls``` will show that the image tagged **isaaclab** is now gone. We can repeat the process for the +A subsequent run of ``docker image ls`` will show that the image tagged **isaaclab** is now gone. We can repeat the process for the underlying NVIDIA container if we wish to free up more space. If a more powerful method of freeing resources from Docker is desired, please consult the documentation for the `docker prune`_ commands. diff --git a/docs/source/setup/installation/binaries_installation.rst b/docs/source/setup/installation/binaries_installation.rst index 7607758bd2..f8738c0547 100644 --- a/docs/source/setup/installation/binaries_installation.rst +++ b/docs/source/setup/installation/binaries_installation.rst @@ -1,3 +1,6 @@ +.. _isaacsim-binaries-installation: + + Installation using Isaac Sim Binaries ===================================== diff --git a/docs/source/setup/installation/pip_installation.rst b/docs/source/setup/installation/pip_installation.rst index 0c58047253..7b42abe7a9 100644 --- a/docs/source/setup/installation/pip_installation.rst +++ b/docs/source/setup/installation/pip_installation.rst @@ -1,3 +1,5 @@ +.. _isaacsim-pip-installation: + Installation using Isaac Sim pip ================================ @@ -5,18 +7,18 @@ Installation using Isaac Sim pip Installing Isaac Sim -------------------- -.. note:: - - Installing Isaac Sim from pip is currently an experimental feature. - If errors occur, please report them to the - `Isaac Sim Forums `_ - and install Isaac Sim from pre-built binaries. +From Isaac Sim 4.0 release, it is possible to install Isaac Sim using pip. This approach is experimental and may have +compatibility issues with some Linux distributions. If you encounter any issues, please report them to the +`Isaac Sim Forums `_. -.. note:: +.. attention:: Installing Isaac Sim with pip requires GLIBC 2.34+ version compatibility. To check the GLIBC version on your system, use command ``ldd --version``. + This may pose compatibility issues with some Linux distributions. For instance, Ubuntu 20.04 LTS has GLIBC 2.31 + by default. If you encounter compatibility issues, we recommend following the + :ref:`Isaac Sim Binaries Installation ` approach. - To use the pip installation approach for Isaac Sim, we recommend first creating a virtual environment. Ensure that the python version of the virtual environment is **Python 3.10**. diff --git a/isaaclab.bat b/isaaclab.bat index f48c331b0f..514f023f23 100644 --- a/isaaclab.bat +++ b/isaaclab.bat @@ -12,40 +12,57 @@ goto main rem Helper functions -rem extract the python from isaacsim -:extract_python_exe -rem Check if IsaacSim directory manually specified -rem Note: for manually build isaacsim, this: _build/linux-x86_64/release -if not "%ISAACSIM_PATH%"=="" ( - rem Use local build - set build_path=%ISAACSIM_PATH% -) else ( - rem Use TeamCity build - set build_path=%ISAACLAB_PATH%\_isaac_sim -) -rem check if using conda +rem extract Isaac Sim directory +:extract_isaacsim_path +rem check if conda environment is activated and isaacsim package is installed if not "%CONDA_PREFIX%"=="" ( rem use conda python set python_exe=%CONDA_PREFIX%\python -) else ( - rem check if isaacsim is installed - pip show isaacsim-rl > nul 2>&1 + call !python_exe! -m pip show isaacsim-rl > nul 2>&1 if errorlevel 1 ( - rem use python from kit if Isaac Sim not installed from pip - set python_exe=%build_path%\python.bat + rem Use the sym-link path to Isaac Sim directory + set isaac_path=%ISAACLAB_PATH%\_isaac_sim ) else ( - rem use current python if Isaac Sim is installed from pip - set "python_exe=" - for /f "delims=" %%i in ('where python') do ( - if not defined python_exe ( - set "python_exe=%%i" + rem retrieve the isaacsim path from the installed package + set "isaac_path=" + for /f "delims=" %%i in ('!python_exe! -c "import isaacsim; import os; print(os.environ['ISAAC_PATH'])"') do ( + if not defined isaac_path ( + set "isaac_path=%%i" ) ) ) +) else ( + rem Use the sym-link path to Isaac Sim directory + set isaac_path=%ISAACLAB_PATH%\_isaac_sim +) +rem Check if the directory exists +if not exist "%isaac_path%" ( + echo [ERROR] Unable to find the Isaac Sim directory: %isaac_path% + echo %tab%This could be due to the following reasons: + echo %tab%1. Conda environment with Isaac Sim pip package is not activated. + echo %tab%2. Isaac Sim directory is not available at the default path: %ISAACLAB_PATH%\_isaac_sim + exit /b 1 +) +goto :eof + +rem extract the python from isaacsim +:extract_python_exe +rem check if using conda +if not "%CONDA_PREFIX%"=="" ( + rem use conda python + set python_exe=%CONDA_PREFIX%\python +) else ( + rem obtain isaacsim path + call :extract_isaacsim_path + rem use python from kit if Isaac Sim not installed from pip + set python_exe=!isaac_path!\python.bat ) rem check if there is a python path available if "%python_exe%"=="" ( - echo [ERROR] No python executable found at path: %build_path% + echo [ERROR] Unable to find any Python executable at path: %isaac_path% + echo %tab%This could be due to the following reasons: + echo %tab%1. Conda environment is not activated. + echo %tab%2. Python executable is not available at the default path: %ISAACLAB_PATH%\_isaac_sim\python.bat exit /b 1 ) goto :eof @@ -53,20 +70,20 @@ goto :eof rem extract the simulator exe from isaacsim :extract_isaacsim_exe -rem Check if IsaacSim directory manually specified -rem Note: for manually build isaacsim, this: _build\linux-x86_64\release -if not "%ISAACSIM_PATH%"=="" ( - rem Use local build - set build_path=%ISAACSIM_PATH% +call :extract_python_exe +call !python_exe! -m pip show isaacsim-rl > nul 2>&1 +if errorlevel 1 ( + rem obtain isaacsim path + call :extract_isaacsim_path + rem python executable to use + set isaacsim_exe=!isaac_path!\isaac-sim.bat ) else ( - rem Use TeamCity build - set build_path=%ISAACLAB_PATH%\_isaac_sim + rem if isaac sim installed from pip + set isaacsim_exe=isaacsim ) -rem python executable to use -set isaacsim_exe=%build_path%\isaac-sim.bat rem check if there is a python path available if not exist "%isaacsim_exe%" ( - echo [ERROR] No isaac-sim executable found at path: %build_path% + echo [ERROR] No isaac-sim executable found at path: !isaac_path! exit /b 1 ) goto :eof @@ -95,15 +112,6 @@ if errorlevel 1 ( echo [ERROR] Conda could not be found. Please install conda and try again. exit /b 1 ) -rem check if Isaac Sim directory manually specified -rem Note: for manually build Isaac Sim, this: _build\windows-x86_64\release -if not "%ISAACSIM_PATH%"=="" ( - rem Use local build - set "build_path=%ISAACSIM_PATH%" -) else ( - rem Use TeamCity build - set "build_path=%ISAACLAB_PATH%\_isaac_sim" -) rem check if the environment exists call conda env list | findstr /c:"%env_name%" >nul if %errorlevel% equ 0 ( @@ -124,27 +132,34 @@ call conda activate %env_name% rem setup directories to load isaac-sim variables mkdir "%CONDA_PREFIX%\etc\conda\activate.d" 2>nul mkdir "%CONDA_PREFIX%\etc\conda\deactivate.d" 2>nul + +rem obtain isaacsim path +call :extract_isaacsim_path + rem add variables to environment during activation ( echo @echo off - rem for isaac-sim - echo set CARB_APP_PATH=%build_path%\kit - echo set EXP_PATH=%build_path%\apps - echo set ISAAC_PATH=%build_path% - echo set PYTHONPATH=%PYTHONPATH%;%build_path%\site + echo rem for isaac-sim echo set "RESOURCE_NAME=IsaacSim" + echo set CARB_APP_PATH=!isaac_path!\kit + echo set EXP_PATH=!isaac_path!\apps + echo set ISAAC_PATH=!isaac_path! + echo set PYTHONPATH=%PYTHONPATH%;!isaac_path!\site + echo. + echo rem for isaac-lab echo doskey isaaclab=isaaclab.bat $* ) > "%CONDA_PREFIX%\etc\conda\activate.d\env_vars.bat" ( - echo $env:CARB_APP_PATH="%build_path%\kit" - echo $env:EXP_PATH="%build_path%\apps" - echo $env:ISAAC_PATH="%build_path%" - echo $env:PYTHONPATH="%PYTHONPATH%;%build_path%\site" + echo $env:CARB_APP_PATH="!isaac_path!\kit" + echo $env:EXP_PATH="!isaac_path!\apps" + echo $env:ISAAC_PATH="!isaac_path!" + echo $env:PYTHONPATH="%PYTHONPATH%;!isaac_path!\site" echo $env:RESOURCE_NAME="IsaacSim" ) > "%CONDA_PREFIX%\etc\conda\activate.d\env_vars.ps1" rem reactivate the environment to load the variables call conda activate %env_name% + rem remove variables from environment during deactivation ( echo @echo off @@ -153,6 +168,8 @@ rem remove variables from environment during deactivation echo set "EXP_PATH=" echo set "ISAAC_PATH=" echo set "RESOURCE_NAME=" + echo. + echo rem for isaac-lab echo doskey isaaclab = echo. echo rem restore paths @@ -160,9 +177,6 @@ rem remove variables from environment during deactivation echo set "LD_LIBRARY_PATH=%cache_ld_library_path%" ) > "%CONDA_PREFIX%\etc\conda\deactivate.d\unsetenv_vars.bat" ( - echo $env:CARB_APP_PATH="" - echo $env:EXP_PATH="" - echo $env:ISAAC_PATH="" echo $env:RESOURCE_NAME="" echo $env:PYTHONPATH="%cache_pythonpath%" echo $env:LD_LIBRARY_PATH="%cache_pythonpath%" @@ -171,6 +185,7 @@ rem remove variables from environment during deactivation rem install some extra dependencies echo [INFO] Installing extra dependencies (this might take a few minutes)... call conda install -c conda-forge -y importlib_metadata >nul 2>&1 + rem deactivate the environment call conda deactivate rem add information to the user about alias @@ -179,8 +194,8 @@ echo [INFO] Created conda environment named '%env_name%'. echo. echo 1. To activate the environment, run: conda activate %env_name% echo 2. To install Isaac Lab extensions, run: isaaclab -i -echo 4. To perform formatting, run: isaaclab -f -echo 5. To deactivate the environment, run: conda deactivate +echo 3. To perform formatting, run: isaaclab -f +echo 4. To deactivate the environment, run: conda deactivate echo. goto :eof @@ -189,7 +204,7 @@ rem Update the vscode settings from template and Isaac Sim settings :update_vscode_settings echo [INFO] Setting up vscode settings... rem Retrieve the python executable -call :extract_python_exe python_exe +call :extract_python_exe rem Path to setup_vscode.py set "setup_vscode_script=%ISAACLAB_PATH%\.vscode\tools\setup_vscode.py" rem Check if the file exists before attempting to run it @@ -244,12 +259,6 @@ if "%arg%"=="-i" ( set ext_folder="%%d" call :install_isaaclab_extension ) - call !python_exe! -m pip show isaacsim-rl > nul 2>&1 - rem if not installing from pip, set up VScode - if errorlevel 1 ( - rem setup vscode settings - call :update_vscode_settings - ) rem install the python packages for supported reinforcement learning frameworks echo [INFO] Installing extra requirements such as learning frameworks... if "%~2"=="" ( @@ -265,7 +274,7 @@ if "%arg%"=="-i" ( shift ) rem install the rl-frameworks specified - !python_exe! -m pip install -e %ISAACLAB_PATH%\source\extensions\omni.isaac.lab_tasks[!framework_name!] + call !python_exe! -m pip install -e %ISAACLAB_PATH%\source\extensions\omni.isaac.lab_tasks[!framework_name!] shift ) else if "%arg%"=="--install" ( rem install the python packages in omni.isaac.rl/source directory @@ -275,12 +284,6 @@ if "%arg%"=="-i" ( set ext_folder="%%d" call :install_isaaclab_extension ) - call !python_exe! -m pip show isaacsim-rl > nul 2>&1 - rem if not installing from pip, set up VScode - if errorlevel 1 ( - rem setup vscode settings - call :update_vscode_settings - ) rem install the python packages for supported reinforcement learning frameworks echo [INFO] Installing extra requirements such as learning frameworks... if "%~2"=="" ( @@ -296,7 +299,10 @@ if "%arg%"=="-i" ( shift ) rem install the rl-frameworks specified - !python_exe! -m pip install -e %ISAACLAB_PATH%\source\extensions\omni.isaac.lab_tasks[!framework_name!] + call !python_exe! -m pip install -e %ISAACLAB_PATH%\source\extensions\omni.isaac.lab_tasks[!framework_name!] + rem update the vscode settings + rem once we have a docker container, we need to disable vscode settings + call :update_vscode_settings shift ) else if "%arg%"=="-c" ( rem use default name if not provided @@ -413,7 +419,7 @@ if "%arg%"=="-i" ( ) else if "%arg%"=="-s" ( rem run the simulator exe provided by isaacsim call :extract_isaacsim_exe - echo [INFO] Running isaac-sim from: %isaacsim_exe% + echo [INFO] Running isaac-sim from: !isaacsim_exe! set "allArgs=" for %%a in (%*) do ( REM Append each argument to the variable, skip the first one @@ -428,7 +434,7 @@ if "%arg%"=="-i" ( ) else if "%arg%"=="--sim" ( rem run the simulator exe provided by Isaac Sim call :extract_isaacsim_exe - echo [INFO] Running isaac-sim from: %isaacsim_exe% + echo [INFO] Running isaac-sim from: !isaacsim_exe! set "allArgs=" for %%a in (%*) do ( REM Append each argument to the variable, skip the first one diff --git a/isaaclab.sh b/isaaclab.sh index 1ef84f013b..d3166b4f48 100755 --- a/isaaclab.sh +++ b/isaaclab.sh @@ -22,34 +22,60 @@ export ISAACLAB_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && p # Helper functions #== +# extract isaac sim path +extract_isaacsim_path() { + # Use the sym-link path to Isaac Sim directory + local isaac_path=${ISAACLAB_PATH}/_isaac_sim + # If above path is not available, try to find the path using python + if [ ! -d "${isaac_path}" ]; then + # Use the python executable to get the path + local python_exe=$(extract_python_exe) + # Retrieve the path importing isaac sim and getting the environment path + if [ $(${python_exe} -m pip list | grep -c 'isaacsim-rl') ]; then + local isaac_path=$(${python_exe} -c "import isaacsim; import os; print(os.environ['ISAAC_PATH'])") + fi + fi + # check if there is a path available + if [ ! -d "${isaac_path}" ]; then + # throw an error if no path is found + echo -e "[ERROR] Unable to find the Isaac Sim directory: '${isaac_path}'" >&2 + echo -e "\tThis could be due to the following reasons:" >&2 + echo -e "\t1. Conda environment is not activated." >&2 + echo -e "\t2. Isaac Sim pip package 'isaacsim-rl' is not installed." >&2 + echo -e "\t3. Isaac Sim directory is not available at the default path: ${ISAACLAB_PATH}/_isaac_sim" >&2 + # exit the script + exit 1 + fi + # return the result + echo ${isaac_path} +} + # extract the python from isaacsim extract_python_exe() { - # Check if IsaacSim directory manually specified - # Note: for manually build isaacsim, this: _build/linux-x86_64/release - if [ ! -z ${ISAACSIM_PATH} ]; - then - # Use local build - build_path=${ISAACSIM_PATH} - else - # Use TeamCity build - build_path=${ISAACLAB_PATH}/_isaac_sim - fi - # check if using conda - if ! [[ -z "${CONDA_PREFIX}" ]]; then - # use conda python - local python_exe=${CONDA_PREFIX}/bin/python - else - if pip show isaacsim-rl > /dev/null 2>&1; then - # use current python executable - python_exe=$(which python) + # default to python in the kit + local python_exe=${ISAACLAB_PATH}/_isaac_sim/python.sh + # if default python is not available, check if conda is activated + if [ ! -f "${python_exe}" ]; then + # check if using conda + if ! [[ -z "${CONDA_PREFIX}" ]]; then + # use conda python + local python_exe=${CONDA_PREFIX}/bin/python else - # use python from kit - local python_exe=${build_path}/python.sh + # note: we need to check system python for cases such as docker + # inside docker, if user installed into system python, we need to use that + # otherwise, use the python from the kit + if [ $(python -m pip list | grep -c 'isaacsim-rl') ]; then + local python_exe=$(which python) + fi fi fi # check if there is a python path available if [ ! -f "${python_exe}" ]; then - echo "[ERROR] No python executable found at path: ${build_path}" >&2 + echo -e "[ERROR] Unable to find any Python executable at path: '${python_exe}'" >&2 + echo -e "\tThis could be due to the following reasons:" >&2 + echo -e "\t1. Conda environment is not activated." >&2 + echo -e "\t2. Isaac Sim pip package 'isaacsim-rl' is not installed." >&2 + echo -e "\t3. Python executable is not available at the default path: ${ISAACLAB_PATH}/_isaac_sim/python.sh" >&2 exit 1 fi # return the result @@ -58,21 +84,13 @@ extract_python_exe() { # extract the simulator exe from isaacsim extract_isaacsim_exe() { - # Check if IsaacSim directory manually specified - # Note: for manually build isaacsim, this: _build/linux-x86_64/release - if [ ! -z ${ISAACSIM_PATH} ]; - then - # Use local build - build_path=${ISAACSIM_PATH} - else - # Use TeamCity build - build_path=${ISAACLAB_PATH}/_isaac_sim - fi + # obtain the isaac sim path + local isaac_path=$(extract_isaacsim_path) # python executable to use - local isaacsim_exe=${build_path}/isaac-sim.sh + local isaacsim_exe=${isaac_path}/isaac-sim.sh # check if there is a python path available if [ ! -f "${isaacsim_exe}" ]; then - echo "[ERROR] No isaac-sim executable found at path: ${build_path}" >&2 + echo "[ERROR] No Isaac Sim executable found at path: ${isaacsim_exe}" >&2 exit 1 fi # return the result @@ -100,16 +118,7 @@ setup_conda_env() { echo "[ERROR] Conda could not be found. Please install conda and try again." exit 1 fi - # Check if IsaacSim directory manually specified - # Note: for manually build isaacsim, this: _build/linux-x86_64/release - if [ ! -z ${ISAACSIM_PATH} ]; - then - # Use local build - build_path=${ISAACSIM_PATH} - else - # Use TeamCity build - build_path=${ISAACLAB_PATH}/_isaac_sim - fi + # check if the environment exists if { conda env list | grep -w ${env_name}; } >/dev/null 2>&1; then echo -e "[INFO] Conda environment named '${env_name}' already exists." @@ -117,6 +126,7 @@ setup_conda_env() { echo -e "[INFO] Creating conda environment named '${env_name}'..." conda create -y --name ${env_name} python=3.10 fi + # cache current paths for later cache_pythonpath=$PYTHONPATH cache_ld_library_path=$LD_LIBRARY_PATH @@ -129,12 +139,9 @@ setup_conda_env() { # setup directories to load Isaac Sim variables mkdir -p ${CONDA_PREFIX}/etc/conda/activate.d mkdir -p ${CONDA_PREFIX}/etc/conda/deactivate.d + # add variables to environment during activation - local isaacsim_setup_conda_env_script=${ISAACLAB_PATH}/_isaac_sim/setup_conda_env.sh printf '%s\n' '#!/usr/bin/env bash' '' \ - '# for Isaac Sim' \ - 'source '${isaacsim_setup_conda_env_script}'' \ - '' \ '# for Isaac Lab' \ 'export ISAACLAB_PATH='${ISAACLAB_PATH}'' \ 'alias isaaclab='${ISAACLAB_PATH}'/isaaclab.sh' \ @@ -142,28 +149,51 @@ setup_conda_env() { '# show icon if not runninng headless' \ 'export RESOURCE_NAME="IsaacSim"' \ '' > ${CONDA_PREFIX}/etc/conda/activate.d/setenv.sh + + # check if we have _isaac_sim directory -> if so that means binaries were installed. + # we need to setup conda variables to load the binaries + local isaacsim_setup_conda_env_script=${ISAACLAB_PATH}/_isaac_sim/setup_conda_env.sh + if [ -f "${isaacsim_setup_conda_env_script}" ]; then + # add variables to environment during activation + printf '' \ + '# for Isaac Sim' \ + 'source '${isaacsim_setup_conda_env_script}'' \ + '' >> ${CONDA_PREFIX}/etc/conda/activate.d/setenv.sh + fi + # reactivate the environment to load the variables # needed because deactivate complains about Isaac Lab alias since it otherwise doesn't exist conda activate ${env_name} + # remove variables from environment during deactivation printf '%s\n' '#!/usr/bin/env bash' '' \ '# for Isaac Lab' \ 'unalias isaaclab &>/dev/null' \ 'unset ISAACLAB_PATH' \ '' \ - '# for Isaac Sim' \ - 'unset CARB_APP_PATH' \ - 'unset EXP_PATH' \ - 'unset ISAAC_PATH' \ - 'unset RESOURCE_NAME' \ - '' \ '# restore paths' \ 'export PYTHONPATH='${cache_pythonpath}'' \ 'export LD_LIBRARY_PATH='${cache_ld_library_path}'' \ + '' \ + '# for Isaac Sim' \ + 'unset RESOURCE_NAME' \ '' > ${CONDA_PREFIX}/etc/conda/deactivate.d/unsetenv.sh + + # check if we have _isaac_sim directory -> if so that means binaries were installed. + if [ -f "${isaacsim_setup_conda_env_script}" ]; then + # add variables to environment during activation + printf '' \ + '# for Isaac Sim' \ + 'unset CARB_APP_PATH' \ + 'unset EXP_PATH' \ + 'unset ISAAC_PATH' \ + '' >> ${CONDA_PREFIX}/etc/conda/deactivate.d/unsetenv.sh + fi + # install some extra dependencies echo -e "[INFO] Installing extra dependencies (this might take a few minutes)..." conda install -c conda-forge -y importlib_metadata &> /dev/null + # deactivate the environment conda deactivate # add information to the user about alias @@ -187,7 +217,7 @@ update_vscode_settings() { if [ -f "${setup_vscode_script}" ]; then ${python_exe} "${setup_vscode_script}" else - echo "[WARNING] setup_vscode.py not found. Aborting vscode settings setup." + echo "[WARNING] Unable to find the script 'setup_vscode.py'. Aborting vscode settings setup." fi } @@ -234,12 +264,6 @@ while [[ $# -gt 0 ]]; do export -f install_isaaclab_extension # source directory find -L "${ISAACLAB_PATH}/source/extensions" -mindepth 1 -maxdepth 1 -type d -exec bash -c 'install_isaaclab_extension "{}"' \; - # unset local variables - unset install_isaaclab_extension - # setup vscode settings - if ! ${python_exe} -m pip show isaacsim-rl &>/dev/null; then - update_vscode_settings - fi # install the python packages for supported reinforcement learning frameworks echo "[INFO] Installing extra requirements such as learning frameworks..." # check if specified which rl-framework to install @@ -257,6 +281,20 @@ while [[ $# -gt 0 ]]; do fi # install the rl-frameworks specified ${python_exe} -m pip install -e ${ISAACLAB_PATH}/source/extensions/omni.isaac.lab_tasks["${framework_name}"] + + # check if we are inside a docker container or are building a docker image + # in that case don't setup VSCode since it asks for EULA agreement which triggers user interaction + if [ -f /.dockerenv ]; then + echo "[INFO] Running inside a docker container. Skipping VSCode settings setup." + echo "[INFO] To setup VSCode settings, run 'isaaclab -v'." + else + # update the vscode settings + update_vscode_settings + fi + + # unset local variables + unset extract_python_exe + unset install_isaaclab_extension shift # past argument ;; -c|--conda) @@ -283,7 +321,7 @@ while [[ $# -gt 0 ]]; do fi # run the formatter over the repository # check if pre-commit is installed - if ! command -v pre-commit &>/dev/null; then + if [ ! command -v pre-commit &>/dev/null ]; then echo "[INFO] Installing pre-commit..." pip install pre-commit fi diff --git a/source/extensions/omni.isaac.lab/config/extension.toml b/source/extensions/omni.isaac.lab/config/extension.toml index 1fbefd0073..1843985841 100644 --- a/source/extensions/omni.isaac.lab/config/extension.toml +++ b/source/extensions/omni.isaac.lab/config/extension.toml @@ -1,7 +1,7 @@ [package] # Note: Semantic Versioning is used: https://semver.org/ -version = "0.19.1" +version = "0.19.2" # Description title = "Isaac Lab framework for Robot Learning" diff --git a/source/extensions/omni.isaac.lab/docs/CHANGELOG.rst b/source/extensions/omni.isaac.lab/docs/CHANGELOG.rst index b2931ffd23..2b04c39758 100644 --- a/source/extensions/omni.isaac.lab/docs/CHANGELOG.rst +++ b/source/extensions/omni.isaac.lab/docs/CHANGELOG.rst @@ -1,6 +1,15 @@ Changelog --------- +0.19.2 (2024-07-05) +~~~~~~~~~~~~~~~~~~~ + +Changed +^^^^^^^ + +* Modified cloning scheme based on the attribute :attr:`~omni.isaac.lab.scene.InteractiveSceneCfg.replicate_physics` to determine whether environment is homogeneous or heterogeneous. + + 0.19.1 (2024-07-05) ~~~~~~~~~~~~~~~~~~~ diff --git a/source/extensions/omni.isaac.lab/omni/isaac/lab/scene/interactive_scene.py b/source/extensions/omni.isaac.lab/omni/isaac/lab/scene/interactive_scene.py index 2242f94741..60795f8747 100644 --- a/source/extensions/omni.isaac.lab/omni/isaac/lab/scene/interactive_scene.py +++ b/source/extensions/omni.isaac.lab/omni/isaac/lab/scene/interactive_scene.py @@ -30,6 +30,22 @@ class InteractiveScene: Based on the specified number of environments, it clones the entities and groups them into different categories (e.g., articulations, sensors, etc.). + Cloning can be performed in two ways: + + * For tasks where all environments contain the same assets, a more performant cloning paradigm + can be used to allow for faster environment creation. This is specified by the ``replicate_physics`` flag. + + .. code-block:: python + + scene = InteractiveScene(cfg=InteractiveSceneCfg(replicate_physics=True)) + + * For tasks that require having separate assets in the environments, ``replicate_physics`` would have to + be set to False, which will add some costs to the overall startup time. + + .. code-block:: python + + scene = InteractiveScene(cfg=InteractiveSceneCfg(replicate_physics=False)) + Each entity is registered to scene based on its name in the configuration class. For example, if the user specifies a robot in the configuration class as follows: @@ -59,6 +75,14 @@ class MySceneCfg(InteractiveSceneCfg): # access the robot based on its type robot = scene.articulations["robot"] + If the :class:`InteractiveSceneCfg` class does not include asset entities, the cloning process + can still be triggered if assets were added to the stage outside of the :class:`InteractiveScene` class: + + .. code-block:: python + + scene = InteractiveScene(cfg=InteractiveSceneCfg(num_envs=128, replicate_physics=True)) + scene.clone_environments() + .. note:: It is important to note that the scene only performs common operations on the entities. For example, resetting the internal buffers, writing the buffers to the simulation and updating the buffers from the @@ -92,18 +116,29 @@ def __init__(self, cfg: InteractiveSceneCfg): self.env_prim_paths = self.cloner.generate_paths(f"{self.env_ns}/env", self.cfg.num_envs) # create source prim self.stage.DefinePrim(self.env_prim_paths[0], "Xform") - # clone the env xform - env_origins = self.cloner.clone( - source_prim_path=self.env_prim_paths[0], - prim_paths=self.env_prim_paths, - replicate_physics=False, - copy_from_source=True, - ) - self._default_env_origins = torch.tensor(env_origins, device=self.device, dtype=torch.float32) + + # when replicate_physics=False, we assume heterogeneous environments and clone the xforms first. + # this triggers per-object level cloning in the spawner. + if not self.cfg.replicate_physics: + # clone the env xform + env_origins = self.cloner.clone( + source_prim_path=self.env_prim_paths[0], + prim_paths=self.env_prim_paths, + replicate_physics=False, + copy_from_source=True, + ) + self._default_env_origins = torch.tensor(env_origins, device=self.device, dtype=torch.float32) + else: + # otherwise, environment origins will be initialized during cloning at the end of environment creation + self._default_env_origins = None + self._global_prim_paths = list() if self._is_scene_setup_from_cfg(): # add entities from config self._add_entities_from_cfg() + # clone environments on a global scope if environment is homogeneous + if self.cfg.replicate_physics: + self.clone_environments(copy_from_source=False) # replicate physics if we have more than one environment # this is done to make scene initialization faster at play time if self.cfg.replicate_physics and self.cfg.num_envs > 1: @@ -128,31 +163,47 @@ def clone_environments(self, copy_from_source: bool = False): If True, clones are independent copies of the source prim and won't reflect its changes (start-up time may increase). Defaults to False. """ - self.cloner.clone( + env_origins = self.cloner.clone( source_prim_path=self.env_prim_paths[0], prim_paths=self.env_prim_paths, replicate_physics=self.cfg.replicate_physics, copy_from_source=copy_from_source, ) - def filter_collisions(self, global_prim_paths: list[str] = []): + # in case of heterogeneous cloning, the env origins is specified at init + if self._default_env_origins is None: + self._default_env_origins = torch.tensor(env_origins, device=self.device, dtype=torch.float32) + + def filter_collisions(self, global_prim_paths: list[str] | None = None): """Filter environments collisions. Disables collisions between the environments in ``/World/envs/env_.*`` and enables collisions with the prims in global prim paths (e.g. ground plane). Args: - global_prim_paths: The global prim paths to enable collisions with. + global_prim_paths: A list of global prim paths to enable collisions with. + Defaults to None, in which case no global prim paths are considered. """ # obtain the current physics scene physics_scene_prim_path = self.physics_scene_path + # validate paths in global prim paths + if global_prim_paths is None: + global_prim_paths = [] + else: + # remove duplicates in paths + global_prim_paths = list(set(global_prim_paths)) + + # set global prim paths list if not previously defined + if len(self._global_prim_paths) < 1: + self._global_prim_paths += global_prim_paths + # filter collisions within each environment instance self.cloner.filter_collisions( physics_scene_prim_path, "/World/collisions", self.env_prim_paths, - global_paths=global_prim_paths, + global_paths=self._global_prim_paths, ) def __str__(self) -> str: diff --git a/source/extensions/omni.isaac.lab/omni/isaac/lab/scene/interactive_scene_cfg.py b/source/extensions/omni.isaac.lab/omni/isaac/lab/scene/interactive_scene_cfg.py index 4a7281bc7c..b4edac41e1 100644 --- a/source/extensions/omni.isaac.lab/omni/isaac/lab/scene/interactive_scene_cfg.py +++ b/source/extensions/omni.isaac.lab/omni/isaac/lab/scene/interactive_scene_cfg.py @@ -85,4 +85,15 @@ class MySceneCfg(InteractiveSceneCfg): """ replicate_physics: bool = True - """Enable/disable replication of physics schemas when using the Cloner APIs. Default is True.""" + """Enable/disable replication of physics schemas when using the Cloner APIs. Default is True. + + If True, the simulation will have the same asset instances (USD prims) in all the cloned environments. + Internally, this ensures optimization in setting up the scene and parsing it via the physics stage parser. + + If False, the simulation allows having separate asset instances (USD prims) in each environment. + This flexibility comes at a cost of slowdowns in setting up and parsing the scene. + + .. note:: + Optimized parsing of certain prim types (such as deformable objects) is not currently supported + by the physics engine. In these cases, this flag needs to be set to False. + """ diff --git a/source/extensions/omni.isaac.lab_assets/test/test_valid_configs.py b/source/extensions/omni.isaac.lab_assets/test/test_valid_configs.py index 882a0fac0d..a5aca1fd20 100644 --- a/source/extensions/omni.isaac.lab_assets/test/test_valid_configs.py +++ b/source/extensions/omni.isaac.lab_assets/test/test_valid_configs.py @@ -22,7 +22,6 @@ import omni.isaac.lab_assets as lab_assets # noqa: F401 from omni.isaac.lab.assets import AssetBase, AssetBaseCfg -from omni.isaac.lab.sensors import SensorBase, SensorBaseCfg from omni.isaac.lab.sim import build_simulation_context @@ -32,12 +31,12 @@ class TestValidEntitiesConfigs(unittest.TestCase): @classmethod def setUpClass(cls): # load all registered entities configurations from the module - cls.registered_entities: dict[str, AssetBaseCfg | SensorBaseCfg] = {} + cls.registered_entities: dict[str, AssetBaseCfg] = {} # inspect all classes from the module for obj_name in dir(lab_assets): obj = getattr(lab_assets, obj_name) # store all registered entities configurations - if isinstance(obj, (AssetBaseCfg, SensorBaseCfg)): + if isinstance(obj, AssetBaseCfg): cls.registered_entities[obj_name] = obj # print all existing entities names print(">>> All registered entities:", list(cls.registered_entities.keys())) @@ -58,7 +57,7 @@ def test_asset_configs(self): # name the prim path entity_cfg.prim_path = "/World/asset" # create the asset / sensors - entity: AssetBase | SensorBase = entity_cfg.class_type(entity_cfg) # type: ignore + entity: AssetBase = entity_cfg.class_type(entity_cfg) # type: ignore # play the sim sim.reset()