https://cafe.naver.com/openrt/24031
노드(node)
-실행 가능한 최소 프로세서. 실제로 실행하는 각 별개의 프로그램
-목적: 프로그램 재사용성 극대화
-ROS 프로그램은 많은 노드가 연동돼 이루어짐
메시지(message)
-연동을 위해 노드 간 입력, 출력 데이터(=메시지)를 주고받아야 함
-데이터형(Integer, string 등)을 가지는 변수 형태
-데이터 구조, 배열 가능
-메시지 통신 방법(4가지): 토픽(topic), 서비스(service), 액션(action), 파라미터(parameter)
패키지(package)
-1개 이상 노드+노드 실행을 위한 정보
(메타패키지(metapackage): 패키지 묶음)
통신 라이브러리
-토픽, 서비스, 액션, 파라미터 모두 사용 방법은 다르지만 토픽의 publish, subscribe 방식을 취함
-발간&구독에 사용되는 ROS2의 통신 라이브러리: DDS
-자체 라이브러리를 개발했던 ROS1과 다르게 표준 통신 방식을 사용하기 위해 DDS 사용
DDS
-ROS1 >> ROS2의 가장 큰 변화점
-DDSI-RTPS를 통해 실시간 데이터 전송, 임베디드 시스템에의 사용 가능
-ROS Master없이 DDS프로그램간 통신 가능
DDS(Data Distribution Service)란?
-데이터 통신을 위한 미들웨어
(아래 그림에서 보이듯 ISO 7계층 레이어에서 Host Layer에 해당되는 4~7계층)
-사실상, DDS사양을 만족하는 미들웨어 API(DDSI-RTPS와 같은)
4.1산업 표준
-분산 객체에 대한 기술 표준
-ROS가 IoT, 자동차, 국방, 항공, 우주 분야로 넓혀갈 수 있는 발판이 됨
4.2운영체제 독립
-다양한 운영체제 지원
4.3언어 독립
-다양한 언어를 지원하는 ROS Client Library->C++, Python, Java, C 가능
4.4 UDP기반의 전송 방식
-UDP: best effort개념
-UDP의 multicast: 여러 목적지로 동시에 데이터를 보낼 수 있으면서, 불특정 목적지가 아닌 특정 도메인 그룹에 대해서만 전송 가능
-multicast사용을 통해 DDS global space에 있는 토픽들에 대해 구독&발행 가능
4.5 데이터 중심적 기능
-Data centric
-적절한 수신자에게 적절한 정보를 효율적으로 전달하는 것을 목표로 하는 발간&구독
4.6 동적 검색(Dynamic Discovery)
-어떤 토픽이 어떤 영역에 있고 어떤 노드가 그를 발신하고 수신하는지 알 수 있음
-ROS1에서는 DOS Master에서 정보 제공 >> ROS2에서는 직접 검색 가능
4.7 확장 가능한 아키텍쳐
-DDS 아키텍처: IoT 디바이스 같은 소형 디바이스부터 인프라, 국방, 항공, 우주 산업과 같은 초대형 시스템으로까지 확장할 수 있도록 설계
-DDS의 Participant 형태의 노드: 확장 가능한 형태로 제공되어 사용
4.8 상호 운용성
-DDS의 표준 사양을 지키는 제품이라면 서로 다른 회사의 제품 간에도 상호 통신 가능
4.9 서비스 품질(QoS)
-데이터의 송수신 관련 설정을 목적에 맞추어 유저가 직접 설정 가능
-QoS(Quality of Service): 노드 간 DDS 통신 옵션 설정
-신뢰성(reliability)기능이 대표적
4.10 보안
-DDS-Security이라는 DDS 보안 사양을 ROS에 적용하여 보안 이슈 해결
5.1 기본적인 퍼블리셔 노드와 서브스크라이브 노드 실행
$ ros2 run demo_nodes_cpp listener
$ ros2 run demo_nodes_cpp talker
$ rqt_graph
-세 명령을 각자 다른 터미널 창에 입력한다.
-두 노드간 토픽을 주고받는 모습
(동그라미: 노드, 네모: 토픽 같은 통신)
처음에 rqt_graph가 안 나와서 뭔가 싶었는데 그냥 새로고침을 하면 나온다.
5.2 RMW 변경 방법
ROS 2 Foxy의 기본 RMW인 rmw_fastrtps_cpp
말고 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
5.3 RMW의 상호 운용성 테스트
$ export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
$ ros2 run demo_nodes_cpp listener
$ export RMW_IMPLEMENTATION=rmw_fastrtps_cpp
$ ros2 run demo_nodes_cpp talker
listener는 rmw_cyclonedds_cpp를 사용하고 talker 노드는 rmw_fastrtps_cpp를 사용함에도 문제없이 통신이 된다.
5.4 Domain 변경 방법
ROS2에서는 UDP 멀티캐스트로 통신이 이루어지기 때문에 별도의 설정을 하지 않으면 같은 네트워크의 모든 노드가 연결된다.
따라서 내 데이터에 아무 동료나 접근하는 게 싫다면 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
ROS_DOMAIN_ID
를 11로 서로 동일하게 맞춘 talker 노드와 listener 노드만이 연결되어 서로 통신됨을 확인했다.
5.5 QoS테스트
5.5.1 Reliability=RELIABLE
$ sudo tc qdisc add dev lo root netem loss 10%
$ ros2 run demo_nodes_cpp listener
$ ros2 run demo_nodes_cpp talker
sudo tc qdisc add dev lo root netem loss 10%를 연속 실행하면
'Error: Exclusivity flag on, cannot modify.'에러가 난다.
해결 방법은 5.5.2에 나오는 데이터 손실 명령 해제를 해 주고 다시 add를 해주는 것이다.
해제를 안 한 상태에서 또 명령을 하면 안 되는 것으로 보인다.
5.5.2 Reliability=BEST_EFFORT
신뢰성 중심이 아닌 속도 중심
$ ros2 run demo_nodes_cpp listener_best_effort
$ ros2 run demo_nodes_cpp talker
오로카에서는 2, 9가 손실되는 걸 관측했는데 나의 경우 149까지 기다렸는데도 손실된 데이터를 관측할 수 없었다 ..
끝났으면 해제해야 한다.
$ sudo tc qdisc delete dev lo root netem loss 10%