Isaac Sim:使用 HTTP Request (GET/POST) 與場景互動

第一步:下載 isaac-sim Download Isaac Sim — Isaac Sim Documentation,直到可以點選 isaac-sim-standalone@4.5.0-rc.3/isaac-sim.bat(版本可能不同,2025/12/12 當下已有 v.5.0)

.bat

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 下載 isaac-sim-standalone@4.5.0-rc.3 後有預設的 isaac-sim.bat 可以使用
# 解讀 isaac-sim.bat 內的指令
@echo off
setlocal
call "%~dp0kit\kit.exe" "%%~dp0apps/isaacsim.exp.full.kit" --ext-folder "%~dp0/apps" %*

# ------------------------------------------------------------------ #
# "%~dp0kit\kit.exe": 執行 kit.exe,也就是 Omniverse 的核心引擎。
# "%%~dp0apps/isaacsim.exp.full.kit": 告訴 Kit 引擎要啟動哪個應用程式配置。.kit 檔案裡面定義了依賴項、設定和要載入的預設 Extension。
# --ext-folder "%~dp0/apps": 告訴 Kit 除了預設路徑外,還要到這個資料夾下尋找可用的 Extensions。
# %*: 傳遞參數。將你執行這個 .bat 檔時後面所帶的所有參數(例如 --vulkan 或 --no-window),全部原封不動地傳給 kit.exe。
# ------------------------------------------------------------------ #


# 所以如果想要客製化自己的專案,我使用的方法是複製 isaac-sim.bat 後改名成 my-isaac-sim.bat
# 並修改成
@echo off
setlocal
call "%~dp0kit\kit.exe" "%%~dp0apps/my-isaacsim.exp.full.kit" --ext-folder "%~dp0/apps" %*

.kit

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 接下來可以去看看 apps/my-isaacsim.exp.full.kit 裡面寫了什麼
# .kit 其實就是一個 TOML 格式的文字檔案,就像 .json 是一個 json 格式的文字檔。
# kit.exe 會依據 .kit 設定的數值啟動服務
# 稍微瀏覽 .kit 裡面的屬性

# 有這些節
# [package]
# [dependencies]
# [settings]
# [settings.app]
# [settings.app.exts.folders]
# [settings.exts."omni.kit.registry.nucleus"]

# 可以看 [dependencies],是啟動 my-isaacsim.exp.full.kit 需要使用到的 extension,這邊是關鍵,目前我都是在這邊增加客製的 extension,跟這篇文章有關的是這兩個
"omni.services.transport.server.http" = { version = "1.3.1" }
"my-extension-sync" = {}

# 接下來用滑鼠點擊 my-isaac-sim.bat,會看到 isaac-sim 視窗打開了,更重要的是從瀏覽器輸入 http://localhost:8011/docs 可以看到 api server 啟動了

omniverse 有內建的 api server 可以啟用,不用自己設定。

1
2
3
4
5
6
7
8
9
# 在 .kit 內的 [dependencies] 加上
"omni.services.transport.server.http" = { version = "1.3.1" }

# 從 isaac-sim-standalone@4.5.0-rc.36\extscache\omni.services.transport.server.http-1.3.1\config\extension.toml 可以看到 port 和 url
# 瀏覽器輸入 http://localhost:8011/docs 可以看到 api server 啟動了
# https://docs.omniverse.nvidia.com/services/latest/design/getting_started.html
exts."omni.services.transport.server.http".http.enabled = true
exts."omni.services.transport.server.http".host = "0.0.0.0"
exts."omni.services.transport.server.http".port = 8011

extension

產生 extension 需要使用 kit-app-template 這個工具 https://github.com/NVIDIA-Omniverse/kit-app-template?tab=readme-ov-file#quick-start

1
2
3
4
5
6
7
8
9
10
11
# 下載 kit-app-template
git clone https://github.com/NVIDIA-Omniverse/kit-app-template.git

