Engineering Notes

로봇 시뮬레이션을 만들며 얻은 것들

물리·강화학습·센서·내비게이션·표준 — imSim 엔지니어링 팀의 기술 노트. 실제 런·커밋·실측 데이터에 근거한 75편의 글.

AMR 내비게이션 입문

12

Occupancy Grid란 무엇인가 — 센서가 본 세계를 격자로 그리는 법

자율주행 로봇이 환경을 '벽/빈공간/미지'의 2D 확률 격자로 표현하는 occupancy grid의 기본 개념과, imSim이 환경을 만들 때 이 격자를 자동 생성하는 방법.

Nav2mappingoccupancy-gridAMR

Static Map이 Nav2 Costmap으로 들어가기까지 — 벽을 아는 지도 vs 빈 지도

점유 격자(occupancy grid)가 어떻게 Nav2가 읽는 map으로 변환되어 static layer costmap이 되는지, 그리고 '벽을 아는 지도'와 '전부 free인 빈 지도'의 차이가 주행을 어떻게 가르는지.

Nav2costmapstatic-mapmap-server

Costmap 2D 완전 해부 — Static · Obstacle · Inflation 세 층의 합성

Nav2 costmap이 단일 지도가 아니라 static·obstacle·inflation 여러 레이어를 쌓아 만들어지는 구조와 각 층의 역할, 그리고 '장애물 층을 빼자 로봇끼리 서로 통과한' 실제 버그.

Nav2costmaplayersobstacle-layer

Inflation이 뭔가 — 로봇을 '점'으로 만들기 위해 장애물을 부풀린다

장애물 주변에 cost 그라데이션을 둘러 로봇 반경을 보상하는 inflation의 원리. 로봇을 '점'으로 다루기 위한 트릭과, 이기종 플릿에서 단일 반경이 만드는 한계.

Nav2inflationcostmaprobot-radius

Global vs Local Costmap — 큰 그림 경로와 즉석 회피의 분업

전역 경로계획용 global costmap과 실시간 회피용 local costmap의 역할 분담, 동적 범위 산정, 그리고 다중 로봇에서 두 costmap을 모두 챙겨야 하는 이유.

Nav2costmapglobal-plannerlocal-planner

Nav2 Lifecycle과 Behavior Tree — 내비게이션 스택은 어떻게 깨어나는가

Nav2 서버들이 정해진 순서로 활성화(lifecycle)되고, bt_navigator가 Behavior Tree로 경로계획·추종·복구를 오케스트레이션하는 구조. 그리고 활성화 순서가 어긋날 때 나는 실제 오류.

Nav2lifecyclebehavior-treebt-navigator

경로 계획기 NavFn / Smac — costmap 위에 최단 경로를 긋는 법

planner가 global costmap 위에서 출발→목적지 최단 경로를 푸는 원리(NavFn=Dijkstra/A* 계열, Smac=격자/Hybrid-A*)와, costmap이 목표를 못 덮을 때 나는 'Off Grid' 실패.

Nav2plannerNavFnSmac

RPP 컨트롤러 — Pure Pursuit가 경로를 바퀴 속도로 바꾸는 법 (그리고 0.05에 갇힌 회전 버그)

Regulated Pure Pursuit가 lookahead로 경로를 cmd_vel로 바꾸는 원리와, odom 가속 클램핑이 회전 속도를 0.05 rad/s에 영구히 가둔 실제 디버깅 사례.

Nav2controllerRPPpure-pursuit

Recovery Behavior — 막혔을 때 로봇이 스스로 빠져나오는 행동들

경로 추종이 실패하거나 로봇이 막혔을 때 spin·backup 같은 복구 행동이 어떻게 트리거되고, Behavior Tree의 복구 분기로 이어지는지. 그리고 플릿 차원의 STOP 처리.

Nav2recoverybehavior-treestuck

VFH+ 반응형 회피 — costmap 없이 polar histogram으로 틈을 찾는 법

Nav2 없이도, 또는 동적 장애물이 많을 때 쓰는 Vector Field Histogram의 3단계 데이터 축소 원리. occupancy grid를 polar histogram으로 줄여 '지나갈 틈'을 직접 고른다.

Nav2VFHreactiveobstacle-avoidance

Nav2가 Isaac Sim과 ROS2로 연결되는 방식 — TF, cmd_vel, 그리고 namespace

