isaac-lab-install
更新时间:2026-06-22
你可以将以下代码以如下形式放到您的 agent 目录中,即可通过/isaac-sim-install + 参数 的形式调用该 Skill。
Plain Text
1.claude/skills/<install-skill>/
2├── SKILL.md
3└── scripts/
4 └── install_isaac_lab.sh
SKILL.md:
Plain Text
1---
2name: isaac-lab-install
3description: >
4 在已有 Isaac Sim Python 上用内置、固定 recipe 安装 Isaac Lab。支持本机或 SSH 远端、临时代理和可选冒烟测试;
5 不安装或重装 Isaac Sim。默认使用 /root/workspace/env_isaacsim/bin/python。
6argument-hint: [local|ssh <ssh-target>] [--profile lab-3.0|lab-main|lab-2.3] [--install-root /root/workspace] [--sim-python <path>|--venv <path>] [--proxy <url>|--no-proxy] [--run-mode wait|background|schedule-check] [--smoke-test]
7disable-model-invocation: true
8allowed-tools: Read, Bash, AskUserQuestion, CronCreate
9---
10
11# Isaac Lab 安装 Skill
12
13你是 Isaac Lab 环境安装工程师。这个 skill 只在已有 Isaac Sim Python 上用内置、固定 recipe 安装 Isaac Lab;不安装、不重装 Isaac Sim。没有 recipe 的 Lab 版本不能自动安装,也不能现场猜 branch、commit 或安装命令。
14
15## 使用边界
16
17- 只安装 Isaac Lab;不调用 Isaac Sim 安装脚本。
18- 必须依赖已有 Isaac Sim Python,默认是 `<install-root>/env_isaacsim/bin/python`。
19- 找不到 Isaac Sim Python 时停止,让用户先运行 `isaac-sim-install` 或显式传 `--sim-python` / `--venv`。
20- 安装逻辑固定在 `scripts/install_isaac_lab.sh`,通过 `--profile` 选择 recipe。
21- 支持本机和 SSH 远端;参数以 `ssh ...` 开头时,所有检查和安装都在远端执行。
22- 代理只临时用于 git/pip 下载;不要写入 shell 配置、安装记录或仓库文件。
23- 默认安装根目录是 `/root/workspace`,但交互流程必须向用户确认。
24- 成功且验证通过后,远端过程目录 `<install-root>/isaac-lab-install-skill` 必须删除。
25
26## 内置 Recipe
27
28| profile | Isaac Lab ref | commit | 期望 Sim | Python | 用途 |
29| --- | --- | --- | --- | --- | --- |
30| `lab-3.0` | `release/3.0.0-beta2` | `a8554968f604e54e4d0862c5922ed0f9b49aaa92` | Sim 6 | `3.12` | 默认推荐 |
31| `lab-main` | `main` | `f58361c8f1ea3380ded6ddfde029c40b0e7203ca` | Sim 6 | `3.12` | 实验组合;不要作为默认推荐 |
32| `lab-2.3` | `release/2.3.0` | `5c2ec81cb17532d32f7922dd7fcaae40d123b71a` | Sim 5 | `3.11` | 兼容 Sim 5.1 线 |
33
34脚本仍接受旧组合 alias,例如 `sim-6.0.0+lab-3.0`、`sim-6.0.0+lab-main`、`sim-5.1.0+lab-2.3`,但新调用优先使用 Lab-only profile。
35
36如果用户要求未列出的版本,例如 `lab-3.1` 或未来 `lab-4.0`,先进入 recipe 扩展流程:查询官方 IsaacLab repo release/tag/branch 和精确 commit、官方 Sim 兼容信息、Python 要求、PyTorch/CUDA pins、`source/` package layout,以及是否会拉偏 Sim 依赖;生成候选 `normalize_profile()` alias 和 `recipe_lab()` 分支后,先运行 `bash -n` 和 `--dry-run`,向用户说明来源、缺口和候选 recipe,得到确认后才写入脚本并允许安装。`lab-main` 也必须固定 commit;更新 main 属于 recipe 更新,不是无钉安装。
37
38## 环境约束
39
40这些约束是安装前预检和最终风险说明的来源,不用于现场改 recipe:
41
42- Isaac Lab 必须复用已有 Isaac Sim Python;不能自动补装 Isaac Sim。
43- Python 版本严格跟随 Lab recipe;不能用系统默认 Python 代替不匹配的小版本。
44- 已安装的 `isaacsim` major 必须和 Lab recipe 的期望 Sim major 对照;不匹配时报告风险。
45- 安装默认使用已有 venv `<install-root>/env_isaacsim`,不要装进系统 Python。
46- Isaac Lab 通过 editable 子包安装,不安装仓库根 `pyproject.toml`,避免它临时改写 Sim 依赖。
47- 安装 Lab 后必须恢复 recipe 中需要保护的 Sim pins;Sim 6 当前恢复 `coverage==7.4.4`、`numpy==2.3.1`、`Pillow==12.1.1`、`psutil==5.9.8`、`packaging==26.0`。
48- `--smoke-test` 必须设置 `OMNI_KIT_ACCEPT_EULA=YES` 和 `OMNI_KIT_ALLOW_ROOT=1`,优先运行 `<install-root>/IsaacLab/scripts/environments/list_envs.py`。
49- 如果 import/smoke test 通过但 `pip check` 或日志有 dependency conflict,最终报告要说明“基础运行可用,但依赖元数据不一致”。
50
51## 安装前决策
52
53用户调用示例:
54
55```text
56/isaac-lab-install ssh -p <port> <user>@<host> --profile lab-3.0 --sim-python /root/workspace/env_isaacsim/bin/python --proxy http://<proxy-host>:<proxy-port> --run-mode wait --smoke-test
57```
58
59参数和交互规则:
60
611. 目标:参数以 `ssh` 开头时,把后续 SSH 参数保存为远端命令前缀;没有 `ssh` 或参数是 `local` 时,在本机执行。
622. 目录:`--install-root` 默认 `/root/workspace`;用户未显式传入时必须确认默认目录是否合适,或让用户用 Other 输入已有/挂载目录。
633. Sim Python:默认 `<install-root>/env_isaacsim/bin/python`;已有 Sim 不在默认位置时,必须让用户传 `--sim-python` 或 `--venv`。
644. 代理:`--proxy <url>` 直接传给脚本;`--no-proxy` 只表示用户选择直连,脚本不接收该参数。
655. 运行方式:`--run-mode wait` 持续追踪到成功/失败;`background` 只启动后台任务并返回日志/PID;`schedule-check` 启动后台任务并设置本会话定时检查。
666. 版本:`--profile` 默认 `lab-3.0`;`lab-main` 是实验组合,不作为默认推荐。
677. 冒烟测试:`--smoke-test` 启用 Lab import 和官方 headless 示例验证。
688. 禁用参数:不支持 `--component`;这个 skill 永远只装 Lab。
69
70只有用户显式给全目标、profile、proxy/no-proxy、run-mode 后,才可以跳过交互直接安装。用户只给 SSH 目标或只确认 host key 时,不要自动开始安装。不允许自动运行 `isaac-sim-install`;缺少 Sim 时停止并说明下一步。
71
72## 交互顺序
73
74一次交互最多问 1–4 个问题;远端首次连接可能需要 host key 信任时,把它合并进安装配置问题。
75
761. 目标和 host key:装本机还是远端;首次 SSH host key 是否信任。信任 host key 只表示允许连接,不等于允许开始安装。
772. 安装目录和 Sim Python:默认 `/root/workspace` 与 `/root/workspace/env_isaacsim/bin/python`;不同位置用 Other 输入 `--sim-python` 或 `--venv` 对应路径。
783. 网络代理:默认不假设用户有内网或预置代理。选项包含“不使用代理(直连)”“我已有代理 URL(选 Other 填写)”“不确定,先检测直连”。
794. 运行方式:`wait`、`background`、`schedule-check`。
805. Lab 版本:默认推荐 `lab-3.0`;实验线可选 `lab-main`;旧线可选 `lab-2.3`。
816. 是否启用 `--smoke-test`。
82
83## 安装脚本
84
85```bash
86bash .claude/skills/isaac-lab-install/scripts/install_isaac_lab.sh \
87 --profile lab-3.0 \
88 --install-root /root/workspace \
89 --sim-python /root/workspace/env_isaacsim/bin/python \
90 --proxy http://host:port \
91 --smoke-test
92```
93
94脚本职责:
95
961. 读取 `recipe_lab()` 中的固定分支、commit、Python/PyTorch 版本和 package dirs。
972. 验证已有 Isaac Sim Python、Python 小版本和 `isaacsim` major。
983. 按权限和参数安装或跳过 apt build dependencies。
994. clone 或 checkout `<install-root>/IsaacLab` 到固定 ref/commit。
1005. 安装 recipe 中列出的 Isaac Lab editable 子包。
1016. 恢复 recipe 钉住的 PyTorch 版本和 Sim pins。
1027. 可选运行 import 和官方 headless 示例测试。
1038. 写 `<install-root>/isaac-lab-install.record`。
104
105## 远端执行模板
106
107远端不一定已有本地 skill 脚本;必须先复制固定脚本,再执行。不要用 `cat <<EOF` 临时拼远端脚本。下面模板里的 `<install-root>` 使用用户确认的安装根目录;未显式指定时展开为 `/root/workspace`。
108
109复制脚本并确认 Sim Python:
110
111```bash
112ssh <target> 'mkdir -p <install-root>/isaac-lab-install-skill/scripts <install-root>/isaac-lab-install-skill/logs'
113scp -P <port> .claude/skills/isaac-lab-install/scripts/install_isaac_lab.sh <target>:<install-root>/isaac-lab-install-skill/scripts/
114ssh <target> 'bash -n <install-root>/isaac-lab-install-skill/scripts/install_isaac_lab.sh && test -x <install-root>/env_isaacsim/bin/python'
115```
116
117启动后台安装:
118
119```bash
120ssh <target> 'nohup bash -lc '\''set -o pipefail; START=$(date +%s); echo $START > <install-root>/isaac-lab-install-skill/logs/lab.start; <install-root>/isaac-lab-install-skill/scripts/install_isaac_lab.sh --profile lab-3.0 --install-root <install-root> --sim-python <install-root>/env_isaacsim/bin/python --smoke-test > <install-root>/isaac-lab-install-skill/logs/lab.log 2>&1; STATUS=$?; END=$(date +%s); echo $STATUS > <install-root>/isaac-lab-install-skill/logs/lab.status; echo $END > <install-root>/isaac-lab-install-skill/logs/lab.end; exit $STATUS'\'' ><install-root>/isaac-lab-install-skill/logs/lab.nohup 2>&1 & echo $! > <install-root>/isaac-lab-install-skill/logs/lab.pid'
121```
122
123检查状态:
124
125```bash
126ssh <target> 'cat <install-root>/isaac-lab-install-skill/logs/lab.status 2>/dev/null || echo running; tail -n 80 <install-root>/isaac-lab-install-skill/logs/lab.log'
127```
128
129成功并验证通过后清理:
130
131```bash
132ssh <target> 'rm -rf <install-root>/isaac-lab-install-skill'
133```
134
135只删除过程目录;不能删除 `<install-root>/env_isaacsim`、`<install-root>/IsaacLab`、`<install-root>/isaac-lab-install.record`、Isaac Sim 文件、用户数据或挂载资产。
136
137## 成功判定
138
139不能只看脚本退出码。最终成功必须同时满足:
140
141- 前台执行时脚本退出码为 `0`;远端后台执行时 `<install-root>/isaac-lab-install-skill/logs/lab.status` 为 `0`。
142- `<install-root>/isaac-lab-install.record` 存在且字段完整。
143- `<install-root>/env_isaacsim/bin/python` 可执行,且 `isaacsim` 仍可导入。
144- `<install-root>/IsaacLab` 存在,且 repo ref/commit 符合 recipe。
145- Python 能导入 `isaaclab`;启用 `--smoke-test` 时,官方 headless 示例通过。
146- `<install-root>/IsaacLab/isaaclab.sh -p` 可作为 Lab 入口;验证时要显式设置 `VIRTUAL_ENV=<install-root>/env_isaacsim` 或清理抢占的 `CONDA_PREFIX`,避免入口误用当前 shell 的 conda Python。
147- 有安装日志时,日志没有 `Traceback`、`ImportError`、`ModuleNotFoundError`、extension startup failure、pip resolver failure 或安装失败信号。
148- `python -m pip check` 结果必须检查;如有 dependency conflict,报告为风险,不能声称环境完全干净。
149
150短验证命令模板:
151
152```bash
153<install-root>/env_isaacsim/bin/python - <<'PY'
154import importlib.metadata as metadata
155import isaacsim
156import isaaclab
157print('isaacsim', metadata.version('isaacsim'))
158print('isaaclab-import-ok')
159PY
160<install-root>/env_isaacsim/bin/python -m pip check
161```
162
163启用 smoke test 时额外验证:
164
165```bash
166OMNI_KIT_ACCEPT_EULA=YES OMNI_KIT_ALLOW_ROOT=1 timeout 180 \
167 <install-root>/env_isaacsim/bin/python <install-root>/IsaacLab/scripts/environments/list_envs.py
168```
169
170远端后台安装时额外检查日志风险信号:
171
172```bash
173grep -Ein '(Traceback|ImportError|ModuleNotFoundError|ResolutionImpossible|dependency conflict|failed building|Could not install|No matching distribution|subprocess-exited-with-error|extension startup)' <install-root>/isaac-lab-install-skill/logs/lab.log || true
174```
175
176## 平台快速开始适配
177
178- `/isaac-sim/python.sh <script.py>` 通常由 `isaac-sim-install` 创建,内部执行 `<install-root>/env_isaacsim/bin/python <script.py>`。
179- 安装 Isaac Lab 后,可用 `VIRTUAL_ENV=<install-root>/env_isaacsim <install-root>/IsaacLab/isaaclab.sh -p <script.py>`;如果当前 shell 有 `CONDA_PREFIX`,先清理或显式设置 `VIRTUAL_ENV`。
180- `~/workspace/quick_start` 是平台样例目录,不是 recipe 自动创建目录;缺失时让用户提供样例脚本,或从已安装的 Isaac Lab 示例中选择替代脚本。
181- `/mnt/bos/isaac-sim` 属于平台资产挂载;缺失时报资产挂载问题,而不是 Lab 安装入口问题。
182
183## 扩展新版本
184
185新增 Isaac Lab 版本时,必须先生成并审查固定 recipe,再改 `scripts/install_isaac_lab.sh`:
186
187- 在 `normalize_profile()` 中添加 profile alias,例如 `lab-3.1`、`isaaclab-3.1`。
188- 在 `recipe_lab()` 中添加 canonical `LAB_PROFILE` 和精确 `LAB_VERSION`。
189- 固定 Isaac Lab repo、branch/tag 和 commit;不能只跟随 branch head。
190- 从官方兼容信息确认期望 Isaac Sim major 或具体 Sim 线。
191- 从官方要求确认 Python 版本。
192- 固定 PyTorch 三件套和 index,不能只写宽松范围。
193- 检查 `source/` 下 editable package dirs,不能默认沿用旧列表。
194- 检查该 Lab 版本是否会拉偏 Sim 依赖;需要时添加对应 `SIM_PIN_PACKAGES`。
195
196扩展后先跑:
197
198```bash
199bash scripts/install_isaac_lab.sh --profile <new-profile> --sim-python /root/workspace/env_isaacsim/bin/python --dry-run
200bash -n scripts/install_isaac_lab.sh
201```
202
203`--dry-run` 必须只展示 recipe、路径、package dirs、pins、命令和 smoke-test 计划,不创建文件、不 clone、不安装包、不写 record、不创建 smoke 脚本。dry-run 不证明目标 Sim Python 和 runtime 可用,除非在目标机器上用真实路径单独验证。
204
205## 最终输出要求
206
207最终只输出有效安装记录,不输出大段日志:
208
209- 目标机器。
210- Lab profile。
211- 安装根目录,以及是否使用用户确认的目录或默认 `/root/workspace`。
212- 使用的 Isaac Sim Python 路径。
213- 检测到的 Isaac Sim 版本,或版本检查警告。
214- Isaac Lab repo、ref、commit、安装路径。
215- editable package dirs。
216- 是否恢复 PyTorch pins 和 Sim pins。
217- `<install-root>/IsaacLab/isaaclab.sh -p` 是否可作为入口。
218- 使用的脚本命令摘要。
219- 安装脚本完成状态。
220- 冒烟测试结果,或跳过原因。
221- 验证结果;必须包含日志风险扫描和 `pip check` 结果。
222- 远端过程目录清理结果;成功并验证通过后应已删除。
223- 如果有 OS/driver 警告或依赖冲突,单独列为“风险”,并明确是否影响已执行的 smoke test。
224
225## Skill 测试报告要求
226
227当用户要求“测试这个 skill”时,最终报告必须包含:
228
229- 测试目标、目标机器、profile。
230- 起止时间和每个阶段耗时。
231- 实际执行的脚本路径和命令摘要。
232- 成功项、失败项、远端日志位置。
233- 失败原因判断:环境问题、网络/SSH 问题、recipe 问题或脚本问题。
234- 已做的 skill 迭代,以及仍需用户或环境侧处理的事项。
install_isaac_lab.sh:
Plain Text
1#!/usr/bin/env bash
2set -euo pipefail
3
4PROFILE="lab-3.0"
5INSTALL_ROOT="/root/workspace"
6VENV_PATH=""
7SIM_PYTHON=""
8PROXY_URL=""
9DRY_RUN=0
10INSTALL_SYSTEM_DEPS=1
11APT_USE_PROXY=0
12SMOKE_TEST=0
13FORCE=0
14PIP_FLAGS=(--progress-bar off --no-input)
15SIM_PIN_PACKAGES=()
16DETECTED_SIM_VERSION=""
17export DEBIAN_FRONTEND=noninteractive
18
19usage() {
20 cat <<'USAGE'
21Install Isaac Lab from a pinned recipe using an existing Isaac Sim Python.
22
23Usage:
24 install_isaac_lab.sh [options]
25
26Recipe:
27 --profile <name> Recipe name: lab-3.0, lab-main, lab-2.3. Combined aliases are accepted for compatibility.
28 --sim-python <path> Python executable from an Isaac Sim install. Overrides --venv.
29 --venv <path> Existing Isaac Sim virtualenv. Default: <install-root>/env_isaacsim
30
31Install location:
32 --install-root <path> Install root directory. Default: /root/workspace
33
34Network and system deps:
35 --proxy <url> Temporary proxy for git/pip downloads only.
36 --skip-system-deps Do not install apt build dependencies.
37 --apt-use-proxy Let apt inherit --proxy. Default: apt runs without that proxy.
38
39Execution:
40 --smoke-test Run import and minimal headless startup checks.
41 --force Re-checkout recipe branch in existing IsaacLab repo.
42 --dry-run Print commands without executing.
43 --help Show this help.
44
45Add a new Isaac Lab version by adding one branch in recipe_lab().
46USAGE
47}
48
49log() { printf '[LAB] %s\n' "$*"; }
50warn() { printf '[LAB][WARN] %s\n' "$*" >&2; }
51die() { printf '[LAB][ERROR] %s\n' "$*" >&2; exit 1; }
52
53supported_profiles() {
54 printf 'lab-3.0, lab-main, lab-2.3'
55}
56
57normalize_profile() {
58 local profile="$1"
59 profile="$(printf '%s' "$profile" | tr '[:upper:]' '[:lower:]')"
60 case "$profile" in
61 lab-3.0|lab-3.0.0|lab-3.0.0-beta2|isaaclab-3.0|isaaclab-3.0.0|sim-6.0.0+lab-3.0|arena-0.2)
62 printf 'lab-3.0'
63 ;;
64 lab-main|isaaclab-main|sim-6.0.0+lab-main)
65 printf 'lab-main'
66 ;;
67 lab-2.3|lab-2.3.0|isaaclab-2.3|isaaclab-2.3.0|sim-5.1.0+lab-2.3|arena-0.1)
68 printf 'lab-2.3'
69 ;;
70 lab-[0-9]*|isaaclab-[0-9]*)
71 printf '%s' "$profile"
72 ;;
73 *)
74 printf '%s' "$profile"
75 ;;
76 esac
77}
78
79run() {
80 if [[ "$DRY_RUN" == "1" ]]; then
81 printf '+ '
82 printf '%q ' "$@"
83 printf '\n'
84 else
85 "$@"
86 fi
87}
88
89run_bash() {
90 if [[ "$DRY_RUN" == "1" ]]; then
91 printf '+ bash -lc %q\n' "$1"
92 else
93 bash -lc "$1"
94 fi
95}
96
97recipe_lab() {
98 REQUESTED_PROFILE="$1"
99 NORMALIZED_PROFILE="$(normalize_profile "$REQUESTED_PROFILE")"
100
101 case "$NORMALIZED_PROFILE" in
102 lab-3.0)
103 LAB_PROFILE="lab-3.0"
104 LAB_VERSION="3.0.0-beta2"
105 EXPECTED_SIM_MAJOR="6"
106 REPO_URL="https://github.com/isaac-sim/IsaacLab.git"
107 REF_KIND="branch"
108 REF_NAME="release/3.0.0-beta2"
109 REF_COMMIT="a8554968f604e54e4d0862c5922ed0f9b49aaa92"
110 PYTHON_REQUIRED="3.12"
111 TORCH_VERSION="2.11.0"
112 TORCHVISION_VERSION="0.26.0"
113 TORCHAUDIO_VERSION="2.11.0"
114 PYTORCH_INDEX="https://download.pytorch.org/whl/cu128"
115 SIM_PIN_PACKAGES=(
116 "coverage==7.4.4"
117 "numpy==2.3.1"
118 "Pillow==12.1.1"
119 "psutil==5.9.8"
120 "packaging==26.0"
121 )
122 PACKAGE_DIRS=(
123 source/isaaclab
124 source/isaaclab_assets
125 source/isaaclab_rl
126 source/isaaclab_tasks
127 source/isaaclab_mimic
128 )
129 ;;
130 lab-main)
131 LAB_PROFILE="lab-main"
132 LAB_VERSION="main"
133 EXPECTED_SIM_MAJOR="6"
134 REPO_URL="https://github.com/isaac-sim/IsaacLab.git"
135 REF_KIND="branch"
136 REF_NAME="main"
137 REF_COMMIT="f58361c8f1ea3380ded6ddfde029c40b0e7203ca"
138 PYTHON_REQUIRED="3.12"
139 TORCH_VERSION="2.11.0"
140 TORCHVISION_VERSION="0.26.0"
141 TORCHAUDIO_VERSION="2.11.0"
142 PYTORCH_INDEX="https://download.pytorch.org/whl/cu128"
143 SIM_PIN_PACKAGES=(
144 "coverage==7.4.4"
145 "numpy==2.3.1"
146 "Pillow==12.1.1"
147 "psutil==5.9.8"
148 "packaging==26.0"
149 )
150 PACKAGE_DIRS=(
151 source/isaaclab
152 source/isaaclab_assets
153 source/isaaclab_rl
154 source/isaaclab_tasks
155 source/isaaclab_mimic
156 )
157 ;;
158 lab-2.3)
159 LAB_PROFILE="lab-2.3"
160 LAB_VERSION="2.3.0"
161 EXPECTED_SIM_MAJOR="5"
162 REPO_URL="https://github.com/isaac-sim/IsaacLab.git"
163 REF_KIND="branch"
164 REF_NAME="release/2.3.0"
165 REF_COMMIT="5c2ec81cb17532d32f7922dd7fcaae40d123b71a"
166 PYTHON_REQUIRED="3.11"
167 TORCH_VERSION="2.7.0"
168 TORCHVISION_VERSION="0.22.0"
169 TORCHAUDIO_VERSION="2.7.0"
170 PYTORCH_INDEX="https://download.pytorch.org/whl/cu128"
171 PACKAGE_DIRS=(
172 source/isaaclab
173 source/isaaclab_assets
174 source/isaaclab_rl
175 source/isaaclab_tasks
176 )
177 ;;
178 *)
179 die "No pinned Isaac Lab recipe for '$REQUESTED_PROFILE' (normalized: '$NORMALIZED_PROFILE'). Supported profiles: $(supported_profiles). Add a recipe_lab() branch before installing this version."
180 ;;
181 esac
182}
183
184parse_args() {
185 while [[ $# -gt 0 ]]; do
186 case "$1" in
187 --profile) PROFILE="$2"; shift 2 ;;
188 --install-root) INSTALL_ROOT="$2"; shift 2 ;;
189 --venv) VENV_PATH="$2"; shift 2 ;;
190 --sim-python) SIM_PYTHON="$2"; shift 2 ;;
191 --proxy) PROXY_URL="$2"; shift 2 ;;
192 --skip-system-deps) INSTALL_SYSTEM_DEPS=0; shift ;;
193 --apt-use-proxy) APT_USE_PROXY=1; shift ;;
194 --smoke-test) SMOKE_TEST=1; shift ;;
195 --force) FORCE=1; shift ;;
196 --dry-run) DRY_RUN=1; shift ;;
197 --help|-h) usage; exit 0 ;;
198 *) die "Unknown argument: $1" ;;
199 esac
200 done
201}
202
203apply_proxy() {
204 if [[ -n "$PROXY_URL" ]]; then
205 export http_proxy="$PROXY_URL" https_proxy="$PROXY_URL" HTTP_PROXY="$PROXY_URL" HTTPS_PROXY="$PROXY_URL"
206 fi
207}
208
209resolve_python() {
210 if [[ -n "$SIM_PYTHON" ]]; then
211 if [[ "$DRY_RUN" != "1" ]]; then
212 [[ -x "$SIM_PYTHON" ]] || die "Isaac Sim Python is not executable: $SIM_PYTHON"
213 fi
214 return
215 fi
216
217 if [[ -z "$VENV_PATH" ]]; then
218 VENV_PATH="${INSTALL_ROOT%/}/env_isaacsim"
219 fi
220 SIM_PYTHON="${VENV_PATH%/}/bin/python"
221 if [[ "$DRY_RUN" != "1" ]]; then
222 [[ -x "$SIM_PYTHON" ]] || die "Isaac Sim Python not found: ${SIM_PYTHON}. Run install_isaac_sim.sh first or pass --sim-python."
223 fi
224}
225
226check_python() {
227 [[ "$DRY_RUN" == "1" ]] && return 0
228 local actual
229 actual="$($SIM_PYTHON - <<'PY'
230import sys
231print(f"{sys.version_info.major}.{sys.version_info.minor}")
232PY
233)"
234 [[ "$actual" == "$PYTHON_REQUIRED" ]] || die "Profile ${LAB_PROFILE} requires Python ${PYTHON_REQUIRED}, got ${actual} from ${SIM_PYTHON}."
235}
236
237check_isaac_sim() {
238 [[ "$DRY_RUN" == "1" ]] && return 0
239 DETECTED_SIM_VERSION="$($SIM_PYTHON -m pip show isaacsim 2>/dev/null | awk '/^Version:/{print $2}')"
240 [[ -n "$DETECTED_SIM_VERSION" ]] || die "isaacsim is not installed in ${SIM_PYTHON}."
241 if [[ "$DETECTED_SIM_VERSION" != ${EXPECTED_SIM_MAJOR}.* ]]; then
242 warn "Isaac Sim ${DETECTED_SIM_VERSION} may not match ${LAB_PROFILE}, expected major ${EXPECTED_SIM_MAJOR}."
243 fi
244}
245
246install_system_deps() {
247 [[ "$INSTALL_SYSTEM_DEPS" == "1" ]] || return 0
248
249 local apt_prefix="env -u http_proxy -u https_proxy -u HTTP_PROXY -u HTTPS_PROXY"
250 [[ "$APT_USE_PROXY" == "1" ]] && apt_prefix="env"
251
252 if [[ "$DRY_RUN" == "1" ]]; then
253 run_bash "$apt_prefix apt-get update"
254 run_bash "$apt_prefix apt-get install -y git cmake build-essential"
255 return 0
256 fi
257
258 if [[ "$(id -u)" != "0" ]]; then
259 warn "Not root; skipping apt build dependencies."
260 return 0
261 fi
262
263 run_bash "$apt_prefix apt-get update"
264 run_bash "$apt_prefix apt-get install -y git cmake build-essential"
265}
266
267checkout_repo() {
268 LAB_DIR="${INSTALL_ROOT%/}/IsaacLab"
269 if [[ ! -d "$LAB_DIR/.git" ]]; then
270 run git clone --branch "$REF_NAME" "$REPO_URL" "$LAB_DIR"
271 else
272 run git -C "$LAB_DIR" fetch origin "$REF_NAME"
273 if [[ "$FORCE" == "1" ]]; then
274 run git -C "$LAB_DIR" checkout -f "$REF_NAME"
275 else
276 run git -C "$LAB_DIR" checkout "$REF_NAME"
277 fi
278 fi
279
280 if [[ -n "$REF_COMMIT" ]]; then
281 run git -C "$LAB_DIR" checkout "$REF_COMMIT"
282 fi
283}
284
285install_packages() {
286 run "$SIM_PYTHON" -m pip install "${PIP_FLAGS[@]}" --index-url https://pypi.org/simple wheel toml "setuptools<82.0.0"
287 for package_dir in "${PACKAGE_DIRS[@]}"; do
288 if [[ "$DRY_RUN" != "1" ]]; then
289 [[ -d "$LAB_DIR/$package_dir" ]] || die "Recipe package path missing: $LAB_DIR/$package_dir"
290 fi
291 run "$SIM_PYTHON" -m pip install "${PIP_FLAGS[@]}" --index-url https://pypi.org/simple --extra-index-url https://pypi.nvidia.com --find-links https://py.mujoco.org/ --no-build-isolation --editable "$LAB_DIR/$package_dir"
292 done
293 run "$SIM_PYTHON" -m pip install "${PIP_FLAGS[@]}" "torch==${TORCH_VERSION}" "torchvision==${TORCHVISION_VERSION}" "torchaudio==${TORCHAUDIO_VERSION}" --index-url "$PYTORCH_INDEX"
294}
295
296restore_sim_pins() {
297 [[ "${#SIM_PIN_PACKAGES[@]}" -gt 0 ]] || return 0
298 run "$SIM_PYTHON" -m pip install "${PIP_FLAGS[@]}" --index-url https://pypi.org/simple "${SIM_PIN_PACKAGES[@]}"
299}
300
301print_recipe_summary() {
302 log "Recipe summary: requested=${REQUESTED_PROFILE}, normalized=${NORMALIZED_PROFILE}, profile=${LAB_PROFILE}, lab_version=${LAB_VERSION}."
303 log "Isaac Lab source: ${REPO_URL} ${REF_KIND}:${REF_NAME} commit=${REF_COMMIT}."
304 log "Expected Isaac Sim major: ${EXPECTED_SIM_MAJOR}; required Python: ${PYTHON_REQUIRED}."
305 log "PyTorch pins: torch=${TORCH_VERSION}, torchvision=${TORCHVISION_VERSION}, torchaudio=${TORCHAUDIO_VERSION}, index=${PYTORCH_INDEX}."
306 log "Install root: ${INSTALL_ROOT}; Lab path: ${INSTALL_ROOT%/}/IsaacLab; Sim Python: ${SIM_PYTHON}."
307 log "Editable package dirs: ${PACKAGE_DIRS[*]}."
308 if [[ "${#SIM_PIN_PACKAGES[@]}" -gt 0 ]]; then
309 log "Sim pins to restore: ${SIM_PIN_PACKAGES[*]}."
310 else
311 log "Sim pins to restore: none."
312 fi
313 if [[ "$SMOKE_TEST" == "1" ]]; then
314 log "Smoke test: enabled."
315 else
316 log "Smoke test: disabled."
317 fi
318 if [[ "$DRY_RUN" == "1" ]]; then
319 log "Dry-run skips real Sim Python, isaacsim package, and runtime validation."
320 fi
321}
322
323smoke_test() {
324 [[ "$SMOKE_TEST" == "1" ]] || return 0
325 run env OMNI_KIT_ACCEPT_EULA=YES OMNI_KIT_ALLOW_ROOT=1 "$SIM_PYTHON" - <<'PY'
326import isaaclab
327print("ISAAC_LAB_IMPORT_OK")
328PY
329
330 local smoke_script
331 smoke_script="${LAB_DIR}/scripts/environments/list_envs.py"
332 if [[ "$DRY_RUN" == "1" ]]; then
333 log "Would run official Isaac Lab smoke test ${smoke_script}."
334 return 0
335 fi
336 [[ -f "$smoke_script" ]] || die "Official smoke test script not found: $smoke_script"
337
338 OMNI_KIT_ACCEPT_EULA=YES OMNI_KIT_ALLOW_ROOT=1 timeout 180 "$SIM_PYTHON" "$smoke_script"
339}
340
341write_record() {
342 local record_path="$INSTALL_ROOT/isaac-lab-install.record"
343 if [[ "$DRY_RUN" == "1" ]]; then
344 log "Would write install record to ${record_path}"
345 return
346 fi
347 cat > "$record_path" <<EOF
348component=isaac-lab
349profile=${LAB_PROFILE}
350lab_version=${LAB_VERSION}
351expected_sim_major=${EXPECTED_SIM_MAJOR}
352detected_sim_version=${DETECTED_SIM_VERSION}
353repo=${REPO_URL}
354ref_kind=${REF_KIND}
355ref_name=${REF_NAME}
356ref_commit=${REF_COMMIT}
357path=${LAB_DIR}
358python=${SIM_PYTHON}
359torch=${TORCH_VERSION}
360torchvision=${TORCHVISION_VERSION}
361torchaudio=${TORCHAUDIO_VERSION}
362pytorch_index=${PYTORCH_INDEX}
363packages=${PACKAGE_DIRS[*]}
364sim_pin_packages=${SIM_PIN_PACKAGES[*]}
365EOF
366}
367
368main() {
369 parse_args "$@"
370 recipe_lab "$PROFILE"
371 apply_proxy
372 resolve_python
373 check_python
374 check_isaac_sim
375 print_recipe_summary
376 install_system_deps
377 run mkdir -p "$INSTALL_ROOT"
378 checkout_repo
379 install_packages
380 restore_sim_pins
381 smoke_test
382 write_record
383 if [[ "$DRY_RUN" == "1" ]]; then
384 log "Dry run complete: no filesystem or package changes were made."
385 exit 0
386 fi
387 log "Isaac Lab installed: ${LAB_DIR}"
388}
389
390main "$@"
评价此篇文章
