QoS 호환성
보내는 쪽과 받는 쪽의 QoS가 다르면 무슨 일이 생길까?
요청과 제공
구독이 바라는 것을 발행이 내놓아야 합니다
구독은 "적어도 이만큼은 돼야 한다"는 QoS를 요청(request)하고, 발행은 "이만큼까지 해 줄 수 있다"는 QoS를 제공(offer)합니다. 모든 정책에서 요청이 제공보다 엄격하지 않아야 연결됩니다.
Reliability
Best effort 발행에 Reliable 구독은 안 됩니다
잃어도 된다는 발행에 "하나도 빠짐없이"를 요구하면 들어줄 수 없어 끊깁니다. 반대로 Reliable 발행은 Best effort 구독에게도 보내 줍니다. 2편에서 Best effort로 거북이 위치를 받은 것이 이 경우입니다.
Durability
Volatile 발행에 Transient local 구독도 안 됩니다
지난 메시지를 남기지 않는 발행에게 지난 메시지를 달라고 하면 끊깁니다. Transient local 발행에 Volatile 구독은 이어지지만 새 메시지만 받습니다. 지난 메시지까지 받으려면 양쪽 모두 Transient local이어야 합니다(4편).
하나라도
정책 하나만 어긋나도 끊깁니다
Reliability가 맞아도 Durability가 어긋나면 연결되지 않습니다. 반면 History와 Depth는 양쪽이 달라도 연결에 상관없습니다. 각자 자기 대기열 크기일 뿐이기 때문입니다.
Deadline, Liveliness도 호환성에 들어가지만 기본값을 쓰면 신경 쓰지 않아도 됩니다.
알아채기
끊기면 경고가 한 줄 뜹니다
rclpy 서브스크라이버는 QoS가 맞지 않는 퍼블리셔를 만나면 이렇게 경고합니다. 마지막의 RELIABILITY가 어긋난 정책 이름입니다. 퍼블리셔 쪽에도 "requesting incompatible QoS"라는 경고가 뜹니다.
실제로는 한 줄로 나옵니다. listener는 예시 노드 이름입니다.
따라 하기
일부러 어긋나게 해 봅니다
터미널 1에서 ros2 topic pub /chatter std_msgs/msg/String "{data: hi}" --qos-reliability best_effort, 터미널 2에서 ros2 topic echo /chatter --qos-reliability reliable을 실행합니다. 경고만 뜨고 메시지는 오지 않습니다. 둘째 옵션을 best_effort로 바꾸면 옵니다.
다음 편