AI와 개발을 쉽게 이해하는 실험실

비개발자도 따라오는 AI 도구, 자동화, 개발 실험 기록

개발 & 기술/로보틱스

Isaac Sim 카메라 붙이기: 로봇 시뮬레이션 첫 예제

루민 Lumin 2026. 8. 2. 08:25
반응형

Isaac Sim 카메라 센서를 로봇에 붙이고 이미지를 확인하는 첫 예제를 정리했습니다. USD 계층 이해부터 뷰포트 확인, 파이썬으로 프레임을 꺼내는 순서까지 초보가 막히기 쉬운 지점 위주로 안내합니다.

Isaac Sim 카메라 붙이기: 로봇 시뮬레이션 첫 예제의 핵심 개념을 단순한 테크 일러스트로 표현한 대표 이미지

Isaac Sim 카메라는 로봇 팔이나 이동 로봇에 "눈"을 달아 시뮬레이션 안에서 이미지를 뽑아내는 기능입니다. 겉보기엔 카메라 하나 붙이는 일이지만, 실제로는 USD 계층 구조, 좌표계, 렌더링 파이프라인이 얽혀 있어 처음엔 뷰포트에 아무것도 안 나와서 당황하기 쉽습니다. 이 글은 Isaac Sim에서 로봇에 카메라 프림(Prim)을 붙이고, 뷰포트에서 확인한 뒤, 파이썬으로 이미지 프레임을 꺼내오는 최소 예제를 순서대로 정리합니다. 공식 문서 링크는 마지막에 모아두었으니 최신 버전 기준으로 반드시 교차 확인해 주세요.

시작 전 알아둘 것 세 가지

Isaac Sim 카메라 작업은 "3D 오브젝트 만들기"가 아니라 USD 씬 그래프에 센서 프림을 추가하는 일입니다. 이 관점을 먼저 잡아야 튜토리얼이 훨씬 잘 읽힙니다.

Isaac Sim은 NVIDIA가 만든 로봇 시뮬레이터로, 내부적으로 Pixar의 USD(Universal Scene Description, 3D 씬을 계층 구조로 표현하는 파일 포맷)를 씁니다. 로봇도, 카메라도, 조명도 전부 USD의 Prim이라는 노드로 트리 안에 들어갑니다.

카메라를 로봇 손목에 붙인다는 건 결국:

World
└── Robot
    └── wrist_link
        └── Camera   ← 여기 자식으로 붙임

이런 트리를 만드는 일입니다. 자식으로 붙이면 부모(wrist_link)가 움직일 때 카메라도 따라 움직입니다.

세 가지만 먼저 기억해 두면 좋습니다.

개념 한 줄 설명
Prim USD 씬 트리의 한 노드. 로봇·링크·카메라 모두 Prim
Stage 지금 열려 있는 USD 씬 전체
Xform 위치·회전·크기를 담는 변환 노드. 카메라 위치 조정용
💡 카메라가 "안 보인다"의 절반 이상은 카메라를 엉뚱한 부모 밑에 붙였거나, 로컬 좌표에서 뒤를 보고 있는 경우입니다.

준비물 체크리스트

본격적으로 씬을 만지기 전에 아래를 먼저 확인합니다. 버전과 요구사항은 자주 바뀌므로 반드시 공식 문서에서 최신 값을 확인하세요.

  • Isaac Sim이 설치돼 있고 정상 실행됨 (Omniverse Launcher 또는 컨테이너)
  • GPU 드라이버가 공식 문서가 요구하는 최소 버전 이상
  • 예제로 쓸 로봇 USD 파일 (Isaac Sim 기본 제공 자산 중 Franka, UR10 등 아무거나)
  • 파이썬 스크립트 편집기 (VS Code 등)

카메라만 붙이는 실습은 로봇을 굳이 움직이지 않아도 되므로, 시뮬레이션 물리 튜닝 지식은 필요 없습니다. USD 계층을 읽고 쓸 줄만 알면 됩니다.

 

