월드는 환경과 실행 조건을 담는다
월드(world)는 중력/물리·바닥/장애물·조명과 모델을 배치한 시뮬레이션 환경이다. 모델은 로봇/상자처럼 링크/관절·시각/충돌/관성 등을 묶은 대상이다. entity는 실행 중 모델/링크·센서 등을 식별하는 개체를 뜻한다. SDF는 이런 시뮬레이션 구성을 기술하는 XML 형식이다. 월드 파일과 로봇 모델 파일은 역할이 다르며 모델의 URDF를 가져와도 월드/센서·구동/시간 계약이 자동 완성되지는 않는다.
이 모듈의 기준 조합은 Ubuntu 24.04/ROS 2 Jazzy/Gazebo Harmonic이다. 공식 호환 표에서 Jazzy/Harmonic 조합을 확인한다. Gazebo Classic용 옛 plugin 이름/토픽·명령을 그대로 쓰지 말고 대상 버전의 기능/구성으로 옮긴다. 여기서는 설치하거나 최신 버전으로 임의 변경하지 않고 주어진 기록을 해석한다.
server는 월드 상태/물리·시스템을 갱신하고 GUI는 상태를 보여 주거나 조작 요청을 보낸다. GUI 창에 로봇이 보이는 것과 물리/구동·센서/ROS 연결이 준비된 것은 다른 관문이다. Harmonic SDF world 문서는 Physics, UserCommands, SceneBroadcaster 같은 system plugin의 역할을 구분한다. 필요한 시스템/서비스와 실제 상태를 확인하며 단순 그림을 물리 실행 결과로 받아들이지 않는다.
스폰은 파일/이름·pose가 있는 생성 과정이다
spawn은 모델을 실행 월드에 생성하는 작업이다. 모델 파일/자산 경로·이름, 초기 pose의 기준/단위, 대상 world와 생성 기능이 필요하다. pose는 위치/방향의 쌍이며 위치는 보통 m/회전은 명시한 규약으로 기록한다. Gazebo Transport와 ROS 서비스는 같은 이름/형식이라고 가정하지 않는다. 이 단위는 Transport 개념을 다루고 ROS 연결은 다음 단위에서 보충한다.
Gazebo Sim 8 entity creation 문서는 UserCommands system이 제공하는 /world/<world_name>/create와 EntityFactory 요청을 설명한다. 실제 요청/응답·생성된 대상의 이름/ID·pose를 연결한다. timeout이면 요청이 처리되었는지 미상일 수 있어 동일 요청을 무조건 반복해 개체를 늘리지 않는다. 모델이 보이더라도 충돌/관성·구동/센서 준비는 별도로 검사한다.
합성 월드 demo에 robot이라는 모델이 이미 하나 있고, 같은 이름으로 다시 생성 요청을 한다고 하자. 공식 기본 설명처럼 이름 변경 허용이 꺼져 있으면 동일 이름을 새 개체로 만들지 않는다. 반대로 이름 변경을 허용해 반복 생성하면 다른 이름의 개체가 추가될 수 있다. 후속 관측/명령이 실제 어느 로봇 ID에 연결되는지 확인해야 한다. 이름만 보고 이전 대상/새 대상을 혼동하지 않는다.
초기 위치가 바닥 안쪽이거나 다른 물체와 겹치면 기대와 다른 접촉/가속이 생길 수 있다. dynamic 모델과 static 바닥의 구분·gravity/관성·collision을 확인한다. 화면에서 모양이 맞아도 질량/축·충돌 형상은 다를 수 있다. 이 과제는 실제 충돌/낙하 시험을 하지 않고 필요한 관측 항목을 설계한다.
고정 스텝은 모형 시간의 증가량이다
physics step의 Δt는 물리 상태를 한 번 적분/갱신할 때 전진하는 모형 시간이다. 설정의 max_step_size와 실제 기록된 step을 구분하며, 아래 계산은 각 완료 physics step의 Δt가 일정하다고 명시적으로 가정한다. 초기 simulation time이 0이고 N번 step이 완료되면 시간은 NΔt다. 더 작은 step도 접촉/솔버·모형/주기에 따라 결과가 달라 실제 정확도/안정성이 자동 보장되지는 않는다.
그림 M09.01-1. 각 칸은 서로 다른 역할/근거다. 나란히 비교할 항목이며 위아래가 시간 순서를 뜻하지 않는다. 직접 제작한 개념도이며 본문의 조건과 함께 읽는다.
합성 Δt=0.001 s(1 ms)에서 완료 step 100개면 simulation time은 0.100 s다. 이 물리 주기에 대응하는 빈도는 1000 Hz지만 카메라/제어·GUI도 모두 1000 Hz라는 뜻은 아니다. 카메라의 모형 갱신 간격 0.050 s는 이 일정 step의 50개, 제어 간격 0.020 s는 20개에 해당한다. 실제 센서 발행/전송·처리와 위상/스케줄은 별도다.
같은 100 step을 Δt=0.002 s로 진행하면 모형 시간은 0.200 s다. 같은 0.100 s를 비교하려면 각각 100/50 step을 완료해야 한다. step 수만 맞춘 두 실험을 같은 지속 시간의 결과라고 쓰면 안 된다. 설정 변경 후 제어/센서 갱신과 관측/로그·접촉 오차를 함께 재검증한다.
모형 시간과 실제 경과·주기를 분리한다
RTF(real-time factor)는 해당 측정 구간의 simulation time 증가를 실제 경과 시간 증가로 나눈 비율로 계산한다. 합성 100 ms 모형 구간에 실제 250 ms가 걸렸으면 RTF=0.4다. 같은 실제 250 ms 동안 모형이 200 ms 전진했다면 0.8이다. 설정 real_time_factor 목표가 1이라고 실제 측정도 반드시 1인 것은 아니다. 연산/렌더링·센서·스케줄/부하에 따라 달라진다.
RTF가 0.4면 모형의 제어 간격 20 ms는 일정한 비율이라는 추가 가정에서 실제 약 50 ms에 대응한다. 실제 간격이 항상 같다는 보장은 없어 평균 비율과 jitter를 나눈다. 느리게 실행되는 모형에서도 모형 시간으로 제어/센서를 정합하면 알고리즘의 기준 간격을 유지할 수 있지만, 실제 장비 timeout/네트워크·벽시계와 섞으면 다른 동작이 된다.
pause는 물리/모형 시간을 멈추는 제어다. Sim 8 pause 문서의 요청과 paused 상태를 확인한다. GUI/프로세스·외부 ROS 노드의 실제 경과가 모두 정지하는 것은 아니다. 화면이 그대로거나 같은 센서 표본이 남아 있는 것과 새로운 관측을 얻는 것은 다르다. 실제 경과 watchdog과 simulation stamp의 목적을 구별한다.
리셋 후 외부 상태와 실험 세대도 맞춘다
Sim 8 reset 문서는 world control의 reset과 system reset 인터페이스를 설명한다. reset은 설정/구현에 따라 해당 모형 상태/시간을 초기화하는 동작이며 외부 정책·ROS 버퍼/파일·사용자 코드 상태까지 모두 과거로 되돌리는 기능은 아니다. 요청 응답과 실제 time/pose·속도/개체·센서 준비의 후속 관측을 연결한다. 실행 중 추가한 모델이 원하는 초기 스냅샷에 포함되는지도 직접 확인한다.
합성 실행 e1의 sim time이 1.200 s였다가 전체 reset 뒤 새 실행 e2에서 0으로 관측되었다고 하자. 이전 관측 stamp 1.190 s를 새 시각 0과 빼면 −1.190 s다. 이를 아주 신선한 관측으로 인정하면 안 된다. e1의 대기 명령/action chunk·필터/추적 상태를 e2에 섞지 않고 epoch/시퀀스와 초기화·새 관측 전제를 확인한다. 명시적인 reset의 0과 아직 첫 clock을 못 받은 미초기화 0도 출처/상태로 구분한다.
재현 기록에는 world/model·자산/physics backend/솔버/Δt·센서/제어 주기, 초기 pose/속도·버전/seed와 외부 상태·clock/epoch를 둔다. seed와 고정 step만으로 모든 backend/장치·비동기 처리의 완전한 동일성을 보장하지 않는다. 기존 2.3 물리 시간/접촉과 6.2 정량 진단을 연결하되 Isaac/PhysX의 API/기본값을 Gazebo에 그대로 적용하지 않는다.