시뮬레이터(Isaac PhysX)와 Nav2 사이의 ROS2 토픽·TF 다리, 멀티 로봇 namespace 격리, 그리고 시뮬 물리의 odom 지연이 Nav2 폐루프에 미치는 영향.

Nav2Isaac-SimROS2TF

AMR 안전 시뮬레이션 — 내비게이션 스택이 ISO 3691-4 인증 KPI로 이어지기까지

지금까지의 내비게이션 개념(점유격자·costmap·planner·controller·회피)이 실제 제품인 AMR 안전검증에서 collision·TTC·near-miss 같은 ISO 3691-4 KPI로 어떻게 측정되는지.

AMRsafetyISO-3691-4KPI

Isaac Sim 작동 원리

10

Isaac Sim 런이 부팅되는 순서 — SimulationApp이 먼저다

Isaac Sim에서 USD·PhysX·RTX를 쓰려면 SimulationApp(Kit 런타임)을 가장 먼저 띄워야 하고, 그 뒤에야 omni 모듈을 import할 수 있다는 강한 순서 의존성.

Isaac-SimOmniverseUSDPhysX

USD로 씬을 조립한다 — Stage · Prim · Reference

Isaac Sim의 씬이 단일 3D 파일이 아니라 USD stage 위의 prim 트리이며, 환경과 로봇은 reference로 끼워 넣고 장애물은 기본 도형으로 정의한다는 것.

Isaac-SimOpenUSDstageprim

Physics Scene과 솔버 — 물리가 씬에 붙는 법

중력·충돌·솔버 반복 같은 물리 설정이 씬 안의 PhysicsScene prim에 담기고, 그 설정이 모든 강체로 퍼지는 방식. 그리고 GPU dynamics가 켜지는 시점.

Isaac-SimPhysXphysics-scenesolver

물리 200Hz, 렌더 60Hz를 분리하는 이유 — substeps

물리를 한 루프에 여러 번(substep) 밟고 렌더는 가끔만 하는 이유 — 안정성과 성능을 동시에 잡는 timestep 분리. 다리 로봇이 60Hz에서 불안정한 이유도 여기 있다.

Isaac-SimPhysXtimestepsubsteps

DriveAPI로 바퀴를 굴린다는 것 — 텔레포트가 아니라 토크

바퀴·관절이 articulation의 joint이고, DriveAPI(목표 속도 + 강성/감쇠)로 PhysX가 토크를 만들어 실제로 굴린다는 것. 위치를 직접 옮기는 kinematic과의 근본 차이.

Isaac-SimPhysXDriveAPIarticulation

OmniGraph로 ROS2와 잇기 — 센서를 토픽으로 내보내는 비주얼 그래프

센서→토픽 발행, /cmd_vel→구동을 OmniGraph(비주얼 컴퓨트 그래프)의 노드 체인으로 구성하는 방식. 그리고 외부 ROS2 명령 수신에서 자주 막히는 함정.

Isaac-SimOmniGraphROS2sensors

센서를 단다 — PhysX LiDAR와 RTX LiDAR, 카메라, IMU

센서가 씬의 prim으로 생성되고, RTX LiDAR는 렌더 결과를 점군으로 뽑는다는 것. 그리고 PhysX LiDAR와 RTX LiDAR의 근본 차이.

Isaac-SimsensorsLiDARRTX

헤드리스인데 왜 렌더가 켜지나 — headless ≠ no-render

화면 없이 돌려도(headless) HLS 스트리밍·영상 녹화·RTX 센서·합성 데이터 때문에 렌더가 필요할 수 있다는 것 — '헤드리스 = 렌더 끔'이라는 흔한 오해.

Isaac-SimheadlessrenderingRTX

Fresh 모드 vs Daemon 모드 — 빠른 재사용의 유혹과 상태 오염

런마다 시뮬레이터를 새로 띄우는 Fresh 모드와, 켜둔 채 재사용하는 Daemon 모드. 후자가 빨라 보이지만, 런 사이 상태 오염이 검증의 신뢰를 무너뜨린다.

Isaac-Simprocess-isolationstatevalidation

시뮬레이션 런 한 번의 일생 — 제출부터 영상·KPI까지

버튼 한 번으로 시작된 시뮬레이션 런이 큐·워커·러너를 거쳐 영상과 KPI로 끝나기까지의 전체 수명 주기. 각 단계가 무엇을 하고 어디서 산출물이 나오는가.

Isaac-Simorchestrationpipelinelifecycle