GUI에서 카메라 붙이기: 가장 빠른 방법

Isaac Sim에서 카메라를 다는 가장 빠른 방법은 상단 메뉴의 Create → Camera로 만든 뒤, Stage 창에서 로봇의 원하는 링크 밑으로 드래그해 넣는 것입니다. 이 한 문장이 오늘 실습의 절반입니다.

순서는 이렇습니다.

  1. 좌측 Stage 패널을 엽니다. 씬의 USD 트리가 보입니다.
  2. 예제 로봇을 씬에 로드합니다 (예: Isaac Examples → Manipulation 카테고리에서 Franka 로봇 씬 열기).
  3. 상단 메뉴 Create → Camera를 누릅니다. World 아래 Camera 프림이 생깁니다.
  4. Stage 창에서 그 Camera 프림을 로봇의 손목 링크(예: panda_hand) 위로 드래그해 자식으로 만듭니다.
  5. 우측 Property 패널에서 카메라의 Translate, Rotate 값을 조정해 원하는 위치·방향으로 맞춥니다.

이 단계에서 일부 환경에서는 첫 번째 함정에 걸립니다.

⚠️ USD 카메라의 로컬 좌표에서 -Z 방향이 "카메라가 보는 방향" 입니다. 앞을 보게 하려면 Rotate 값을 조정해서 -Z가 씬의 앞쪽을 향하도록 맞춰야 합니다.

카메라가 잘 붙었는지 확인하려면 뷰포트 상단의 카메라 선택 드롭다운(기본은 Perspective)을 눌러 방금 만든 카메라 이름으로 바꿉니다. 그 카메라 시점에서 화면이 렌더링됩니다.

파이썬으로 카메라 프림 만들기

GUI로 붙이는 게 익숙해지면 다음은 스크립트입니다. 실험 조건을 바꿔가며 여러 번 돌려야 하는 로보틱스 프로젝트에서는 파이썬으로 카메라 프림을 생성·배치하는 쪽이 재현성 면에서 훨씬 낫습니다.

Isaac Sim은 자체 파이썬 환경을 제공합니다. Script Editor 창을 열거나 Standalone 파이썬 스크립트로 실행하면 됩니다. 아래는 카메라를 특정 링크 밑에 붙이는 최소 예제의 골격입니다.

# Isaac Sim Script Editor에서 실행
import omni.usd
from pxr import UsdGeom, Gf

stage = omni.usd.get_context().get_stage()

# 카메라를 붙일 부모 경로 (로봇 링크)
parent_path = "/World/Franka/panda_hand"
camera_path = parent_path + "/wrist_camera"

# 카메라 프림 생성
camera = UsdGeom.Camera.Define(stage, camera_path)

# 로컬 위치·회전 설정 (예: 손목에서 앞으로 5cm)
xform = UsdGeom.Xformable(camera)
xform.AddTranslateOp().Set(Gf.Vec3d(0.0, 0.0, 0.05))

이 스크립트가 하는 일은 세 가지입니다. 첫째, 현재 열려 있는 Stage를 가져옵니다. 둘째, panda_hand 링크 밑에 wrist_camera라는 이름으로 카메라 프림을 만듭니다. 셋째, 부모 링크 기준으로 5cm 앞에 위치를 잡습니다.

Rotate까지 필요하면 AddRotateXYZOp()을 이어 붙여 오일러 각도를 설정합니다. 이 부분은 로봇마다 링크의 기준 축이 달라 값이 제각각이므로, 뷰포트에서 카메라 프림을 눌러 gizmo를 보면서 조정하는 편이 빠릅니다.

 

이미지 프레임을 실제로 꺼내오기

카메라가 씬에 있다고 해서 자동으로 이미지가 파이썬 변수로 들어오지는 않습니다. 렌더 프로덕트(Render Product)와 애노테이터(Annotator)를 연결해야 프레임을 배열 형태로 받을 수 있습니다.

