# 물리(Physics) 시뮬레이션 기초 설정

#### 물리 시뮬레이션의 개념

시뮬레이션에서 물리 엔진은 물리 법칙을 모사하여 객체의 운동과 상호작용을 계산한다. 가장 기본은 뉴턴의 운동 법칙이며, Isaac Sim은 NVIDIA PhysX 엔진을 활용하여 이를 구현한다. 객체의 질량, 관성 모멘트, 충돌 및 마찰 계수 등의 속성을 통해 현실적인 동작을 시뮬레이션하게 된다. 특히 Isaac Sim은 GPU 병렬 연산 기능을 포함해 확장성이 높으며, ROS2 Humble과 연동하여 로봇 제어 및 센서 피드백도 시뮬레이션할 수 있다.

질량중심에 대한 고전역학에서 물체의 움직임은 $t$ 시점에 대한 위치 $\mathbf{r}(t)$, 속도 $\mathbf{v}(t)$, 가속도 $\mathbf{a}(t)$로 표현할 수 있다. 단일 입자(또는 질점) 모델을 가정한다면, 다음과 같은 뉴턴의 2법칙으로 기술할 수 있다.

$$
\begin{align} \mathbf{F}\_{\text{net}} = m \mathbf{a}  \end{align}
$$

여기서 $m$은 질량, $\mathbf{a}$는 가속도, $\mathbf{F}\_{\text{net}}$는 입자에 작용하는 힘의 합이다. 여러 물체가 상호작용할 때는 충돌, 마찰, 조인트(joint) 연결 등 다양한 요소가 힘으로 표현되어 시뮬레이션에서 처리된다.

#### Isaac Sim과 물리 엔진 개요

Isaac Sim은 NVIDIA의 PhysX를 기본 물리 엔진으로 채택한다. PhysX는 크게 다음과 같은 핵심 기능을 제공한다.

* 충돌 감지 및 응답(Collision Detection & Response)
* 강체(Rigid Body) 시뮬레이션
* 연성체(Soft Body), 천 시뮬레이션 등 확장 기능
* 조인트(Joint) 기반의 메카니즘 시뮬레이션

Isaac Sim에서 기본적인 물리 시뮬레이션 환경 설정은 Stage(USD 기반 3D 장면)의 Physics Scene을 통해 제어된다. 예를 들어 중력, 시뮬레이션 타임스텝(time step), 서브스텝(substep), 솔버 이터레이션(solver iteration) 등이 중요한 설정 값이다.

#### 물리 시뮬레이션의 주요 파라미터

Isaac Sim의 물리 시뮬레이션 설정에서 핵심이 되는 파라미터들을 살펴보면 다양한 요소가 포함된다.

**중력(Gravity)**

시뮬레이션에서 중력은 전역적으로 적용되는 힘으로, 보통 지구 표준 중력을 사용한다. Isaac Sim에서는 $\mathbf{g} = (0, 0, -9.81),\text{m/s}^2$ 를 기본값으로 하며, USD Stage의 Physics Scene 속성에서 값을 변경할 수 있다. 만일 특정 시나리오에서 다른 중력을 가정하거나 무중력 환경을 테스트하고자 한다면 이를 0으로 설정하거나 다른 벡터로 조정할 수 있다.

**타임스텝(Time Step)과 서브스텝(Substep)**

시간 간격(Time Step)은 시뮬레이션에서 한 프레임을 업데이트하는 데 사용되는 가상 시간의 간격을 의미한다. 예를 들어 타임스텝을 60Hz로 설정하면, 실제로는 약 $16.66,\text{ms}$의 간격을 모사하게 된다.

서브스텝은 각 타임스텝을 다시 쪼개어 더 작은 시간 단위로 물리 연산을 수행하는 과정을 의미한다. 충돌이나 충격이 극도로 빠르게 일어나는 경우, 메인 타임스텝만으로는 정확도가 떨어질 수 있다. 이를 보완하기 위해 서브스텝을 도입함으로써 물리 계산 정확도를 향상시킨다.

서브스텝은 시뮬레이션 정밀도와 계산 비용 간의 트레이드오프가 있다. 서브스텝을 많이 할수록 더 정확하지만 계산 비용이 증가한다. 따라서 동역학이 급격하게 변화하는 로봇 조인트나 충돌이 잦은 장면에서는 서브스텝 수를 높이고, 정적 환경에서는 낮춰 시뮬레이션 효율을 높일 수 있다.

**솔버 이터레이션(Solver Iteration)**

물리 엔진 내부에서 운동 방정식을 수치적으로 해결하기 위해 반복(iteration)을 수행한다. 보통 Position Iteration, Velocity Iteration으로 구분하여 설정할 수 있다. 물리 시뮬레이션에서 중요한 것은 충돌이 발생했을 때 객체 간의 간섭이 최소화되도록 빠른 시간에 해를 찾는 것이며, 이때 반복 횟수가 충분하지 않으면 서로 관통(Penetration) 현상이 발생하거나 안정성이 떨어진다.

Position Iteration은 주로 겹침 현상을 줄이는 데 유효하며, Velocity Iteration은 충돌 후 반발 속도 등 동적 거동을 정확하게 보정하는 데 기여한다. Isaac Sim 환경에서는 시스템 규모, 로봇의 조인트 연결 방식, 물리 상호작용의 복잡도에 따라 적절한 솔버 이터레이션을 지정한다.

**마찰(Friction)과 반발계수(Restitution)**

물리 시뮬레이션에서 마찰계수 $\mu$는 접촉면에서 발생하는 마찰력을 결정한다. 마찰력은 쿨롱 마찰 모델을 많이 사용하며, 일반적인 경우 다음과 같이 표현한다.

$$
\begin{align} \mathbf{F}\_{\text{fric}} = \mu , N , \hat{\mathbf{t}}  \end{align}
$$

$N$은 법선방향 접촉력의 크기, $\mu$는 마찰계수, $\hat{\mathbf{t}}$는 접촉면에서의 접선 방향 단위벡터이다. Isaac Sim은 동적 마찰과 정지 마찰 계수를 별도로 설정할 수도 있다.

반발계수(Restitution)는 충돌 후 객체가 얼마나 탄성적으로 반발하는지를 나타낸다. 0에 가까우면 비탄성 충돌(inelastic collision)이 되어 충돌 후 에너지가 소멸되고, 1에 가까우면 탄성 충돌(elastic collision)이 되어 거의 에너지를 잃지 않는다. PhysX에서는 0과 1 사이의 값을 권장하며, Isaac Sim 내 Material 설정에서 마찰계수와 함께 조절 가능하다.

**질량(Mass)과 관성 모멘트(Inertia)**

Isaac Sim에서 객체의 질량과 관성 모멘트를 설정할 수 있다. 관성 모멘트는 3차원 물체의 회전 운동에서 중요한 요소로, 물체의 형상과 질량 분포에 의해 결정된다. 기본적으로 Convex Hull 등의 단순화 방식으로 관성 모멘트를 계산하거나, 사용자가 직접 값을 지정할 수도 있다.