Physical AI 기초

5

Physical AI란 무엇인가 — 디지털을 넘어 물리 세계로 나온 지능

텍스트·이미지를 다루는 디지털 AI를 넘어, 물리 세계를 인지하고 그 안에서 행동하는 Physical AI. 왜 시뮬레이션이 그 핵심 인프라인가.

physical-aiembodied-airoboticssimulation

OpenUSD 씬 컴포지션 — 레이어·레퍼런스·페이로드로 월드를 조립하기

USD가 단일 3D 파일이 아니라 '비파괴 레이어 합성 시스템'이라는 것 — 같은 자산을 여러 시나리오가 충돌 없이 재사용하는 원리(레이어·레퍼런스·페이로드·variant·LIVRPS).

OpenUSDcompositionlayersLIVRPS

가짜 빛으로 진짜 센서를 만들다 — RTX 기반 EO/IR/LiDAR/Radar/Sonar

다중 도메인 센서(EO/IR/LiDAR/Radar/Sonar)가 물리 기반 렌더링과 광선·음선 추적으로 합성 데이터를 만드는 방식과 모달리티별 차이.

RTXsensorsLiDARradar

디지털 트윈은 3D 모델이 아니다 — 살아 동기화되는 쌍둥이

디지털 트윈은 멋진 3D 모델이 아니라, 실제 시스템과 살아 동기화되는 가상 쌍둥이다. 센서가 트윈을 갱신하고, 트윈이 미래를 예측하는 양방향 고리가 핵심이다.

digital-twinOpenUSDsimulationfacility

시뮬에서 배운 정책이 로봇 위 칩으로 — Edge AI 배포의 현실

거대한 GPU에서 학습한 정책을, 로봇에 달린 작은 칩에서 실시간으로 돌리기까지. 양자화·추론 최적화·지연·전력의 제약, 그리고 시뮬레이션이 그 다리를 어떻게 검증하나.

edge-aideploymentTensorRTquantization

디버깅 전쟁 일지

7

함정 7척을 마리아나 해구로 가라앉힌 한 줄 — substring 매칭의 함정

수면 부력 셋업이 식별자에 'UUV'가 들어있는지 하나로 판정했고, 잠수함 식별자엔 'UUV'가 없다는 이유로 함대 전체의 부력이 통째로 꺼져 7척이 -2989m로 침몰한 사건.

debuggingbuoyancymaritimewar-story

mission_success=1은 PASS가 아니다 — strict_pass 게이트의 탄생

수백 개 런이 'mission_success=1'로 성공 표시됐지만, 실제 산업 등급 grasp는 단 한 건이었다. 이진 성공 플래그가 어떻게 false PASS의 온상이 됐고, 그걸 막는 strict_pass 게이트는 어떻게 생겼나.

debuggingKPIfalse-passvalidation

joint 속도가 한도의 40배였다 — peak KPI가 숨긴 12,078 dps

물건을 집어 든 '최대 높이'만 보는 peak KPI는 로봇팔이 이동 중 물건을 떨어뜨려도 PASS를 줬다. 궤적(trajectory) KPI를 심자, 'PASS'였던 셀의 절반이 joint 속도 한도의 40배로 날뛰고 있었다.

debuggingmanipulatorKPItrajectory

정적 분석은 '불가능'이라 했지만, 실측은 렌더됐다 — Gaussian Splatting in Isaac Sim

코드 분석상 'Gaussian Splatting은 이 빌드에서 불가능'이라는 결론이 나왔다. 그런데 실제로 돌려 보니 사진 같은 실내가 렌더됐다. 추측이 아니라 실측이 진실을 뒤집은 교과서적 사례.

debugginggaussian-splattingNuRecinstrument-first

추측형 게이트가 멀쩡한 워크로드를 죽인 나흘 — silent reject의 함정

며칠째 '옛날 잘 돌던 런이 다시 안 돈다'였다. 근본 원인은 며칠 전 추가된 추측성 사전 차단 게이트가 멀쩡한 런을 silent하게 거부한 것 — 에러 메시지가 단 한 줄도 없었다.

debugginginfrafail-louddispatch

차량 한 대가 -63°로 뒤집혔다 — 물리 버그로 위장한 환경 버전 갈림

검증까지 끝낸 차량 호송 시나리오에서 어느 날 한 대가 -63°로 전복했다. 물리를 의심하며 한참 헤맸지만, 범인은 환경 DB가 검증된 평탄 지형에서 가파른 버전으로 조용히 바뀐 것이었다.

