이름보다 데이터가 오가는 모양부터 정한다
Topic은 이름 있는 데이터 흐름에 발행자(publisher)가 메시지를 내고 구독자(subscriber)가 받는 방식이다. 센서 관측이나 로봇 상태처럼 반복해서 나오는 데이터를 여러 소비자가 읽는 경우에 잘 맞는다. 매번 개별 응답을 요구하는 절차와 다르다. 발행/구독 개수는 하나로 고정되지 않으며 구독자가 없다고 발행자의 계산이 반드시 멈추는 것도 아니다. 같은 이름뿐 아니라 메시지 타입과 QoS 등 통신 조건도 맞아야 하므로 ‘Topic에 올렸으니 모두 도착했다’고 보장하지 않는다. QoS의 상세 호환은 M05.03에서 다룬다.
그림 M05.02-1. 각 칸은 서로 다른 역할/근거다. 나란히 비교할 항목이며 위아래가 시간 순서를 뜻하지 않는다. 직접 제작한 개념도이며 본문의 조건과 함께 읽는다.
Service는 클라이언트가 요청(request)을 보내고 서버가 응답(response)을 돌려주는 절차다. 짧은 계산이나 상태 조회처럼 빨리 끝나는 요청에 적합하다. 비동기 클라이언트가 기다리는 동안 다른 일을 할 수 있어도, 서비스 자체가 장시간 작업의 진행·취소 계약을 자동으로 제공하는 것은 아니다. 같은 서비스 이름에 서버를 여러 개 두고 어느 서버가 처리할지 추측하는 설계도 피한다. Jazzy 공식 설명의 권장 사용 범위는 ‘요청과 응답’이라는 모양과 함께 읽는다.
Action은 목표(goal)를 제안하여 수락 여부를 확인하고, 처리 중 피드백(feedback)을 받으며, 종료 결과(result)를 받는 장시간 작업의 계약이다. 취소 요청도 가능하다. 경로 탐색 계산처럼 오래 걸리거나 진행을 확인해야 하는 작업에 어울린다. 서버가 목표를 수락한 것, 진행률을 보낸 것, 성공 종료한 것은 서로 다른 사건이다. 취소를 요청할 수 있다는 것도 즉시 물리적 정지나 안전 정지를 보장하는 뜻이 아니다. 서버의 취소 처리와 실제 실행기의 상태를 별도로 설계해야 한다. 이 단위의 Action 예는 종이 기록이며 실제 이동 명령이 아니다.
Parameter는 특정 노드의 설정값이다. 예를 들어 검사 노드의 stale_limit_ms=100이라는 설정은 그 노드가 관측의 오래됨을 판단할 때 쓸 수 있다. 값의 단위와 유효 범위는 설계자가 정의한다. 전체 로봇의 공유 데이터베이스나 반복 명령 스트림이라고 생각하지 않는다. 노드가 선언한 이름·타입과 검증 조건에 따라 변경 요청이 거절될 수 있으며, 수락된 값이 재시작 뒤 자동 유지된다는 보장도 없다. 파일/초기화 또는 별도 영속화가 필요하다. 설정값 저장 성공과 실제 코드가 그 값을 올바르게 사용하는지도 구분한다.
자료형 검사는 물리 의미를 모두 검사하지 않는다
ROS 인터페이스 정의에서 .msg는 필드와 타입을, .srv는 요청과 응답 두 부분을, .action은 goal/result/feedback 세 부분을 정의한다. 생성 도구는 이 정의로 언어별 자료구조를 만든다. 아래는 문법 모양을 읽기 위한 교육용 .action 예다. ROS 패키지로 빌드하거나 전송하지 않는다. 각도는 rad, 기간은 s, goal은 절대 목표각이라고 이 문서에서 명시한다.
# goal: 절대 목표각과 목표 기간
float64 target_angle_rad
float64 duration_s
---
# result: 성공 여부와 마지막 관측각
bool success
float64 final_angle_rad
---
# feedback: 현재 관측각과 진행률
float64 measured_angle_rad
float64 progress_ratio
구분선 뒤의 순서는 result 다음 feedback이다. 실행 시간 순서는 goal→여러 feedback→result일 수 있으므로 파일의 선언 순서와 시간 순서를 혼동하지 않는다. float64는 부동소수 타입이라는 뜻이지 모든 값이 유한하고 장치 허용 범위 안이라는 뜻은 아니다. NaN·음수 기간·범위 밖 목표를 검사하는 정책과 실패 응답도 필요하다. 필드 이름에 rad가 있어도 잘못된 코드는 30도를 숫자 30으로 넣을 수 있다. 타입 검사만으로 단위 오류를 차단하지 못한다.
목표 30도는 π/6≈0.524 rad다. 가상 현재 각도가 10도이고 절대 목표가 30도라면 잔차는 20도=π/9≈0.349 rad다. 이때 절대 목표의 숫자 30도를 증분 +30도로 잘못 해석하면 현재 각도 10도에 더하여 40도를 목표로 삼게 된다. 잔차 +20도를 올바른 증분으로 사용하는 경우와 구별한다. duration_s=2는 어떤 경로·가속·완료 조건을 뜻하는지 추가 정의가 필요하며 이 필드 하나가 기한 준수를 보장하지 않는다. 피드백 progress_ratio=0.5도 실제 각도가 정확히 중간이라는 뜻인지, 처리 단계의 절반인지 정의해야 한다. 이 예에서는 ‘계획된 시간 단계의 비율’로만 정의하여 위치 정확도의 증거로 사용하지 않는다.
수락과 완료 사이의 불확실성을 남긴다
가상 서비스 요청을 0 ms에 보내고 클라이언트가 100 ms에 timeout을 선언했으나 서버의 처리 완료 기록은 120 ms일 수 있다. timeout은 클라이언트의 대기 한계가 끝났다는 뜻이며, 요청이 서버에 도착하지 않았거나 처리되지 않았다는 증거가 아니다. 상태를 바꾸는 요청을 무조건 재시도하면 같은 작업이 중복 수행될 수 있다. 작업 식별자·중복 방지 정책·서버 결과 조회 같은 계약이 필요하다. 일반 Service가 이러한 응용 수준의 ‘정확히 한 번 실행’을 자동으로 제공한다고 가정하지 않는다.
Action 기록에서도 목표 수락 10 ms, 취소 요청 50 ms, 취소 수락 60 ms, 종료 상태 확인 90 ms는 구별한다. 목표가 끝났다는 상태와 실행기가 멈췄다는 별도 관측의 시간도 다를 수 있다. 피드백 누락만으로 실패를 확정하거나 취소 응답만으로 안전을 선언하지 않는다. 먼저 어떤 단계까지 관측했는지 기록한다. 요청 ID/goal ID, 시각의 시계, 노드의 설정 버전, 명시된 종료 상태가 있으면 다음 판정이 분명해진다. 기존 1장의 상태/명령 분리 예제도 통신 성공과 제어 성공을 같은 것으로 보지 않는 관점으로 읽는다.