질량행렬 $\mathbf{M}$은 강체(rigid body)에서 다음과 같은 꼴을 가진다.

$$
\begin{align} \mathbf{M} =  \begin{pmatrix} m \mathbf{I}*{3\times 3} & \mathbf{0} \ \mathbf{0} & \mathbf{I}*{\text{inertia}} \end{pmatrix}  \end{align}
$$

여기서 $m$은 질량, $\mathbf{I}*{3\times 3}$는 $3\times 3$ 단위행렬, $\mathbf{I}*{\text{inertia}}$는 3차원 관성 텐서(inertia tensor)이다. Isaac Sim에서 이 행렬을 바탕으로 회전 운동과 병진 운동을 계산하게 된다.

#### Isaac Sim에서 물리 설정 조정하기

Isaac Sim은 GUI(그래픽 사용자 인터페이스)에서 Physics 메뉴를 통해 쉽게 제어할 수 있다. Stage에 Physics Scene 프리미티브(USD 속성)를 추가하고, 다음과 같은 요소를 확인한다.

* 물리 엔진(PhysX) 활성화
* 시뮬레이션 업데이터(Time Step / Substep)
* 기본 중력 벡터
* 솔버 이터레이션(입력값에 따라 Position / Velocity iteration 설정)
* Material(마찰, 반발계수) 적용

Python 스크립트로 제어하려면 OmniKitHelper 등의 Isaac Sim API를 통해 접근 가능하다. 아래는 예시 코드이다.

```python
from omni.isaac.kit import SimulationApp
simulation_app = SimulationApp({'headless': False})

import omni
from pxr import UsdPhysics

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

# Physics Scene 생성
scene = UsdPhysics.Scene.Define(stage, "/World/PhysicsScene")
physx_scene_api = UsdPhysics.Scene.Get(stage, "/World/PhysicsScene")

# 중력 벡터 설정
scene.CreateGravityDirectionAttr().Set((0.0, 0.0, -1.0))
scene.CreateGravityMagnitudeAttr().Set(9.81)

# Time Step 설정
scene.CreateTimeCodesPerSecondAttr().Set(60)

# 나머지 물리 설정 (substep, solver iteration 등) 지원 함수
# 여기서는 개념적 예시로서, 실제 Isaac Sim 버전에 따라 API가 다를 수 있음
# ...

simulation_app.update()
simulation_app.play()
```

이와 같이 Python API를 사용하면 Isaac Sim 내의 USD Stage에 직접 물리 정보를 주입할 수 있다. ROS2 Humble과 함께 사용할 경우, ros2 node에서 원하는 트리거나 이벤트가 발생했을 때 Isaac Sim의 물리 파라미터를 동적으로 바꿀 수도 있다.

#### 고급 물리 설정: 서브스텝 전략, 솔버 알고리즘 확장

일부 상황에서는 타임스텝을 고정하되 서브스텝을 유연하게 늘이는 적응형(substep) 전략이 필요하다. 예컨대 로봇이 빠른 속도로 움직이며 복잡한 충돌이 빈번히 일어날 경우, 서브스텝을 높여야 정확도를 유지할 수 있다. 반면 서브스텝이 과도하게 크면 프레임레이트가 떨어져 시뮬레이션 체감 속도가 느려질 수 있으므로, 적절한 균형점을 찾는 것이 중요하다.

PhysX 솔버 자체도 여러 알고리즘(Sequential Impulse, TGS(Temporal Gauss-Seidel), PGS(Project Gauss-Seidel) 등)을 지원하며, Isaac Sim 버전에 따라 해당 알고리즘을 선택적으로 적용할 수 있다. 예컨대 TGS 솔버는 안정도가 높은 편이므로 조인트가 복잡하게 연결된 로봇 모델에서 유리하다.

#### 강체, 동적(Dynamic) 객체, 그리고 운동학(Kinematic) 객체

시뮬레이션에서 오브젝트를 어떻게 분류하고 제어하느냐에 따라 물리 계산 방식이 달라진다. Isaac Sim에서 대표적으로 세 가지 물체 유형이 존재한다.

* **정적(Static) 객체**: 완전히 움직이지 않는 물체로, 충돌 계산에는 참여하나 자기 자신은 움직이지 않는다. 지면, 벽 등의 주변 환경이 대표적 사례이다. 관성이나 속도를 가지지 않으므로 물리 연산에 부하가 적다.
* **동적(Dynamic) 객체**: 질량과 관성 모멘트를 가지며, 외력이나 충돌에 의해 자유롭게 움직인다. 일반적으로 로봇의 각 링크나 이동 물체 등이 여기에 해당한다.
* **운동학(Kinematic) 객체**: 물리 시뮬레이션에서 직접 힘이나 충돌로 움직임을 계산하지 않고, 사용자가 직접 위치나 속도를 지정해 움직이는 객체이다. 예컨대 Isaac Sim에서 로봇 조인트 조작을 시뮬레이션할 때, 상위 레벨의 제어기에 의해 궤적이 정해지는 링크가 존재할 수 있다. 이때 이 링크를 Kinematic으로 설정하면, 엔진이 해당 링크를 물리적으로 풀어내기보다는 사용자가 지정한 위치로 즉시 이동시킬 수 있다. 운동학 객체도 다른 동적 객체와의 충돌은 계산하지만, 자신은 외력에 의해 거동이 바뀌지 않는다.

#### 충돌(콜리전) 형태와 바운딩 볼륨(Bounding Volume)

물체의 물리적 충돌 검출은 크게 두 단계로 진행된다.

1. 충돌 가능성을 빠르게 평가하는 Broad Phase
2. 실제 접촉 지점을 세밀하게 계산하는 Narrow Phase

이를 수행하기 위해 물체를 어떤 형태(Shape)로 근사할 것인지가 매우 중요하다. Isaac Sim에서는 대표적으로 아래 형태들이 사용된다.

* Box, Sphere, Capsule, Cylinder와 같은 기본 기하학 형태
* Convex Hull, Mesh(삼각 메쉬) 기반의 정확한 형태
* Plane, Height Field 등 환경 표현용 큰 스케일 형태

단순화된 기하학 형태(Box, Sphere 등)는 충돌 계산이 빠르지만 물체 형상을 정확하게 반영하기 어렵다. 반면 Convex Hull이나 Mesh 충돌은 정밀하지만 계산 비용이 증가한다. PhysX 엔진은 물체의 실제 Mesh Geometry를 직접 사용하기도 하나, 너무 복잡한 Mesh는 성능 저하가 심하므로 보통 중간 단계의 Convex Hull 다면체를 활용한다.

#### 고급 충돌 필터링(Collision Filtering)과 그룹

시뮬레이션 과정에서 모든 객체가 서로 충돌할 필요는 없다. 물리 엔진은 충돌 필터링(collision filtering)을 통해 특정 그룹 간에만 충돌 계산을 수행할 수 있다. 예를 들어 내부 기어 같은 부품은 서로 충돌이 발생해선 안 되거나, 로봇 팔 조인트 링크 간 자기 충돌(self-collision)을 무시해야 하는 경우가 생긴다.

