NVIDIA Isaac Replicator를 정확히 이해하기 위해서는, 이 기술이 독립적인 도구가 아니라 NVIDIA의 다층적 로보틱스 플랫폼 내에 깊숙이 통합된 특수 기능이라는 점을 먼저 파악해야 합니다. 이 에코시스템은 시뮬레이션에서 현실 세계로, 그리고 다시 시뮬레이션으로 이어지는 선순환 구조를 구축하도록 설계되었습니다. Replicator의 역할과 가치는 이러한 거시적인 맥락 속에서 비로소 명확해집니다.
NVIDIA Omniverse는 로보틱스 도구 자체가 아니라, 로보틱스 도구들이 실행되는 일종의 ‘운영체제’와 같은 역할을 하는 협업 및 시뮬레이션 플랫폼입니다.1 이는 실시간, 물리 기반 3D 콘텐츠 제작과 시뮬레이션을 위한 핵심 인프라를 제공하며, Replicator를 포함한 Isaac 에코시스템 전체의 근간을 이룹니다.
Isaac Sim은 Omniverse 플랫폼 위에 구축된 대표적인 레퍼런스 애플리케이션으로, 특히 로보틱스 시뮬레이션에 특화되어 있습니다.1 이곳이 바로 Replicator가 주로 사용되는 환경입니다. Isaac Sim은 로보틱스 개발자를 위해 Omniverse의 범용적인 복잡성을 일부 추상화하고, 휴머노이드, 매니퓰레이터, 자율이동로봇(AMR)과 같은 사전 구축된 로봇 모델, 카메라, LiDAR, IMU 등의 센서 모델, 그리고 ROS/ROS 2 통합과 같은 로보틱스 특화 기능을 제공합니다.6
Isaac Sim은 크게 세 가지 핵심 워크플로우를 지원합니다:
Isaac Lab은 Isaac Sim 위에 구축된 오픈소스 프레임워크로, 로봇 학습 연구, 특히 강화학습(RL)을 단순화하고 가속화하기 위해 설계되었습니다.7 이 프레임워크는 이전에 Isaac Orbit으로 알려졌으며, 현재는 단종된 Isaac Gym의 후속 버전입니다.7 Isaac Lab은 RL 훈련에 바로 사용할 수 있는 “배터리 포함(batteries-included)” 환경, 태스크, 로봇 모델을 제공하며, Isaac Sim의 빠르고 병렬화된 시뮬레이션 능력을 최대한 활용합니다.9
Cosmos는 이 에코시스템에서 가장 미래 지향적인 최신 구성 요소입니다. 이는 Omniverse 및 Isaac Sim과 함께 작동하여 데이터 생성과 월드 모델링을 강화하는 생성형 AI 파운데이션 모델 스위트입니다.1 Cosmos는 물리 시뮬레이션을 직접 수행하지는 않지만, 대신 생성형 AI를 사용하여 시뮬레이션 콘텐츠를 생성하고 향상시킵니다. 예를 들어, 텍스트 프롬프트로부터 다양한 3D 환경을 생성하거나 시뮬레이션 결과물을 초현실적인 이미지로 변환하여 ‘심투리얼(sim-to-real)’ 격차를 더욱 줄이는 역할을 합니다.1
이러한 구성 요소들의 관계를 분석하면 NVIDIA의 전략적 방향성을 파악할 수 있습니다. 첫째, Omniverse, Isaac Sim, Replicator, Cosmos의 긴밀한 통합은 강력하고 자기 강화적인 개발 루프를 형성합니다. 예를 들어, 로봇 인식 모델 훈련이 필요한 개발자는 (1) 현실 세계 데이터의 한계로 인해 합성 데이터의 필요성을 느끼게 되고, (2) 시뮬레이션 환경을 제공하는 Isaac Sim을 사용하며, (3) 그 안에서 Replicator로 합성 데이터를 생성합니다. (4) 더 나아가 Cosmos를 이용해 데이터의 다양성과 사실성을 높일 수 있으며, (5) 제어 정책 훈련이 필요할 경우 Isaac Sim 내에서 실행되는 Isaac Lab을 활용합니다. 이 모든 과정은 USD와 Nucleus를 기반으로 하는 Omniverse 플랫폼 위에서 이루어집니다.4 이는 강력한 수직 통합 스택을 형성하며, 이는 개방형 대안인 Gazebo/ROS의 모듈식 철학과 대조됩니다. 이러한 구조는 사용자에게 강력한 기능을 제공하는 동시에 NVIDIA 생태계에 대한 의존성을 높이는 결과를 낳습니다.
둘째, 포토리얼리즘과 하드웨어 요구사항 사이에는 명확한 인과 관계가 존재합니다. NVIDIA의 핵심 역량은 GPU 기술이며, Isaac 에코시스템은 RTX 렌더링을 통해 이러한 강점을 극대화하도록 설계되었습니다.3 이 고충실도 시뮬레이션은 막대한 계산 비용을 수반하며, 이는 고사양 NVIDIA RTX GPU를 필수적으로 요구하는 직접적인 원인이 됩니다.11 이러한 하드웨어 의존성은 접근성의 장벽을 높이며, 사용자 보고에 따르면 강력한 하드웨어를 갖추더라도 소수의 에이전트를 시뮬레이션할 때는 MuJoCo와 같은 그래픽 집약도가 낮은 시뮬레이터에 비해 성능이 저하될 수 있습니다.11 결국 시각적 충실도와 계산 성능/접근성 사이에는 본질적인 트레이드오프가 존재하며, Isaac Sim은 충실도를 우선시하는 선택을 한 것입니다.
Isaac Replicator의 내부 작동 방식을 이해하기 위해, 그 구성 요소를 분해하고 데이터 흐름을 추적해 볼 필요가 있습니다. 이를 통해 씬 정의부터 최종 주석 데이터 출력까지의 과정을 명확히 파악할 수 있습니다.
Replicator는 “데이터 중심(data-centric)” AI 개발 철학을 구현합니다. 이는 모델의 하이퍼파라미터를 끝없이 조정하는 대신, 훈련 데이터셋 자체를 반복적으로 개선하여 모델 성능을 향상시키는 데 초점을 맞추는 방식입니다.3 Replicator는 이러한 반복적인 데이터 정제를 가능하게 하는 핵심 도구입니다.
Replicator는 합성 데이터 생성을 위해 6개의 핵심 구성 요소로 이루어진 파이프라인을 사용합니다.3
시맨틱 스키마 편집기 (Semantics Schema Editor):
랜더마이저 (Randomizers):
omni.syntheticdata 확장 기능:
주석 생성기 (Annotators):
omni.syntheticdata로부터 원시 데이터(AOV)를 입력받아 DNN 훈련을 위한 정밀한 레이블이 지정된 주석으로 처리하는 시스템입니다.3시각화 도구 (Visualizer):
라이터 (Writers):
기능: 파이프라인의 마지막 단계로, 주석 생성기로부터 주석 처리된 데이터를 받아 특정 DNN 훈련 프레임워크에 적합한 형식으로 디스크에 저장합니다.3
예시: 간단한 형식을 위한 BasicWriter, 널리 사용되는 KITTI 데이터셋 형식을 위한 KittiWriter 18, 그리고 직접적인 온라인 훈련을 위한
PytorchWriter와 같은 특수 라이터가 있습니다.19
Replicator의 6개 구성 요소 아키텍처는 의도적으로 모듈화되고 분리되어 있습니다. 데이터 생성 과정은 (1) 애셋 준비(시맨틱), (2) 씬 변형(랜더마이저), (3) 렌더러의 원시 데이터 생성(omni.syntheticdata), (4) 원시 데이터의 레이블 해석(주석 생성기), (5) 출력 형식 지정(라이터)의 순서로 진행됩니다. 각 단계는 논리적으로 구별되는 단위이며, 이러한 분리 구조 덕분에 Replicator는 확장성을 갖습니다.3 개발자는 전체 Replicator 소스 코드를 수정하지 않고도 새로운 유형의 그라운드 트루스를 위한 맞춤형 주석 생성기나 새로운 ML 프레임워크를 위한 맞춤형 라이터를 만들 수 있습니다.
또한, 최종 사용자에게 항상 보이지는 않지만 OmniGraph는 이 모든 과정의 기저에 있는 실행 엔진입니다. Replicator YAML 16이나 Python 스크립트와 같은 사용자 인터페이스는 원하는 데이터 생성 파이프라인을 정의하고, Replicator API는 이러한 고수준 정의를 OmniGraph라는 계산 그래프로 변환합니다.16 이 그래프는 랜더마이저 노드, 렌더링 트리거, 주석 생성기, 라이터를 연결하며, 이 그래프를 실행함으로써 데이터가 생성됩니다. Replicator가 백그라운드에서 OmniGraph를 구축하고 실행한다는 사실을 이해하는 것은 그 작동 모델을 파악하는 데 핵심적입니다. 액션 그래프 편집기가 손상되었을 때 전체 시스템이 불안정해지는 사용자 보고 20는 이 기본 구성 요소가 얼마나 중요한지를 보여줍니다.
이 섹션에서는 아키텍처 이론에서 실제 적용으로 초점을 옮겨, Replicator를 사용한 합성 데이터 생성(SDG)의 “방법”에 대해 다룹니다. 핵심 기법인 도메인 랜덤화에 집중하고 이를 구현하기 위한 다양한 도구와 워크플로우를 탐색합니다.
해결책 (도메인 랜덤화, DR): 도메인 랜덤화는 의도적으로 시뮬레이션 파라미터를 변경하여 광범위한 분포의 훈련 데이터를 생성하는 과정입니다. 그 목표는 모델에게 실제 세계가 마치 훈련 중에 겪었던 랜덤화된 도메인의 또 다른 변형처럼 보이게 만드는 것입니다.14
omni.replicator.core): 가장 유연하고 강력한 방법입니다. 주요 파라미터를 랜덤화하는 코드 예시는 다음과 같습니다.
rep.distribution.uniform과 같은 분포를 사용하여 맞춤형 재질을 만들고 확산 색상(diffuse color)과 같은 속성을 랜덤화합니다.17OmniIsaacGymEnvs와 같은 프레임워크의 RL 작업에 특히 유용합니다.16distribution(uniform, gaussian 등), operation(additive, scaling, direct), 그리고 트리거(on_reset, on_interval, on_startup)에 대해 자세히 설명합니다.21scatter_2d 함수를 사용하여 팔레트 위에 상자들이 흩뿌려집니다.BasicWriter, KittiWriter와 같은 다양한 라이터가 YAML 또는 JSON 파일을 통해 RGB, 분할, 3D 바운딩 박스와 같은 여러 주석 유형을 출력하도록 설정되는 방법을 보여줍니다.18NVIDIA는 다양한 사용자 기술 수준에 맞춰 DR을 위한 여러 인터페이스(GUI, YAML, Python API)를 제공합니다. 초보자나 아티스트는 GUI 기반의 합성 데이터 레코더로 시작하여 프로세스에 대한 감을 잡을 수 있고 16, RL 연구원은 작업 로직(Python)과 랜덤화 파라미터(YAML)를 깔끔하게 분리할 수 있는 선언적 YAML 인터페이스를 선호할 수 있습니다.21 반면, 고급 사용자나 맞춤형 SDG 파이프라인을 구축하는 사람은 복잡하고 조건부적인 랜덤화를 구현하기 위해 omni.replicator.core Python API의 완전한 유연성이 필요할 것입니다.17 이러한 계층적 접근은 가파른 학습 곡선을 완화하려는 전략적 시도이지만, 사용자 피드백 24에 따르면 이러한 도구들에도 불구하고 플랫폼의 근본적인 복잡성은 여전히 중요한 장애물로 남아 있습니다.
또한 Replicator의 설계에는 이중성이 존재합니다. 이는 진화 과정과 Isaac 에코시스템의 다른 부분으로 통합된 직접적인 결과입니다. “고전적인” omni.replicator 워크플로우는 랜덤화와 데이터 캡처를 단일하고 결정적인 OmniGraph로 결합하여 오프라인 데이터셋 생성에 이상적입니다.25 그러나 로보틱스와 RL 작업은 종종 비결정적이며 더 많은 유연성을 요구합니다. 이로 인해 “Isaac Sim Replicator” 워크플로우가 개발되었습니다. 이 새로운 워크플로우는 랜덤화 트리거링과 데이터 캡처를 분리합니다. 예를 들어, RL 루프에서는 물리 단계가 진행되고,
on_rl_frame에 따라 랜덤화가 적용된 다음, 관측값이 캡처되는 등 모든 작업이 별개의 독립적인 행동으로 처리됩니다.25 이 이중성은 사용자에게 혼란의 원인이 될 수 있으며, isaacsim.replicator.domain_randomization 문서 26는 속도를 위해 USD 업데이트가 비활성화된 시뮬레이션을 위해 해당 메서드들이 설계되었다고 명시하며 이 차이점을 강조합니다.
이 섹션에서는 Replicator로 생성된 데이터가 로보틱스에서 가장 중요한 두 하위 시스템, 즉 인식 모델 훈련을 위한 딥러닝 프레임워크와 로봇 제어 및 통신을 위한 ROS 미들웨어에 의해 어떻게 소비되는지 분석합니다.
오프라인 훈련: Replicator가 Writer를 사용하여 KITTI 형식과 같은 데이터셋을 디스크에 저장하는 표준 워크플로우입니다.18 이 파일들은 이후 표준 PyTorch
Dataset 및 DataLoader에 의해 로드되어 훈련에 사용됩니다.
온라인 훈련 (인메모리): 디스크 I/O를 우회하는 더 발전되고 효율적인 워크플로우입니다.
핵심 구성 요소: PytorchWriter와 PytorchListener의 역할을 설명합니다.19
PytorchWriter는 데이터를 캡처하여 PytorchListener로 직접 전송하고, PytorchListener는 이 데이터를 PyTorch 텐서 형태로 메모리에 보관합니다.
맞춤형 IterableDataset: 맞춤형 torch.utils.data.IterableDataset을 만드는 과정을 상세히 설명합니다.27 이 데이터셋의 __next__ 메서드는 Replicator 스텝(rep.orchestrator.step())을 트리거하고, 주석 생성기로부터 그라운드 트루스를 수집하여 올바른 형식으로 처리한 후, 훈련 샘플을 PyTorch 훈련 루프에 직접 제공합니다.
사용 사례: 이는 RL 및 훈련 에이전트의 상태에 따라 데이터를 즉석에서 생성해야 하는 다른 시나리오에 이상적입니다.
PyTorch 통합이 더 직접적으로 보이지만, TensorFlow도 주로 NVIDIA TAO(Train, Adapt, and Optimize) 툴킷을 통해 지원됩니다.30
워크플로우:
TFRecord 형식으로 변환합니다.30ROS 2 Bridge Extension을 통해 ROS 2와 통합됩니다.32 이 확장 기능을 통해 Isaac Sim은 ROS 2 토픽, 서비스, 액션을 발행하고 구독할 수 있어 원활한 소프트웨어 인 더 루프 테스트가 가능합니다.PyTorch와의 통합, 특히 온라인 훈련을 위한 통합은 TensorFlow보다 더 직접적이고 정교해 보입니다. isaacsim.replicator.writers 확장 기능은 전용 PytorchWriter와 PytorchListener 클래스를 제공하며 19, PyTorch에 메모리 내 데이터를 공급하기 위한 맞춤형 IterableDataset 클래스 생성에 대한 상세한 튜토리얼이 존재합니다.27 또한 IsaacGymEnvs와 같은 NVIDIA 자체 RL 프레임워크 및 예제 다수가 PyTorch를 사용하여 구축되었습니다.35 반면, TensorFlow 통합은 주로 외부 TAO 툴킷을 통해 문서화되어 있으며, TFRecords로의 중간 데이터 변환 단계가 포함됩니다.30 이는 TensorFlow가 지원되기는 하지만 Isaac 에코시스템 내 개발 초점과 가장 긴밀한 통합은 PyTorch를 향하고 있음을 시사하며, 이는 연구 커뮤니티에서 PyTorch의 지배적인 추세를 반영하는 것으로 보입니다.
한편, ROS는 로보틱스의 사실상 표준이므로 NVIDIA는 반드시 통합을 제공해야 합니다. 그러나 Isaac 플랫폼의 아키텍처적 선택은 상당한 마찰을 유발합니다. Isaac Sim은 특정 Python 버전을 포함한 엄격한 종속성을 가진 단일체(monolithic) 수직 통합 애플리케이션입니다.33 반면 ROS는 시스템 수준 종속성과 함께 작동하도록 설계된 분산형 모듈식 프레임워크입니다. 이러한 근본적인 아키텍처 불일치는 특히 Python 버전 충돌과 같은 통합 문제를 야기합니다. 문서화된 해결책인 소스에서 ROS 재빌드나 복잡한 Docker 설정 33은 사용자에게 상당한 부담을 주는 비정상적인 해결 방법입니다. 이 마찰은 자체 포함된 독점적 에코시스템(Isaac)과 이기종 오픈소스 에코시스템(ROS)을 연결하는 어려움을 잘 보여줍니다.
이 섹션에서는 Isaac Sim(그리고 그 Replicator 기능)을 주요 경쟁 제품과 비교하여 중요한 시장 맥락을 제공합니다. 이 분석은 각 시뮬레이터가 다양한 사용 사례에 대해 갖는 뚜렷한 강점과 약점에 초점을 맞춘 다각적인 접근 방식을 취할 것입니다.
약점: 극도로 높은 하드웨어 요구사항(RTX GPU 필수) 12; 복잡한 Omniverse 스택 의존성으로 인한 가파른 학습 곡선 12; 보고된 성능 문제 및 불안정성 13; Gazebo에 비해 덜 성숙한 ROS 통합.33
약점: 덜 발전된 렌더링 기능(비사실적) 12; CPU 기반 물리 시뮬레이션으로 Isaac Lab과 같은 대규모 병렬화에 최적화되지 않음 12; 오랜 역사와 Ignition에서 Gazebo로의 이름 변경으로 인해 문서가 단편적이거나 오래될 수 있음 36; RL 지원이 “턴키” 방식이 아니며 Isaac Lab보다 더 많은 설정 필요.36
약점: 시각화는 기능적이지만 사실적이지 않음 12; 역사적으로 가파른 학습 곡선과 덜 직관적인 UI 41; Isaac Sim에 비해 내장된 고충실도 센서 시뮬레이션(예: 인식을 위한 카메라) 부족.11
다음 표는 주요 로보틱스 시뮬레이터의 핵심적인 장단점을 요약하여, 특정 프로젝트 요구사항에 가장 적합한 도구를 선택하는 데 도움을 주기 위해 구성되었습니다. 이 표는 각 시뮬레이터의 기술적 특성과 실제 사용 사례에서의 적합성을 한눈에 비교할 수 있도록 합니다.
표 5.1: 주요 로보틱스 시뮬레이터 비교 매트릭스
| 특성 | Isaac Sim/Lab | Gazebo | MuJoCo | PyBullet |
|---|---|---|---|---|
| 주요 사용 사례 | 포토리얼리스틱 인식 및 병렬 RL | ROS 중심의 일반 로보틱스 | 빠른 접촉 동역학 및 RL 연구 | 신속한 프로토타이핑 및 교육 |
| 물리 엔진/충실도 | NVIDIA PhysX 5 (높음) | ODE/DART/TPE (높음) | MuJoCo (매우 높음, 접촉 중심) | Bullet (중간) |
| 렌더링 품질 | 포토리얼리스틱 (경로 추적) | 기능적 (비사실적) | 기본/기능적 | 기본 |
| 성능 패러다임 | GPU 가속, 대규모 병렬 처리 | CPU 기반, 단일 인스턴스 | CPU/GPU (MJX), 빠른 단일 인스턴스 | CPU 기반, 경량 |
| ROS 2 통합 | 양호 (브리지 통해, 복잡한 설정) | 우수 (네이티브) | 수동/커뮤니티 | 수동/커뮤니티 |
| 강화학습 | 우수 (Isaac Lab 통해 턴키 방식) | 양호 (설정 필요) | 우수 (사실상 표준) | 양호 (다수의 Gym 래퍼) |
| 학습 곡선 | 매우 높음 | 높음 | 중간 | 낮음 |
| 핵심 한계 | 하드웨어 의존성 및 복잡성 | 물리용 GPU 가속 부재 | 고충실도 센서 부재 | 낮은 충실도 |
이 섹션에서는 기술적 세부 사항에서 실제 영향으로 초점을 전환하여, Replicator를 핵심으로 하는 Isaac 에코시스템이 로보틱스 연구의 경계를 넓히는 데 어떻게 사용되고 있는지 보여줍니다.
이 하위 섹션에서는 Isaac Sim과 Isaac Lab에 크게 의존하는 NVIDIA의 최첨단 연구를 조사하여 플랫폼의 역량을 보여줍니다.
이러한 연구 프로젝트들은 강력한 “플라이휠 효과(flywheel effect)”를 보여줍니다. Isaac Sim/Lab과 같은 고급 시뮬레이터는 이전에는 다루기 어려웠던 새로운 유형의 연구(예: 휴머노이드를 위한 대규모 RL)를 가능하게 합니다. 이러한 연구는 다시 시뮬레이터의 새로운 기능 개발과 개선(예: 더 나은 물리, 더 빠른 렌더링)을 촉진합니다. 개선된 시뮬레이터는 그 다음 훨씬 더 진보된 연구를 가능하게 합니다. GraspGen 프로젝트 44는 이를 명확히 보여줍니다. 대규모 합성 데이터셋을 생성하는 능력은 시뮬레이터의 역량 덕분에만 가능하며, 이 데이터셋은 더 일반적이고 견고한 파지 모델의 훈련을 가능하게 합니다. 결국 NVIDIA는 자사의 연구팀을 “파워 유저”로 활용하여 Isaac 플랫폼의 개발을 주도하고 과시하며, 연구와 제품 엔지니어링 사이에 긴밀한 피드백 루프를 만들고 있습니다.
이 섹션에서는 플랫폼의 중요한 단점을 인정하면서 균형 잡힌 비판적 시각을 제공합니다. 이는 심층적인 “고찰”에 필수적이며, 공식 문서와 솔직한 사용자 피드백을 기반으로 합니다.
Scatter3D 노드는 world.physics와 함께 사용될 때 물리를 깨뜨릴 수 있음.46rt_subframes 값을 높여야 할 수 있음.46inf 값을 지원하지 않는 파서에서 실패할 수 있음.47사용자 포럼의 피드백은 플랫폼의 실제 사용 경험에 대한 중요한 정보를 제공합니다.20
플랫폼의 문제점들은 빠르게 발전하는 “최첨단(bleeding edge)” 기술의 전형적인 증상입니다. NVIDIA는 Isaac Sim 4.5 업데이트, Cosmos 통합 등 새로운 복잡한 기능들을 빠른 속도로 추가하고 있습니다.8 이러한 빠른 개발 속도는 종종 문서화, 안정화, 버그 수정을 앞지릅니다. 이것이 바로 사용자들이 보고하는 깨진 링크, 오래된 튜토리얼, 잦은 충돌의 원인입니다. 플랫폼은 Omniverse Kit, USD, PhysX와 같은 다른 복잡하고 진화하는 기술 스택 위에 구축되어 있으며, 하위 계층의 버그나 변경 사항은 Isaac Sim에 연쇄적인 영향을 미칠 수 있습니다. 결국 사용자들은 매우 야심차고 복잡한 플랫폼의 성장통을 경험하고 있는 것입니다. 강력한 기능은 안정성과 완성도의 희생을 대가로 제공되며, 사용자 피드백 24은 이러한 트레이드오프를 직접적으로 반영합니다.
이 마지막 섹션에서는 이전 분석을 종합하여 Isaac Replicator와 더 넓은 NVIDIA 로보틱스 플랫폼의 미래 궤적을 예측합니다. 이 플랫폼이 단순한 랜덤화를 넘어 지능적이고 AI 주도적인 월드 생성의 미래로 나아가고 있음을 논증할 것입니다.
도메인 랜덤화는 강력하지만 여전히 절차적이고 “무차별 대입(brute-force)” 방식에 가깝습니다. 개발자가 무엇을 얼마나 랜덤화할지 명시적으로 정의해야 합니다. 미래는 생성형 AI 파운데이션 모델을 사용하여 시뮬레이션 콘텐츠를 자동적이고 지능적으로 생성하는 데 있습니다.
모든 분석을 종합하면 NVIDIA Isaac 에코시스템의 최종 목표는 다음과 같은 원활한 루프를 만드는 것임을 알 수 있습니다.
이 비전은 로보틱스에 대한 “시뮬레이션 우선” 접근법의 궁극적인 실현을 나타냅니다. 여기서 시뮬레이션과 현실 사이의 경계는 단지 포토리얼리즘에 의해서가 아니라, 실제 세계의 무한한 변형을 예측하고 생성할 수 있는 AI 주도 콘텐츠 생성에 의해 흐려집니다.
| Simulation Tools | Joel’s PhD Blog - GitHub Pages, accessed July 18, 2025, https://joel-baptista.github.io/phd-weekly-report/posts/sim_tools/ |