diff --git a/.vscode/tools/setup_vscode.py b/.vscode/tools/setup_vscode.py index 8156a1a943..7750be6f9f 100644 --- a/.vscode/tools/setup_vscode.py +++ b/.vscode/tools/setup_vscode.py @@ -31,11 +31,11 @@ # 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 +48,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 +99,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 +126,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 +153,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/docker/Dockerfile.pip b/docker/Dockerfile.pip new file mode 100644 index 0000000000..5053638c11 --- /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: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: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/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..f3f27c90ee 100755 --- a/isaaclab.sh +++ b/isaaclab.sh @@ -22,34 +22,78 @@ export ISAACLAB_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && p # Helper functions #== -# 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} +# extract isaac sim path +extract_isaacsim_path() { + # Check if we have pip package installed inside conda environment + if ! [[ -z "${CONDA_PREFIX}" ]]; then + # Use the python executable to get the path + local python_exe=${CONDA_PREFIX}/bin/python + # 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'])") + else + # If package not installed, try with the default path + local isaac_path=${ISAACLAB_PATH}/_isaac_sim + fi + elif command -v python &> /dev/null; then + # note: we need to deal with this case because of docker containers + # Retrieve the path importing isaac sim and getting the environment path + if [ $(python -m pip list | grep -c 'isaacsim-rl') ]; then + local isaac_path=$(python -c "import isaacsim; import os; print(os.environ['ISAAC_PATH'])") + else + # If package not installed, use an empty path for failure + local isaac_path='' + fi else - # Use TeamCity build - build_path=${ISAACLAB_PATH}/_isaac_sim + # Use the sym-link path to Isaac Sim directory + local isaac_path=${ISAACLAB_PATH}/_isaac_sim + 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 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) + elif command -v python &> /dev/null; then + # note: we need to deal with this case because of docker containers + if [ $(python -m pip list | grep -c 'isaacsim-rl') ]; then + local python_exe=$(which python) else - # use python from kit - local python_exe=${build_path}/python.sh + # leave a blank path for failure + local python_exe='' fi + else + # use python from kit + local python_exe=${ISAACLAB_PATH}/_isaac_sim/python.sh 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 + # kit dependencies are built with python 3.10 so any other version will not work + # this is needed in case users have multiple python versions installed and the wrong one is being used + if [ "$(${python_exe} --version | grep -c '3.10')" -eq 0 ]; then + echo "[ERROR] Found Python version: $(${python_exe} --version) while expecting 3.10. Please use the correct python version." >&2 exit 1 fi # return the result @@ -58,21 +102,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 +136,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 +144,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 +157,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 +167,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 +235,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 +282,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 +299,19 @@ 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 (in that case don't setup VSCode) + 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 +338,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