Isaac Sim에서 이미지·깊이·세그멘테이션 같은 센서 출력을 뽑을 때 쓰는 도구가 Replicator입니다. 흐름은 이렇습니다.

카메라 Prim
   ↓
Render Product 생성
   ↓
Annotator 붙임 (rgb, depth 등)
   ↓
프레임 배열 획득

핵심 API는 omni.replicator.core 아래에 있습니다. 이름·시그니처가 버전마다 조금씩 바뀌므로, 최신 버전의 Replicator 공식 문서에서 create.render_product, AnnotatorRegistry.get_annotator("rgb") 부분을 확인하는 게 안전합니다.

개념만 짚어두면 이렇게 이해하면 됩니다.

요소 역할 비유
Camera Prim 씬 안의 가상 카메라 실제 카메라 본체
Render Product 그 카메라로 렌더링한 결과 스트림 카메라 케이블
Annotator 결과에서 원하는 데이터 뽑기 (RGB, 깊이 등) 캡처 보드

RGB 애노테이터를 붙이면 프레임마다 (H, W, 4) 형태의 numpy 배열이 나옵니다. 이걸 OpenCV로 저장하거나, PyTorch 텐서로 넘겨 학습 파이프라인에 태우면 됩니다.

예를 들어 로봇 팔이 물체를 잡기 전에 손목 카메라로 물체를 인식해야 한다면, 시뮬레이션 매 스텝마다 이 RGB 배열을 꺼내 학습된 detection 모델에 넣고, 결과를 다시 제어 코드로 되돌리는 구조가 됩니다.

자주 막히는 부분

첫 예제에서 반복적으로 걸리는 지점 몇 가지를 정리합니다.

1. 뷰포트에 검은 화면만 나온다 카메라가 아무것도 없는 방향을 보고 있거나, 로봇 내부 메시 안쪽에 들어가 있을 확률이 높습니다. 카메라 Translate를 로봇 바깥쪽으로 크게 빼서 확인해 보세요.

2. 로봇이 움직여도 카메라가 안 따라온다 World 바로 밑에 카메라를 만들고 링크 밑으로 옮기지 않은 경우입니다. Stage 트리에서 카메라의 부모가 링크인지 다시 확인합니다.

3. 이미지 배열의 값이 전부 0이다 렌더링이 한 프레임도 돌지 않은 상태에서 배열을 읽으면 이렇게 나옵니다. 시뮬레이션 스텝을 최소 한 번 이상 진행한 뒤에 애노테이터를 읽어야 합니다.

4. FoV·해상도가 예상과 다르다 카메라 Property에서 Focal Length, Horizontal Aperture 값을 확인합니다. FoV는 이 둘의 조합으로 결정됩니다. 해상도는 Render Product 생성 시 지정합니다.

다음에 시도해 볼 것

여기까지 따라오면 로봇에 카메라를 붙이고 이미지를 파이썬 배열로 꺼내는 최소 파이프라인이 완성됩니다. 그 위에 얹을 만한 다음 단계는 아래와 같습니다.

  • 깊이·세그멘테이션 애노테이터 추가 — RGB 대신 distance_to_camera, semantic_segmentation으로 바꿔 붙이면 됩니다.
  • 여러 대 카메라 동시 운용 — 손목 카메라 + 외부 카메라를 각각 Render Product로 만들면 스테레오 실험도 가능합니다.
  • Domain Randomization — Replicator로 조명·재질·배경을 무작위화해 학습 데이터셋을 늘리는 방식.
  • ROS 2 브릿지 — 실기와 동일한 토픽으로 이미지를 흘려보내 정책 코드를 그대로 실기에 옮기는 실험.

버전과 API 이름은 자주 바뀌니, 실제로 코드를 붙일 때는 NVIDIA의 Isaac Sim 공식 문서와 omni.replicator.core 레퍼런스에서 함수 시그니처를 한 번 더 확인하는 습관을 들이면 시행착오가 크게 줄어듭니다.

함께 보면 좋은 글

반응형