Isaac Sim에서 충돌 필터링은 Material이나 Collision Group 설정을 통해 가능하다. 예를 들어 특정 충돌 그룹(예: Group1)에는 로봇 자체를 포함하고, 외부 환경(Group2)에는 충돌을 허용하되, 로봇 내부 링크 간(Group1 내 자기 충돌)은 무시하도록 설정한다. 이를 통해 시뮬레이션 성능과 일관성을 유지할 수 있다.

#### 조인트(Joint)과 조인트 제약(Constraint)

다중 링크 멀티바디(multi-body) 구조를 구성할 때는 각 링크를 조인트로 연결한다. Isaac Sim에서 대표적인 조인트 유형은 아래와 같다.

* Revolute(회전)
* Prismatic(직선 이동)
* Fixed(고정)
* Spherical(구형)
* Articulation(고차원 조인트 연결을 포함한 PhysX 고유 구조)

조인트는 원하는 각도 범위(또는 거리 범위), 제한 토크(토크 한계) 등을 설정할 수 있으며, 내부적으로 제약 조건을 통해 물리 엔진이 연산한다. 예컨대 회전 조인트의 각도 제한은 다음의 제약 방정식으로 표현할 수 있다:

$$
\begin{align} \theta\_{\min} \le \theta \le \theta\_{\max}  \end{align}
$$

여기서 $\theta$는 조인트의 회전각이며, Isaac Sim 물리 엔진은 제한 범위를 넘어서지 않도록 힘과 토크를 적용해 제어한다.

아울러 링크의 관성 모멘트가 잘못 설정되거나, 조인트 강성(stiffness), 댐핑(damping) 값이 적절하지 않으면 시뮬레이션이 불안정할 수 있다. PhysX Articulation 기능을 사용하면 계층적 구조로 서로 연결된 조인트에 대해 보다 안정적인 해석이 가능하다.

#### 3차원 강체 운동 방정식

동적 객체의 3차원 운동은 병진 운동과 회전 운동이 결합되어 있다. 병진 운동은 앞서 언급한 뉴턴의 운동 법칙:

$$
\mathbf{F}\_{\text{net}} = m \mathbf{a}
$$

를 따르며, 회전 운동은 오일러 방정식(Euler’s equation)으로 기술된다:

$$
\begin{align} \boldsymbol{\tau}*{\text{net}} = \frac{d}{dt}\bigl(\mathbf{I}*{\text{inertia}} \boldsymbol{\omega}\bigr) + \boldsymbol{\omega} \times \bigl(\mathbf{I}\_{\text{inertia}} \boldsymbol{\omega}\bigr)  \end{align}
$$

여기서 $\boldsymbol{\tau}*{\text{net}}$는 물체에 작용하는 토크의 합, $\boldsymbol{\omega}$는 각속도 벡터, $\mathbf{I}*{\text{inertia}}$는 물체의 관성 텐서이다. Isaac Sim(PhysX)은 위 식을 수치적으로 적분하여 물체의 위치, 자세, 속도, 각속도를 매 프레임 업데이트한다.

#### 비선형 충돌과 각속도 상호작용

충돌 시 회전이 큰 역할을 하는 경우, 예컨대 긴 막대가 한쪽 끝으로 충돌받아 크게 회전하는 상황 등에서는 타임스텝, 서브스텝, 솔버 이터레이션 설정이 매우 중요해진다. 충돌 순간에 정확한 접촉점, 충돌 각도, 물체의 관성 모멘트를 고려하여 반발 속도와 각속도를 계산해야 하기 때문이다. 서브스텝이 부족하거나 솔버 이터레이션이 충분하지 않으면 비현실적인 관통이나 회전 불안정 현상이 발생한다.

#### Isaac Sim 디버깅 툴 활용

Isaac Sim은 다양한 시각화 툴과 디버깅 기능을 제공한다. 다음과 같은 기능을 적절히 활용하면 물리 시뮬레이션의 정확도를 손쉽게 검증하고, 문제가 발생했을 때 원인을 파악할 수 있다.

* **Collisions 시각화**: 실제로 충돌이 감지되는 지점을 표시해주므로, 겹침이나 의도치 않은 충돌이 있는지 확인 가능하다.
* **Contacts 시각화**: 접촉면의 법선 벡터나 마찰 방향 등을 확인해 문제점을 파악한다.
* **Joint 시각화**: 조인트 축과 연결 관계를 직접 확인해 조인트 위치와 제한 범위를 시각적으로 검증할 수 있다.

또한 Python API를 통해 접촉 지점(Contact Point) 정보를 받아오거나 충돌 검사 결과를 분석할 수도 있다.

#### Python을 통한 물리 디버깅 예시

아래 예시는 Isaac Sim에서 동작하는 Python 스크립트로, 특정 경로에 배치된 두 객체 사이의 충돌 정보를 모니터링하는 개념적 코드이다.

```python
from omni.isaac.kit import SimulationApp
simulation_app = SimulationApp({'headless': False})

import omni
import math

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

# 예시로 두 개의 박스 생성
# 실제 API 호출 방식은 Isaac Sim 버전에 따라 다를 수 있음
from pxr import UsdGeom, Gf

box_path_1 = "/World/Box1"
box_1 = UsdGeom.Cube.Define(stage, box_path_1)
box_1.GetSizeAttr().Set(0.5)
box_1.AddTranslateOp().Set(Gf.Vec3f(0, 0, 0.25))

box_path_2 = "/World/Box2"
box_2 = UsdGeom.Cube.Define(stage, box_path_2)
box_2.GetSizeAttr().Set(0.5)
box_2.AddTranslateOp().Set(Gf.Vec3f(0.5, 0, 0.25))

# 물리 설정
scene = stage.GetPrimAtPath("/World/PhysicsScene")
if not scene.IsValid():
    from pxr import UsdPhysics
    scene = UsdPhysics.Scene.Define(stage, "/World/PhysicsScene")
    
# 시뮬레이션 수행
simulation_app.update()
simulation_app.play()

# 콜리전 검사 시연
# (개념적인 예: 실제 Isaac Sim에서 접촉 이벤트 콜백 등을 활용할 수도 있음)
for i in range(100):
    simulation_app.update()
    # 여기서 접촉 정보를 추출하거나 디버깅 툴로 확인 가능
    # ...
    
simulation_app.stop()
simulation_app.close()
```

위 코드는 매우 간략한 예시이며, 실제 프로젝트에서는 콜리전 필터링, 재질(Material) 설정, Joint 생성 등을 함께 고려해야 한다.

#### 고급 주제: GPU 가속 PhysX와 확장

NVIDIA PhysX는 CPU 기반 시뮬레이션과 더불어 GPU 가속 모드를 지원한다. Isaac Sim은 Omniverse RTX Renderer와 결합되어 있어 GPU 자원을 적극 활용할 수 있다. 단, GPU PhysX 모드는 모든 기능이 CPU 모드와 1:1 동일하게 지원되지 않을 수 있다. 대규모 입자 시뮬레이션이나 복잡한 충돌 계산을 수행할 때 GPU 가속 모드가 유리할 수 있다.

