1.4 ROS 2 Jazzy 통신 모델
1.4.1 ROS 그래프와 Node
ROS 2 그래프는 실행 중인 Node와 그 사이의 인터페이스를 나타낸다. Node는 일반적으로 하나의 논리적 책임을 갖는다. 카메라 드라이버, 상태 추정, 정책 추론, 안전 필터를 하나의 거대한 Node로 묶으면 장애 격리와 주기 측정이 어려워진다.
Node는 서로 다른 프로세스·호스트에 있을 수도 있고 component로 같은 프로세스에 합성될 수도 있다. 프로세스를 나누면 장애 격리는 좋아지지만 직렬화와 스케줄링 비용이 늘 수 있다. 초기에는 책임 경계를 올바르게 나누고, 측정 후 필요한 경로만 최적화한다.
1.4.2 Topic, Service, Action 선택
| 프리미티브 | 의미 | 로봇 예 | 피해야 할 사용 |
|---|---|---|---|
| Topic | 지속적인 비동기 데이터 스트림 | 카메라, JointState, 속도 명령 | 한 번의 요청에 반드시 한 번 응답해야 하는 설정 |
| Service | 짧은 요청-응답 RPC | 캘리브레이션 상태 조회, gripper reset | 수 초 이상 걸리거나 진행률·취소가 필요한 작업 |
| Action | 장시간 Goal, Feedback, Result, Cancel | Pick-and-place, 경로 추종 | 100 Hz 연속 센서 스트림 |
Action은 내부적으로 여러 Topic과 Service를 사용하지만, 사용자는 Goal의 상태와 취소 의미를 명시적인 인터페이스로 다룬다. “시작” Service와 “상태” Topic을 임의로 조합하는 것보다 장기 작업에는 Action이 일관적이다.
잠깐 점검 — 어떤 ROS 2 인터페이스를 고를까?
- 30 fps 카메라 영상은 Topic, Service, Action 중 무엇이 적절한가?
- 20초 동안 진행되며 진행률 표시와 취소가 필요한 Pick-and-place는 무엇이 적절한가?
확인 포인트: 지속 데이터 스트림인 카메라는 Topic, 목표·피드백·결과·취소가 필요한 장기 작업은 Action이 적절하다.
1.4.3 DDS와 RMW
ROS 2 클라이언트 라이브러리 rclpy와 rclcpp 아래에는 ROS middleware interface(RMW)가 있다. RMW 구현은 DDS 또는 다른 전송 계층과 ROS 타입·발견·통신을 연결한다. 애플리케이션은 보통 동일한 ROS API를 사용하지만, 발견 방식, 설정, 성능 특성은 구현에 따라 달라질 수 있다.
DDS의 데이터 중심 publish/subscribe는 중앙 브로커 없이 참가자를 발견하고, Topic 단위의 QoS를 협상한다. 이는 네트워크 설정이 필요 없다는 뜻이 아니다. 멀티캐스트가 차단된 네트워크, 컨테이너, VPN에서는 발견이 실패할 수 있다.
1.4.4 QoS는 인터페이스 계약이다
중요 QoS 정책은 다음과 같다.
- Reliability:
RELIABLE은 전달 재시도를,BEST_EFFORT는 최신성 우선 전달을 뜻한다. - Durability:
TRANSIENT_LOCAL은 늦게 참여한 구독자에게 보관 표본을 제공할 수 있다. - History/Depth: 큐에 보관할 표본 수를 제한한다.
- Deadline: 표본이 기대 주기 안에 도착해야 한다는 계약을 표현한다.
- Liveliness: 발행자가 살아 있음을 판단한다.
- Lifespan: 오래된 표본의 유효 기간을 제한한다.
카메라 미리보기는 손실된 과거 프레임을 재전송하느라 현재 프레임이 늦어지는 것보다 BEST_EFFORT, 작은 depth가 나을 수 있다. 반대로 낮은 빈도의 설정 변경은 RELIABLE과 TRANSIENT_LOCAL이 적절할 수 있다. 발행자와 구독자의 QoS가 호환되지 않으면 그래프에 이름이 보여도 데이터가 흐르지 않는다.
1.4.5 시간의 두 종류
ROS Node는 시스템 시간과 시뮬레이션 시간을 구분한다. /clock을 사용하고 use_sim_time=true이면 시뮬레이터가 시간의 권위자(authority)가 된다. 시뮬레이션을 일시정지하거나 reset하면 시간도 멈추거나 되돌아갈 수 있다.
- 메시지 헤더는 측정 시각을 기록한다.
- 처리 완료 시각을 헤더에 넣지 않는다.
steady_clock은 타임아웃 측정에, ROS clock은 데이터 정렬에 구분해 사용한다.- reset 뒤 이전 epoch의 버퍼를 비운다.