ROS의 메시지 통신
노드 (node)
-
프로그램의 재사용성을 극대화 하기 위하여 최소 단위의 실행 가능한 프로세스를 노드라고 정의
-
하나의 실행 가능한 프로그램이라고 생각하면 됨
-
하나 이상의 노드 또는 노드 실행을 위한 정보 등을 묶어 놓은 것을 패키지라고 하며 패키지의 묶음은 메타패키지라고 부름
-
수많은 노드들이 연동되는 ROS 시스템을 위해서는 노드와 노드 사이에 입력과 출력 데이터를 서로 주고 받을 수 있게 설계해야함
메시지 (message)
-
주고받는 데이터를 ROS에서는 message라고 함
-
메시지는 integer, float, boolean, string 와 같은 변수 형태이며 간단한 데이터 구조 및 메시지들의 배열과 같은 구조를 사용 할 수 있음
-
메시지를 주고 받는 통신 방법에 따라 topic, service, action, parameter로 구분됨

DDS란?
-
DDS는 데이터 분산 시스템이라는 용어로 그 실체는 데이터 통신을 위한 미들웨어
-
DDS = Data Distribution Service, 즉 데이터 분산 서비스의 약자
-
ROS 2 에서는 DDS를 통해 시스템의 다양한 구성 요소를 보다 쉽게 통신하고 데이터를 공유할 수 있게함
DDS 사용 예시

# 해당 가상환경이 존재하는 폴더에 들어가서 터미널을 3개를 열고 각각 코드를 작성
$ ros2 run demo_nodes_cpp listener
$ ros2 run demo_nodes_cpp talker
$ rqt_graph
코드 설명
- Listener 노드
- 'ros2 run demo_nodes_cpp listener' 명령어로 실행함
- Hello World라는 메시지를 순차적으로 받고 있음
- Talker 노드
- 'ros2 run demo_nodes_cpp talker' 명령어로 실행함
- Hello World라는 메시지를 순차적으로 보내고 있음
- rqt_graph
- ROS 2 시각화 도구임
- 노드 간의 통신 구조를 보여줌
- talker 노드가 chatter 토픽을 통해 listener 노드에 데이터를 전송하는 것을 나타내고있음
rqt_graph 설명

- rqt_graph 개요
- ROS 2의 rqt 프레임의크의 일부로 현재 실행중인 ROS 2 시스템 구조를 그래프 형태로 시각화
- 주요 기능
- Nodes/Topics(all) 드롭다운 : 표시할 노드와 토픽의 종류를 선택
- 검색 : 특정 노드나 토픽을 찾을 수 있음
- Group : 노드나 토픽을 그룹화하여 복잡한 시스템을 단순화할 수 있음
- Nanespaces, Actions 등의 체크박스 : 특정 유형의 정보를 표시하거나 숨김
- Hide 옵션 : Dead sinks, Leaftopics, Debug 정보등을 숨길 수 있어 그래프를 간소화
- 그래프 의미
- /talker 노드가 /chatter 토픽으로 메시지를 publish하고 있음
- /listener 노드가 /chatter 토픽으로 subscribe 하고 있음
- 전형적인 publish - subscribe 패턴을 보여줌
DDS 사용 예시 - RMW 변경 방법
# 각각의 터미널에 실행해줌
$ export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
$ ros2 run demo_nodes_cpp listener
$ export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
$ ros2 run demo_nodes_cpp talker

해당 오류가 발생했음
해당 오류는 ROS 2 시스템에 rmw_cyclonedds_cpp 라이브러리가 설치되어 있지 않거나 제대로 설정되지 않았을 때 발생함
설치해줌
sudo apt update
sudo apt install ros-jazzy-rmw-cyclonedds-cpp
ros-jazzy 의 경우 본인 ros2 버전에 맞게 바꿔주면 됨
ex) Humble 이라면
sudo apt install ros-humble-rmw-cyclonedds-cpp
$ source /opt/ros/jazzy/setup.bash
다시 환경설정 해주고 실행하면 오류가 안뜬다.