특수한 시나리오(예: 수백 개의 동적 객체가 동시에 충돌, 대규모 로봇 팔레트 작업, 물리 기반 시각효과 시뮬레이션 등)를 다룰 경우, GPU PhysX 설정을 고려해볼 수 있다. Isaac Sim GUI나 Python API를 통해 모드를 전환하는 옵션이 제공되며, 안정성과 호환성 테스트가 요구된다.

#### 센서 시뮬레이션을 위한 물리 엔진 설정 고려

ROS2 Humble과 결합해 로봇 센서를 시뮬레이션하려면, 물리 엔진의 해상도나 업데이트 주기를 센서 주기와 잘 맞추는 것이 중요하다. 예컨대 LiDAR, Depth Camera, IMU 등의 센서를 Isaac Sim에서 구현할 때, 센서 데이터를 생성하는 간격과 물리 시뮬레이션 타임스텝을 조율하지 않으면 센서 값이 불규칙하거나, 지연이 발생할 수 있다.

시뮬레이션은 실제 시간(real-time)과 동기화할 수도 있지만, 때로는 가속 또는 감속 모드로 돌려야 하는 상황이 있다. Isaac Sim에서 기본적으로 실제 시간(real-time)에 맞춰서 시뮬레이션하려면, 한 프레임(타임스텝)을 처리하는 데 걸리는 시간이 실제 1/프레임레이트(예: 1/60초)를 넘지 않도록 관리해야 한다. 하지만 복잡한 장면에서는 계산량이 많아져 실제 시간보다 느려지기도 하며, 이때 ROS2 쪽에서 /clock 토픽을 사용해 시뮬레이션 시간을 알리면, 노드는 시뮬레이션 시간 기준으로 동작할 수 있다.

#### 센서 물리 설정: 충돌 체와 광선 추적

카메라나 LiDAR, 레이다 같은 센서는 광선(ray) 기반의 시뮬레이션을 활용한다. Isaac Sim은 RTX 기반 광선 추적을 사용해 실제에 가까운 센서 데이터를 생성할 수 있으며, 물리 엔진의 충돌 체와 렌더링 엔진의 Mesh 간 일관성을 유지해야 한다. 가령 충돌 체가 생략된 객체나 시각적으로는 보이지만 물리 엔진에서 제외된 객체는 센서에서 관측되지 않거나, 반대로 충돌 체만 존재하고 시각적으로는 보이지 않는 경우 센서가 이상 데이터를 뿌릴 수 있다.

IMU(가속도, 자이로) 시뮬레이션은 로봇의 질량중심이나 관성 모멘트 설정과 밀접하게 연관되며, 물리 엔진의 실시간 운동 계산 값을 적절히 변환해 센서 노이즈 모델 등을 적용한다. Isaac Sim은 자체적인 IMU 시뮬레이터를 제공하거나, Python 확장을 통해 사용자가 직접 운동 데이터에 노이즈를 추가하여 ROS2 토픽으로 퍼블리시할 수도 있다.

#### ROS2 Humble과 물리 시뮬레이션 시간 동기

ROS2와 Isaac Sim 간 시간 동기는 /clock 토픽을 통해 이루어진다. Isaac Sim이 시뮬레이션 시간(가상 시간)을 퍼블리시하면, ROS2 노드는 이를 구독해 콜백, 타이머, TF 변환 등을 수행한다. 실제 시간(real-time)보다 빠르게 시뮬레이션을 돌릴 수도 있으며, 시뮬레이션이 불규칙하게 느려지더라도, ROS2 측에서는 Isaac Sim이 제공하는 가상 시간에 맞춰서 작동한다.

아래는 ROS2 Humble에서 Isaac Sim의 /clock 토픽을 사용해 노드가 동기화되는 상황을 간략히 보여주는 개념도다.