# 進入 kit-app-template 資料夾
cd kit-app-template

# 使用 .repo 產生 application 或 extension
# linux
./repo.sh template new
# window
.\repo.bat template new

image.png

1
2
# 接下來只要把整個 extension 資料夾複製到 /isaac-sim-standalone@4.5.0-rc.36/exts 內就可以在 my-isaacsim.exp.full.kit 內的 [dependencies] 加上
"my_company.my_python_ui_extension" = {}

啟動 my-isaac-sim 可以看到建立的 extension。

image 1.png

如果沒有自動出現可以去 window/extensions 內 enabled

image 2.png

測試用 api 可以觸發產生 cube

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# 修改 \isaac-sim-standalone@4.5.0-rc.36\exts\my_company.my_python_ui_extension\my_company\my_python_ui_extension\extension.py

# 1. 新增的套件
from pydantic import BaseModel, Field
from typing import List
from pxr import UsdGeom, Gf

# 2. 在 def on_startup(self, _ext_id): 加入
main.register_endpoint(
url="/mcp/spawn_cube",
verb="post",
func=create_cube_handler,
tags=["MCP Actions"],
)

# 3. 加入 create_cube_handler function
class CubeModel(BaseModel):
name: str = Field(..., description="方塊的名稱 (必須唯一)", example="my_box_01")
size: float = Field(100.0, description="方塊的大小")
position: List[float] = Field([0.0, 0.0, 0.0], description="位置 [x, y, z]")


async def create_cube_handler(request: CubeModel) -> dict:
print(f"Received request to create cube: {request}")
# 獲取當前的舞台 (Stage)
ctx = omni.usd.get_context()
stage = ctx.get_stage()

if not stage:
return {"status": "error", "message": "沒有開啟任何舞台 (Stage)"}

# 組合路徑,例如:/World/my_box_01
# 注意:Omniverse 的路徑通常從 /World 開始
path = f"/World/{request.name}"

# 檢查該路徑是否已經存在物件,避免覆蓋
if stage.GetPrimAtPath(path):
return {"status": "error", "message": f"物件 {path} 已經存在!"}

# --- USD 核心操作開始 ---

# A. 定義一個 Cube (立方體)
cube_prim = UsdGeom.Cube.Define(stage, path)

# B. 設定大小
cube_prim.GetSizeAttr().Set(request.size)

# C. 設定位置 (Translation)
# 為了移動它,我們需要加入一個 Translate 的操作 (Op)
xform_api = UsdGeom.XformCommonAPI(cube_prim)
xform_api.SetTranslate(
Gf.Vec3d(request.position[0], request.position[1], request.position[2])
)

# B. 設定顏色 (選用,設為紅色讓它明顯一點)
cube_prim.GetDisplayColorAttr().Set([Gf.Vec3f(1.0, 0.0, 0.0)])

# --- USD 核心操作結束 ---

return {"status": "success", "path": path, "message": f"已建立方塊:{request.name}"}

測試

1
2
3
4
5
6
7

# 用 postman 觸發 http://localhost:8011/mcp/spawn_cube,並且記得設定 body
{
"name": "hello",
"size": 100,
"position": [0,0,0]
}

GifMaker_20251211164844307.gif

如果出現 my_company.my_python_ui_extension 匯入錯誤

1
2
3
4
5
# 到 \isaac-sim-standalone@4.5.0-rc.36\exts\my_company.my_python_ui_extension\config\extension.toml 的 [dependencies] 加上依賴的 extension
[dependencies]
"omni.kit.uiapp" = {}
"omni.services.core" = {}
"omni.services.transport.server.http" = {}

這些綜合起來可以完全自由開發了嗎?好像可以。

  • 善用 isaac-sim-standalone 資料夾內的 example,直接從範例抄需要的功能因為文件很難找: \isaac-sim-standalone@4.5.0-rc.36\standalone_examples

  • 下載 isaac-sim Download Isaac Sim — Isaac Sim Documentation