RMW = ROS Middleware
- RMW_IMPLEMENTATION 변경
- ROS 2 는 여러 DDS를 지원
- 기본적으로 하나의 RMW가 설정되어 있지만 직접 다른 RMW로 변경 가능
- 해당 예제에서는 'rmw_cyclonedds_cpp'를 사용
- 지원되는 RMW
- rmw_cyclonedds_cpp
- rmw_fastrtps_cpp
- rmw_connext_cpp
- rmw_gurumdds_cpp
- RMW 변경의 의미
- 특정 DDS가 특정 환경이나 응용 프로그램에 더 적합할 수 있음
- 각 DDS마다 고유한 기능과 최적화가 있음
- 여러 RMW에서 시스템을 테스트하며 호환성 확인 가능
- 주의사항
- RMW를 변경할 때는 모든 노드가 동일한 RMW를 사용
- 서로 다른 RMW를 사용하면 통신 불가능할 수 있음
DDS 사용 예시 - RMW의 상호 운용성 테스트

# Listener 노드
$ export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
ros2 run demo_nodes_cpp listener
# Talker 노드
$ export RMW_IMPLEMENTATION=rmw_fastrtps_cpp
ros2 run demo_nodes_cpp talker
주요 포인트
- 서로 다른 RMW 사용하지만 통신이 잘 이루어지고 있음
- 이는 두 RMW 구현체가 DDS 표준을 잘 준수하고 있음을 보여줌
테스트의 의의
- ROS 2 시스템에서 다양한 DDS 구현체를 혼용할 수 있음을 보여줌
서로 다른 벤더의 DDS 구현체 간 호환성을 확인할 수 있음
DDS 사용 예시 - Domain 변경 방법

$ export ROS_DOMAIN_ID=11
$ ros2 run demo_nodes_cpp talker
$ export ROS_DOMAIN_ID=12
$ ros2 run demo_nodes_cpp listener
$ export ROS_DOMAIN_ID=11
$ ros2 run demo_nodes_cpp listener
서로 다른 도메인을 사용하고 있기에 아무런 반응이 없음

도메인을 맞추면 다시 신호를 받음
DDS 사용 예시 : Qos 테스트 (Reliability = RELIABLE vs BEST_EFFORT)
# 터미널 1
# 불안정한 네트워크 환경을 위해 로컬 네트워크 인터페이스에 10% 패킷 손실을 인위적으로 추가
$ sudo tc qdisc delete dev lo root netem loss 10%
$ ros2 run demo_nodes_cpp talker
# 터미널 2
$ ros2 run demo_nodes_cpp listener_best_effor

- QQS 설정
- RELIBLE : 모든 메시지가 반드시 전달되도록 보장함. 손실된 메시지는 재전송됨
- BEST_EFFORT : 메시지 전달을 보장하지 않지만, 더 낮은 지연시간 제공
- 테스트 결과 해석
- 10% 패킷 손실에도 불구하고 메시지가 잘 도달함
- 이는 RELIABLE 설정이 사용되었음을 시사
- 손실된 패킷들이 재전송되어 모든 메시지가 성공적으로 전달됨
- 테스트 의의
- 불안정한 네트워크 환경에도 RELIABLE 설정이 메시지 전달을 보장
- 네트워크 조건에 따라 적절한 Qos 설정이 중요
- 로봇 시스템이 실제 환경에서 마주할 수 있는 네트워크 문제를 시뮬레이션
Qos란?
- Qos (Quality of Service)는 네트워크 통신의 품질을 제어하는 설정. ROS2와 DDS에서 QoS는 데이터 전송의 다양한 측면을 세밀하게 조정할 수 있게 해주는 중요한 개념
- Reliability (신뢰성)
- RELIABLE : 모든 데이터가 반드시 전달됨을 보장
- BEST_EFFORT : 데이터 전달은 보장하지 않지만 더 낮은 지연시간을 제공
- Durability (지속성)
- VOLATILE : 새로운 구독자에게 과거 데이터를 제공안함
- TTRANIENT_LOCAL : 새로운 구독자에게 일정 기간동안의 과거 데이터를 제공
- Deadline (기간)
- Lifespan (수명)
- History(기록)
- KEEP_LAST : 지정된 수의 최근 메시지만 유지
- KEEP_ALL : 모든 메시지 유지
- Depth (깊이)
- KEEP_LAST 설정 시 유지할 메시지 수 지정
- Lineliness (활성)
- 노드나 토픽의 '생존' 상태를 확인하는 방법 정의
# 터미널 1
# 불안정한 네트워크 환경을 위해 로컬 네트워크 인터페이스에 10% 패킷 손실을 인위적으로 추가
$ sudo tc qdisc delete dev lo root netem loss 10%
$ ros2 run demo_nodes_cpp talker
# 터미널 2
$ ros2 run demo_nodes_cpp listener_best_effort

BEST_EFFORT 설정을 통해 메시지 누락이 있음을 확인