debuggingenvironmentconfigregression

차가 차를 통과한다 — ORCA 회피와 PhysX 충돌을 혼동한 대가

차량끼리 부딪혀도 그냥 통과하고, 장애물도 뚫고 지나갔다. 두 개의 충돌 개념(ORCA 사전 회피 vs PhysX 물리 접촉)을 혼동한 데서 비롯된 버그를 풀어낸 기록.

debuggingcollisionPhysXORCA

디버깅 철학

5

Silent Fail 박물관 — fail-loud가 디버깅의 90%인 이유

진단 print 자체에 오타가 있었고, 그게 거대한 try/except에 먹혀 HUD 전체가 안 그려졌다. 빈 dict, silent no-op, '조용히 넘어가기' 한 줄이 어떻게 전체 기능을 죽이는가.

debuggingfail-loudphilosophyerror-handling

막다른 길을 기록하라 — 같은 실패를 두 번 하지 않는 법

복잡한 시스템에서는 '이미 시도했다가 실패한 접근'을 또 시도하는 데 시간을 가장 많이 낭비한다. 막다른 길을 명시적으로 기록해, 같은 실패를 반복하지 않는 방법.

debuggingphilosophypostmortemknowledge

절대 수치는 거짓말한다 — 레퍼런스 대비로 보고하라

'진동이 0.5m로 안정됐다'는 좋은 보고일까? 절대 수치만으로는 알 수 없다. 모든 수치를 레퍼런스(기준선) 대비로 표현해야 의미가 생긴다.

debuggingreportingKPIcommunication

당신이 고친 그 파일, 실제로 실행되는 게 맞나 — 프로덕션 경로로 검증하라

런처 파일을 고쳐 테스트했는데 실제 프로덕션은 다른 경로로 실행된다면, 당신은 아무것도 검증하지 않은 것이다. 검증은 반드시 실제 실행 경로를 통해야 한다.

debuggingvalidationproductionphilosophy

'거의 다 됐다'가 가장 위험하다 — closure의 진실성

'나사 몇 개만 빼고 다 했다'는 보고가 가장 위험하다. '완료'를 선언하기 전에 충족해야 할 조건과, 누락을 숨기지 않고 드러내는 것이 왜 신뢰의 핵심인가.

engineeringhonestydefinition-of-donereporting

RL & World Models

5

Sim-to-Real 격차 — 시뮬에선 되는데 실물에선 안 되는 이유, 그리고 정직한 측정

시뮬레이션에서 완벽하던 정책이 실제 로봇에서 무너지는 Sim-to-Real 격차의 근원과, 그 격차를 좁히는 도메인 무작위화, 그리고 격차를 '정직하게' 측정하는 법.

sim2realdomain-randomizationRLvalidation

World Foundation Model로 합성 데이터를 찍어내다 — NVIDIA Cosmos와 data flywheel

실제 로봇 데이터는 비싸고 적다. 물리를 이해하는 영상 생성 모델(World Foundation Model)로 합성 데이터를 대량 생산해 인지·정책을 학습시키는 data flywheel의 구조.

Cosmosworld-modelsynthetic-dataphysical-ai

작업마다 정책을 새로 학습하던 시대의 끝 — VLA 파운데이션 모델과 GR00T

물건 집기 따로, 문 열기 따로 정책을 학습하던 방식에서, 하나의 모델이 보고·듣고·행동하는 VLA 파운데이션 모델로. NVIDIA GR00T의 dual-system 구조와 시뮬레이션의 역할.

VLAGR00Tfoundation-modelhumanoid

GPU에서 수천 개의 로봇을 동시에 학습시키기 — Isaac Lab 병렬 강화학습

강화학습이 느린 이유와, 수천 개의 환경을 GPU에서 동시에 굴려 학습을 가속하는 텐서 기반 시뮬레이션의 작동 방식.

RLIsaac-LabGPUPPO

RL 정책이든 cuMotion이든 같은 구멍에 꽂힌다 — PolicyAdapter Protocol

로봇을 움직이는 '두뇌'는 RL 정책일 수도, 고전 모션 플래너일 수도, 파운데이션 모델일 수도 있다. 어떤 두뇌든 같은 인터페이스로 꽂히게 하는 PolicyAdapter Protocol의 설계.

policyadapterprotocolarchitecture