{% @mermaid/diagram content="flowchart LR
A(Isaac Sim) -- /clock --> B(ROS2 Node)
B -- callback, TF --> B" %}

이때 Isaac Sim에서 물리 파라미터(타임스텝, 서브스텝)와 렌더링 파이프라인의 성능이 복합적으로 영향을 주어, /clock 업데이트 간격이 실제 환경과 달라질 수 있다. 시뮬레이션이 과부하에 걸리면 /clock 발행 주기가 느려지고, 결과적으로 ROS2 노드 콜백도 실시간보다 느린 속도로 호출될 것이다.

#### Isaac Sim과 ROS2 제어 루프

ROS2를 통한 로봇 제어는 일반적으로 다음 흐름을 거친다.

로봇 상태(센서) → ROS2 Topic → 제어 노드(Ctrl) → 제어 입력(토크, 속도 등) → Isaac Sim의 물리 엔진 → 로봇 상태 갱신

이 흐름에서 Isaac Sim 물리 엔진이 충분히 빠르게, 안정적으로 돌아야 제어 노드가 원하는 대로 제어 값을 산출할 수 있다. 불안정한 물리 설정(너무 낮은 솔버 이터레이션, 부정확한 충돌 체)으로 인해 시뮬레이션 잡음이 커지면, ROS2 측 제어 알고리즘에서 과도한 피드백이 발생하거나, 목표 상태를 제대로 유지하기 어렵다.

로봇 조인트 제어를 예로 들면, Isaac Sim의 각 조인트(link)에 대해 동적 객체(Dynamic)로 설정하고, 물리 엔진이 제공하는 회전 운동 방정식에 따라 자율적으로 운동을 계산한다. ROS2 노드가 해당 조인트에 인가할 토크나 속도를 퍼블리시하면, Isaac Sim은 물리 계산 후 결과 상태(각속도, 각도, 가속도 등)를 다시 ROS2 토픽으로 보낸다.

#### Articulation과 ROS2 Controller 연동

Isaac Sim에서 Articulation으로 묶인 로봇 모델은 내부적으로 보다 안정적이고 효율적인 물리 계산 경로를 거친다. 로봇의 전체 조인트 정보를 하나의 대형 다체(multi-body)로 해석하여, 조인트 제약과 상호관계를 효율적으로 풀이한다. 이런 방식은 다음과 같은 장점을 가진다.

* 조인트 제약(Constraint)을 동시에 처리하므로 조인트 사이 간섭이나 충돌이 적다.
* 고속 모션이나 복잡한 링크 구조에서 수치 안정성이 높은 편이다.

ROS2의 다양한 컨트롤러(예: EffortController, PositionController)를 사용하려면 Isaac Sim 측에서도 조인트별로 힘(토크)을 인가하거나 각도 지령을 따르도록 설정이 필요하다. 이를 위해 Isaac Sim의 Extension 기능 또는 Python API로 Articulation 속성을 제어하고, ROS2에서 올바른 메시지 타입(sensor\_msgs/JointState, control\_msgs/FollowJointTrajectoryAction 등)을 수신∙발행하도록 매핑한다.

#### 실시간 인자 파라미터 조정

시뮬레이션 도중에 마찰계수나 중력을 바꾸거나, 타임스텝을 동적으로 변경해야 하는 경우가 생길 수 있다. ROS2의 dynamic\_reconfigure(또는 ROS2 Parameter Server 기능)에 해당하는 개념을 Isaac Sim 측에서 지원하도록 확장하면, ROS2 노드에서 파라미터를 변경하자마자 물리 엔진에 반영될 수도 있다. 이는 시험 환경에서 로봇이 다양한 마찰 조건(바닥 재질, 경사 등)을 만났을 때 동작이 어떻게 달라지는지를 빠르게 검증할 수 있게 해준다.

아래 예시는 물리 파라미터를 동적으로 변경하는 개념을 보여주는 Python 코드이다.

```python
import omni
from pxr import Usd, UsdPhysics

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

physx_scene_api = UsdPhysics.Scene.Get(stage, "/World/PhysicsScene")
if physx_scene_api:
    # 예시: 중력의 크기를 실시간으로 바꾸고 싶다고 가정
    new_gravity = 3.0  # 값 예시
    physx_scene_api.CreateGravityMagnitudeAttr().Set(new_gravity)

    # Solver Iteration 변경
    # 실제 API 구조에 따라 접근 방식이 다를 수 있음
    # ...
```

실제 구현에서는 ROS2 Subscriber를 만들어서 해당 Python 스크립트를 제어하거나 Isaac Sim의 Extension에서 ROS2 메시지를 처리해 파라미터를 바꾸도록 작성할 수 있다.

#### 시뮬레이션 안정성을 위한 팁

고성능∙고정밀 시뮬레이션을 위해서는 하드웨어 성능과 물리 엔진 설정 최적화가 필수다. 예컨대 복잡한 로봇, 센서, 환경이 한데 모여 있는 장면에서는 다음과 같은 조치를 통해 안정성을 확보할 수 있다.

* Mesh 충돌을 사용하기 전, 가능하면 Convex Hull이나 단순 기하체(Box, Sphere 등)로 대체해 충돌 계산 비용을 낮춘다.
* 서브스텝, 솔버 이터레이션을 테스트해 보면서 최소값을 찾는다. 너무 높으면 프레임레이트가 떨어지고, 너무 낮으면 관통이나 비현실적 움직임이 커진다.
* 자주 충돌할 일이 없는 객체끼리는 충돌 필터링을 적용해 계산 로드를 줄인다.
* Material(마찰, 반발계수) 설정이 잘못되어 있지 않은지, 관성 텐서가 말도 안 되는 값이 아닌지 확인한다(특히 CAD 모델에서 자동 추출된 관성 값이 비정상적인 경우가 있다).
* ROS2 제어 루프 주기와 물리 업데이트 주기가 너무 괴리되지 않도록 조정한다. 예컨대, ROS2 제어 노드가 1kHz로 토크 지령을 보내는데 물리 엔진이 30Hz로만 업데이트한다면, 불안정해지거나 제어기의 성능이 제대로 나오기 어렵다.

#### Isaac Sim 물리와 Real-Time Factor(RTF)

시뮬레이터가 실제 시간 대비 얼마나 빠르게 혹은 느리게 동작하고 있는지를 나타내는 척도로 RTF(Real-Time Factor)가 있다. 예컨대 시뮬레이터가 실제 1초 동안 2초치의 시뮬레이션을 진행하면 RTF가 2가 된다. Isaac Sim에서 RTF가 1 이상이면 실시간보다 빠른 진행이 가능함을 의미하고, 1 이하라면 실시간보다 느리게 도는 것이다.

ROS2와 함께 사용할 때는 RTF가 1보다 낮아도 /clock 토픽을 통해 가상 시계를 제공하므로, 노드 입장에서는 시뮬레이션 세계에서의 1초가 흐르는 동안 자체적으로는 1초가 흐른 것으로 간주한다. 이를 이용해 고성능 PC에서 시뮬레이션을 가속하고, 오프라인에서 데이터 세트를 빠르게 수집하거나 인퍼런스 테스트를 빠르게 진행하는 식으로 응용할 수 있다. 반면, 시뮬레이션이 너무 무거워져 RTF가 지나치게 낮아지면, 한 번의 시뮬레이션 테스트에 과도한 실제 시간이 소요될 수 있다.

#### 연성체(Soft Body) 시뮬레이션

Isaac Sim은 기본적으로 강체(rigid body) 물리 시뮬레이션에 최적화되어 있지만, NVIDIA PhysX의 확장 기능을 통해 연성체(Soft Body) 시뮬레이션도 일부 지원한다. 예컨대 스폰지나 고무와 같은 탄성체, 유연성이 있는 케이블 등을 표현할 수 있다.

연성체는 질점-스프링(mass-spring) 모델 또는 세분화된 물리 메쉬를 사용해 변형을 계산하며, 초기 상태에서 각 질점 간 탄성 계수와 댐핑을 정의한다. Isaac Sim에서 이 기능을 활성화하려면, PhysX Extensions 중 Soft Body 관련 플러그인이 필요한 경우가 있다.

연성체를 구현할 때는 메쉬가 충분히 정교해야 변형 거동이 자연스럽고, 내부 질점에 대한 연산량이 늘어나므로 시뮬레이션 비용이 커진다. 따라서 실제 환경에서 로봇이 다룰 물체가 연성체이거나, 케이블-호스 배선의 물리적 궤적을 모사해야 할 때 유용하다. 그러나 아직은 강체 시뮬레이션보다 제한이 많고, 실시간 성능 확보가 어렵기 때문에 복잡한 케이블 라우팅이나 유연 로봇 구조물을 세밀하게 표현하려면 특정 최적화 작업이 요구된다.

#### 천(Cloth) 시뮬레이션

의류나 로봇이 다루는 천(towel, blanket), 망토와 같은 패브릭(fabric)을 Isaac Sim에서 표현할 수도 있다. PhysX에는 별도의 Cloth 솔버가 존재하며, 삼각 메쉬 기반으로 천 모델을 정의하고, 물리 속성을 지정해 시뮬레이션한다.

천 시뮬레이션은 바람, 중력, 마찰, 충돌 등 다양한 요소를 고려하며, 특히 충돌 처리를 위해 천 메쉬와 주변 물체(로봇 링크, 테이블 등) 간 충돌 계산이 필요하다. 천 시뮬레이션이 활성화되면 서브스텝이나 솔버 이터레이션이 크게 늘어날 수 있으니, 해상도를 줄이거나 단순화된 메쉬를 사용해 성능을 조절해야 한다.

#### 입자 시스템(Particle System)과 유체

Isaac Sim의 코어 PhysX 엔진 자체는 유체(fluid)나 입자(particle) 시뮬레이션을 기본으로 제공하지 않는다. 대신 NVIDIA FleX나 Flow 등 다른 라이브러리를 연동하면 GPU 기반의 입자 시뮬레이션이 가능해진다.

물리 엔진으로 물이나 연기, 분말을 시뮬레이션하려면 오버헤드가 매우 커진다. 로봇 시나리오에서 액체를 다루는 작업(예: 음료 따르기, 페인트 분사)을 모사하려면, Isaac Sim 상에서 FleX를 사용하거나 별도의 외부 엔진을 연결할 수 있다. 다만 ROS2와의 실시간 제어가 필요한 경우, 실제 물리와는 거리가 있는 단순화된 모델(이산 이벤트나 합성된 센서 데이터)을 사용하는 편이 일반적이다.

#### 강체 파괴(Fracture) 기법

로봇이 충격을 가해 물체를 깨트리거나 분할하는 시나리오를 재현하려면 강체 파괴(Fracture) 기법이 필요하다. PhysX에는 DCC(Destruction) 기능이 있었으나, Isaac Sim에서는 아직 제한적이다. USD 스테이지 관점에서는 파괴 후 생기는 조각들을 별도의 다체로 분리해 시뮬레이션해야 하며, 높은 수준의 연산 및 모델링 부담이 따른다.

주로 시각효과용으로 사용될 가능성이 높고, 로봇 공정 시나리오에서 파손 여부 확인을 자동화할 때는 충돌 기반 이벤트 + 시각적 효과만 간단히 사용하는 편이 유리하다.

#### 힘/토크 센서 시뮬레이션

Isaac Sim에서 로봇 조인트별 힘/토크(Force/Torque) 센서를 시뮬레이션하려면 조인트에 작용하는 반작용력 혹은 충돌 시 발생하는 충격량을 가져와 ROS2 토픽으로 퍼블리시할 수 있다.

PhysX 엔진은 각 충돌 지점이나 조인트 제약에 대한 힘을 계산하며, 이 정보를 Python API나 Articulation 데이터를 통해 접근할 수 있다. 해당 값을 가지고 노이즈 모델, 오프셋, 드리프트 등을 적용해 실제 센서와 유사하게 만들 수도 있다. 로봇 팔의 엔드 이펙터에 6축 Force/Torque 센서를 부착해 물체를 쥐었을 때 힘을 측정한다거나, 충돌 시 토크를 분석해 안전 제어 알고리즘을 개발하는 식의 활용이 가능하다.

#### Domain Randomization을 통한 시뮬레이션 다양성 확보

시뮬레이션 기반 학습이나 검증에서 중요한 기법 중 하나는 Domain Randomization이다. 배경, 조명, 물체 재질(마찰, 반사율), 질량, 관성 등 다양한 환경 요인을 무작위로 변동시키며, 로봇 제어나 인식 알고리즘이 편중되지 않도록 한다. Isaac Sim에서는 Python API를 통해 다음과 같은 요소를 난수로 설정하여 매 시뮬레이션마다 다른 조건을 만든다.

* 재질(Material) 파라미터(마찰, 반발계수)
* 조명 강도, 그림자 특성
* 물체 배치 위치, 질량, 크기
* 센서 잡음, 화질 등

이 과정을 통해 실제 물리 환경의 오차나 편차를 대비할 수 있으며, ROS2 노드의 안정성과 학습 모델의 일반화 성능이 높아진다.

#### 시뮬레이션 파이프라인 최적화와 로깅

Isaac Sim에서 복잡한 물리 환경을 다룰 때는 시뮬레이션 과정을 여러 단계로 나눠 관리할 수 있다. 예컨대 대규모 실험 데이터를 얻기 위해 자동 스크립트를 작성하고, 다양한 초기 조건을 배치한 뒤 물리 시뮬레이션을 진행하며 로봇 동작 로그, 센서 로그를 저장한다.

ROS2 노드 측에서도 bag를 기록하거나, Isaac Sim API를 통해 직접 CSV나 HDF5 형식으로 기록할 수 있다. 로깅 데이터는 추후 분석이나 모델 학습에 매우 유용하므로, 시뮬레이션 실행 중 매 프레임 혹은 특정 이벤트(충돌, 목표 도달 등)에 로그를 쌓는 방식을 선호한다.

#### 안정성과 성능 확보 전략

연성체, 천, 입자, 파괴 등 고급 물리 기능을 동시에 활용하면 시뮬레이션 부하가 기하급수적으로 커질 수 있다. 이를 방지하려면 다음과 같은 전략을 사용할 수 있다.

* 가능하면 강체 모델로 단순화하거나, 충돌 체를 축소∙간소화한다.
* 연성체나 천 시뮬레이션은 주된 로봇 동작에 꼭 필요하지 않은 부분에서는 비활성화한다.
* GPU PhysX 모드나 RTX 시각화를 부분적으로 적용해 최적화한다.
* 마찰, 반발 계수, 관성 텐서가 비정상적으로 크거나 작은 값을 갖지 않도록 점검한다.

이런 최적화 과정을 거쳐야 시뮬레이션이 실시간(또는 준실시간)에 가깝게 동작하고, ROS2 제어 루프에서도 안정적으로 제어 입력과 센서 데이터를 주고받을 수 있다.

#### 고급 마찰 모델과 접촉 해석

기본 쿨롱 마찰 모델 외에도 마찰력을 보다 정교하게 다루려면 접촉 해석(Contact Mechanics)과 함께 여러 확장 모델을 고려해야 한다. 쿨롱 마찰은 정지 마찰과 운동 마찰을 구분하지만, 회전(rolling friction), 점성 마찰(viscous friction), 박스(Bauks) 모델, LuGre 모델 등의 비선형 마찰 모델이 존재한다. Isaac Sim(PhysX)에서는 일반적으로 쿨롱 마찰에 기반해 계산되지만, 물리 현장감과 시뮬레이션 목표에 따라 다음과 같은 요소를 추가적으로 살필 수 있다.

회전 마찰(rolling friction)은 구르면서 발생하는 에너지 손실을 표현한다. 간단한 방식으로는 다음과 같은 식을 적용할 수 있다.

$$
\begin{align} F\_{\text{roll}} = c\_{\text{roll}}, N  \end{align}
$$

여기서 crollc\_{\text{roll}}은 회전 마찰 계수, NN은 접촉면에서의 법선력이다. 이 식은 물리 엔진 내부에 직접 적용되는 것은 아니지만, 일부 확장이나 사용자 정의 스크립트를 통해 구현 가능하다.

접촉 해석에서 시간적 변화에 따른 동적 마찰력이 중요한 경우(예: 타이어 모델, 연성 재질과의 접촉 등), 접촉면이 탄성 변형을 보이거나 따로 동적 거동을 표현해야 할 수 있다. Isaac Sim은 표준 PhysX 기능으로 이를 충분히 커버하기 어렵다면, 별도의 커스텀 솔버(또는 OmniGraph 노드)를 구현해 접촉력을 계산하여 외력을 반영할 수도 있다.

#### 대규모 조립체(Assembly) 시뮬레이션

Isaac Sim에서 여러 로봇이나 수십 개 이상의 객체가 상호작용하는 복잡한 환경을 구성할 때, 물리 엔진 설정이 매우 중요해진다. 동적 객체의 개수가 많아질수록 충돌 감지와 솔버 계산 비용이 늘어난다. 시뮬레이션을 효율적으로 구성하기 위해서는 중복 충돌 검사를 줄이고, 필요 없는 동적 객체를 Static이나 Kinematic으로 바꾸고, 동일 객체를 여러 번 인스턴싱(instancing)하는 방식을 사용하면 이점을 얻는다.

만일 대규모 생산 라인 시나리오를 Isaac Sim 상에서 재현하고자 한다면, 필요한 구간마다 시뮬레이션을 단계적으로 구분하거나, 특정 구간만 자세히 물리를 적용하고 나머지는 단순화하여 관리할 수 있다. 예컨대 로봇셀(robot cell) 내부만 고정밀 시뮬레이션을 돌리고, 외부 물류 설비나 배경 객체는 Static으로 처리해 불필요한 물리 계산을 생략한다.

#### 분산 시뮬레이션과 병렬 처리

Omniverse 기반 Isaac Sim은 멀티 GPU나 클라우드 환경에서 분산 시뮬레이션을 수행할 수 있다. 복수의 시뮬레이션 인스턴스를 병렬로 띄워 자동화 테스트(Regression Test)나 정책 탐색(Policy Search)을 진행하기도 한다. 이 경우, 물리 엔진 내부의 멀티쓰레딩과 GPU 가속 기능을 활용해 시뮬레이션 속도를 높일 수 있다.

병렬 시뮬레이션 시에는 각 인스턴스 간 물리 파라미터를 공유하거나, Domain Randomization을 다르게 적용하면서 로봇 제어 알고리즘의 범용성을 높이는 식으로 응용한다. Isaac Sim은 별도의 Isaac Orchestration 기능이나 Python 스크립트를 통해 여러 시뮬레이션 프로세스를 띄우고, ROS2 각 노드를 연결해 집단 테스트를 수행할 수 있다.

#### Articulation vs. 일반 Rigid Body 조인트

Isaac Sim의 PhysX에는 Articulation이라는 고급 다체 역학(multi-body dynamics) 프레임워크가 존재한다. 일반 Rigid Body로 조인트를 하나씩 붙이는 방식도 가능하지만, 복잡한 로봇은 Articulation을 사용해 내부 제약을 일괄적으로 풀이하면 해석 정확도와 안정성이 좋아진다. Articulation은 다음과 같은 특징을 갖는다.

* 계층 구조를 갖춘 트리 형태의 링크들을 묶어, 병진∙회전 운동 및 조인트 제약을 동시에 처리한다.
* 조인트에 PID 제어, 힘 제한, 각도 제한을 간단히 적용할 수 있다.
* TGS(Temporal Gauss-Seidel) 등 고급 알고리즘을 사용해 조인트 결합이 많은 로봇에서도 높은 안정도를 유지한다.

일반 조인트와 Articulation의 가장 큰 차이는 내부 해석 방식이다. 일반 Rigid Body 조인트는 한 프레임마다 분산된 제약 풀을 실행하여 충돌∙조인트를 처리하는 반면, Articulation은 로봇 전체의 강체 연결을 하나로 묶어 더 정확한 역학 계산을 수행한다. 다만, Articulation은 트리 구조만 지원하며, 닫힌 루프(closed-loop) 기구는 별도의 처리나 보조 링크가 필요할 수 있다.

#### PhysX Visual Debugger(PxPvd)와 Isaac Sim

PhysX Visual Debugger(PxPvd)는 물리 엔진의 내부 정보를 추적하는 데 유용한 툴이다. Isaac Sim 초기 버전에서 PxPvd를 연결해 충돌체, 조인트, 힘, 접촉점 등에 관한 물리 엔진 레벨의 디버깅 정보를 확인할 수 있었다. 현재 Omniverse 환경에서 이 기능을 얼마나 직접 지원하는지는 버전에 따라 다르지만, 확장 기능이나 별도의 설정으로 연결 가능한 경우가 있다.

PxPvd를 활용하면, 물리 엔진 내부에서 어떤 순서로 충돌이 해결되고, 조인트 제약이 어떤 값을 갖는지를 세밀하게 관찰할 수 있다. 시뮬레이션 중 발생하는 비정상 현상의 원인을 찾거나, 조인트가 예상과 다르게 동작할 때 내부 토크 계산 과정을 살펴볼 수 있다. Isaac Sim의 GUI 디버깅 기능과 PxPvd를 함께 사용하면 더욱 풍부한 진단 정보를 얻을 수 있다.

#### 사용자 정의 물리 확장: OmniGraph와 Python

Isaac Sim의 OmniGraph는 노드 기반 프로그래밍 환경으로, 시뮬레이션 과정에서 발생하는 이벤트나 데이터를 실시간 처리할 수 있다. 이를 통해 물리 단계가 업데이트될 때마다 커스텀 노드를 실행하여, 특정 객체에 추가 힘을 인가하거나 센서 모델을 계산하고, 결과를 ROS2 토픽으로 발행하는 식의 워크플로우를 구현한다.

Python 확장을 작성하면 물리 엔진의 단계별(on\_physics\_step 등) 콜백을 받아 원하는 로직을 수행할 수 있다. 예를 들어, 물체가 특정 위치 이하로 떨어지면 제거하거나, 로봇에 가해지는 충돌력을 측정해 이벤트를 발생시키는 자동화 스크립트를 쉽게 만들 수 있다. 이 사용자 정의 스크립팅은 Isaac Sim을 단순히 시각화 도구가 아닌 실제 로봇 실험 환경의 대체재로 확장시킨다.

#### Isaac Gym, Isaac Cortex와의 연계

Isaac Sim은 로보틱스 시뮬레이션을 포괄적으로 다루지만, 강화학습(RL)이나 대규모 시뮬레이션 병렬화에 집중한 Isaac Gym과는 용도가 다르다. Isaac Gym은 로봇 RL 훈련에 초점을 맞추었고, 수천 개 환경을 GPU 병렬 처리로 동시에 시뮬레이션하는 기능이 특화되어 있다. Isaac Sim은 고품질 렌더링과 Omniverse 생태계 통합이 강점이며, ROS2와의 결합, 센서 시뮬레이션, 상호작용 UI가 주된 특징이다.

Isaac Cortex는 로봇 태스크 그래프(Task Graph)를 구성하고, 다양한 모션 프리미티브를 조합하여 고수준 로봇 동작을 구현할 수 있는 플랫폼이다. Isaac Sim에서 이동 로봇이나 매니퓰레이터를 시뮬레이션하고, Isaac Cortex를 통해 로봇 태스크를 오케스트레이션하는 식의 연동도 가능하다. 이처럼 NVIDIA Isaac 스택은 각 모듈 간 API 연계를 통해 점진적으로 통합 워크플로우를 구축할 수 있다.

#### 더 높은 사실성(Physical Accuracy) vs. 실시간성(Real-time)

시뮬레이션에서 사실성과 실시간성은 종종 충돌한다. 실제와 최대한 유사하게 하려면 시뮬레이션 해상도를 높이고, 더 많은 서브스텝과 정밀한 충돌 메쉬, 복잡한 물성 모델을 사용해야 한다. 그러나 이는 계산 부하를 높여 실시간성을 떨어뜨린다. 따라서 용도에 따라 적절한 균형점을 찾는 것이 핵심이다.

로봇 개발 초기 단계에서 궤적 검증, 충돌 위험 평가 등을 목표로 할 땐 어느 정도 단순화된 모델로 충분히 빠르고 유연한 시뮬레이션을 선호한다. 반면 시뮬레이션 기반 제어 튜닝이나 정밀 작업 검증, 또는 물리 기반 합성 데이터 생성이 필요하면 사실성에 좀 더 무게를 두고 리소스를 투자해도 좋다. Isaac Sim은 다양한 스케일에 대응할 수 있도록, GUI∙Python∙OmniGraph 레벨에서 폭넓은 설정을 제공한다.

#### 멀티 로봇 시나리오와 상호 충돌 관리

Isaac Sim에서 여러 대의 로봇을 동시에 시뮬레이션하려면, 물리 엔진은 각 로봇의 조인트 제약 및 충돌 검사를 모두 병렬 처리해야 한다. 로봇 개수가 늘어날수록 충돌 검사(특히 로봇끼리 서로 충돌하지 않도록 필터링하는 과정)에 드는 연산량이 증가한다. 이때 다음 방법으로 효율성을 높일 수 있다.

* **그룹별 충돌 필터링**: 로봇 간 충돌이 현실적으로 잘 일어나지 않거나, 특정 상황에서만 감지하면 될 때는 충돌 필터링을 통해 과도한 접촉 계산을 피한다.
* **Articulation 활용**: 각 로봇을 별도의 Articulation으로 처리하면, 내부 조인트 계산이 빠르고 안정적이며, 로봇 간 충돌만 Broad Phase 단계에서 효율적으로 확인한다.
* **서브스텝 및 솔버 설정의 동적 조절**: 멀티 로봇이 협동 작업 등 복잡한 상호작용을 하는 시점에만 서브스텝 수를 일시적으로 증가시키고, 상대적으로 간단한 이동 구간에서는 감소시켜 최적화할 수 있다(Adaptive Time Stepping).

#### 자율주행(Automotive) 및 이동 로봇 시뮬레이션

이동 로봇(AMR, AGV)이나 자율주행 차량(Automotive) 시뮬레이션에서는 바닥 면과 휠(바퀴)의 접촉, 노면 마찰, 서스펜션 기구(차량의 경우) 등이 중요하다. Isaac Sim은 로봇 분야에 특화되어 있으나, 휠 모델을 Revolute 조인트로 단순화하거나, 별도의 차량 모델(PhysX Vehicle SDK)을 활용해 물리 기반 이동을 시뮬레이션할 수 있다.

* **PhysX Vehicle SDK**: 차량 서스펜션, 타이어 마찰, 엔진 구동계 모델 등을 포함하여 비교적 현실감 있게 자율주행 차량의 동작을 모사할 수 있다. 현재 Isaac Sim과의 통합 상태는 버전마다 다르므로, 자동차용 프로젝트에서는 별도의 예제나 확장 기능이 있는지 확인해야 한다.
* **휠 로봇 시뮬레이션**: 일반적으로 바퀴를 Kinematic Joint로 처리한 뒤, 회전 속도를 인가하여 이동시키거나, 간단히 회전 마찰 계수 등을 적용해 동적 효과를 표현할 수 있다. 로봇의 주행 시나리오에서 SLAM, Navigation 같은 ROS2 패키지와 연동하면, Isaac Sim 내에서 현실적인 맵 구축 및 경로 계획을 테스트할 수 있다.

#### 디지털 트윈(Digital Twin)과 실제 하드웨어 매핑

Isaac Sim은 엔비디아 Omniverse 플랫폼의 일부로, 물리 환경과 실제 하드웨어를 1:1로 매핑하는 ‘디지털 트윈’ 시나리오를 지원한다. 이를 위해서는 CAD 모델로부터 정확한 질량, 관성, 조인트 파라미터를 가져와야 하며, 실제 제조사에서 제공하는 로봇 데이터 시트(마찰, 모터 스펙 등)도 반영해야 한다. 또한 센서(카메라, LiDAR, IMU) 측정값과 실제 하드웨어 센서 값이 일치 혹은 유사하게 나오도록, 해상도와 노이즈 모델을 정교하게 구성해야 한다. 이런 과정을 거치면 실제 로봇에서 작동할 ROS2 노드를 거의 그대로 Isaac Sim 환경에서 구동해도 유사한 거동을 기대할 수 있다.

#### USD 기반 확장과 협업

Isaac Sim은 USD(Universal Scene Description) 기반으로 장면을 구성하므로, 여러 협업자가 동시에 물리 파라미터를 수정하고, 로봇 모델을 업데이트하며, 특정 지점의 충돌체만 교체할 수도 있다. 팀 단위로 대규모 로봇 프로젝트를 진행할 때는 Omniverse Nucleus 서버를 통해 버전 관리를 하고, 여러 사람이 Isaac Sim의 Stage를 공동 편집하면서 물리 테스트를 할 수 있다.

#### 물리(Physics) 시뮬레이션 디버그 팁 정리

* **Collision Debug**: 겹침 현상이나 예기치 않은 충돌이 의심되면, ‘Collisions(Contacts) 시각화’를 활성화해 실제 접촉 점을 확인한다.
* **Joint Visual Debug**: 조인트 축, 조인트 제한, Articulation 트리를 시각화해 링크들이 올바르게 연결되었는지 본다.
* **Console Log**: Isaac Sim 콘솔에 물리 오류나 경고(예: “Non-convex geometry” 등)가 표시될 수 있으니 참고한다.
* **Mesh Simplification**: 복잡한 CAD 모델을 그대로 가져오면 관성 텐서가 이상해지거나 충돌 계산이 부담된다. 필요 시 ‘Convex Decomposition’, ‘Mesh Simplification’을 수행한다.
* **Physics Step Profiling**: Isaac Sim에서 물리 연산 시간과 렌더링 시간을 분리하여 측정할 수 있으므로, 물리 솔버가 병목인지 확인하고, Solver Iteration이나 서브스텝 수를 재조정한다.

#### Isaac Sim 최신 버전 참고 사항

* 버전에 따라 Physics Scene의 설정 메뉴 구조나 API가 조금씩 달라질 수 있으므로, NVIDIA의 공식 Isaac Sim Release Note와 Documentation을 수시로 확인한다.
* PhysX 소버 알고리즘 선택, GPU 가속 지원 여부, Articulation 기능은 버전별로 호환성이 다를 수 있다.
* ROS2 Humble용 패키지(isaac\_ros\_\* 시리즈 등)도 Isaac Sim과 연동하는 예제나 튜토리얼이 계속 업데이트되므로, 호환성 매트릭스를 확인한다.

***

이상으로 Isaac Sim 물리(Physics) 시뮬레이션 기초 설정부터 고급 주제까지 폭넓게 다루었다. 이를 활용해 다양한 로봇 및 시나리오를 보다 정확하고 효율적으로 시뮬레이션할 수 있을 것이다.
