# 멀티로봇 간 노드 통신 설정 기초

#### 멀티로봇 통신 구조 이해

멀티로봇 환경에서 ROS2를 활용하려면, 각 로봇이 별도의 노드(Node) 집합을 운영하더라도 상호 간의 정보 교환이 가능하도록 통신 구조를 설계해야 한다. 일반적으로 로봇은 다음과 같은 통신 구조를 가진다.

* 각 로봇(예: 로봇 A, 로봇 B)은 독립적인 ROS2 노드 집합을 실행한다.
* 멀티로봇 시스템이 서로 다른 네트워크 대역에 물리적으로 연결되어 있더라도, IP 라우팅 설정 혹은 브리지(Bridge) 장비를 통해 하나의 논리적 네트워크로 묶일 수 있다.
* DDS(데이터 배포 서비스)를 기반으로 각 노드가 상대방을 자동으로 탐색(Discovery)하여 통신 채널(Topic 또는 Service, Action 등)을 수립한다.

따라서 초기 단계에서 멀티로봇 간 노드 통신을 원활하게 만들려면, 다음 사항을 고려해야 한다.

1. **도메인 ID(Domain ID)**: 여러 그룹의 로봇이 각자 독립적인 통신을 해야 한다면, 서로 다른 도메인 ID를 사용하거나, 반대로 협업이 필요한 경우 동일 도메인 ID를 사용한다.
2. **브로드캐스트/멀티캐스트 가능성**: DDS Discovery 시 브로드캐스트 혹은 멀티캐스트 패킷이 사용될 수 있다. 네트워크 라우터 또는 스위치가 이를 막지 않도록 설정해야 한다.
3. **로컬 호스트 vs. 원격 호스트**: 같은 호스트(PC) 내에서 구동되는 ROS2 노드는 공유 메모리를 통한 빠른 통신이 가능하지만, 다른 물리적 호스트로 분산되면 네트워크 지연이 있을 수 있다.

#### ROS2 간 노드 연결 메커니즘

ROS2 통신은 DDS 미들웨어를 통해 다음 단계로 연결된다.

1. **노드 기동**: 노드가 기동되면서 해당 노드의 QoS(신뢰도, 이력 크기 등) 설정, 토픽 이름, 서비스 이름 등의 정보를 DDS와 동기화한다.
2. **Discovery**: DDS 프로토콜이 노드가 속한 도메인 내에서 동작하는 다른 노드들을 탐색한다.
3. **Matching**: 서로의 토픽 이름, QoS 설정이 호환되면 통신 연결을 자동으로 수립한다. 서로 다른 QoS 정책을 갖는 노드는 기본적으로 호환되지 않을 수 있으므로, 협업이 필요한 노드는 동일 또는 호환 가능한 QoS 프로파일을 가져야 한다.
4. **전송/수신**: 이후에는 토픽 단위로 메시지가 전송되거나, 서비스 호출이 일어나면서 데이터가 교환된다.

#### DDS Discovery 동작 개념

멀티로봇 시스템에서 서로 물리적 거리가 떨어진 로봇 간에도 네트워크가 연결되어 있다면, DDS Discovery가 이를 자동으로 감지한다. DDS Discovery의 핵심 과정은 다음과 같다.

* 각 노드는 초기화 시 `SpdpSimpleParticipantData`(Simple Participant Discovery Protocol) 패킷을 멀티캐스트로 전송하여, 같은 도메인 ID를 공유하는 다른 노드를 찾아간다.
* 수신 노드는 `SEDP`(Simple Endpoint Discovery Protocol)로 자신의 토픽, 서비스 정보를 응답한다.
* 노드들은 상호 보유한 엔드포인트(토픽, 서비스, 액션 등)에 대한 메타데이터를 교환한 후, 실제 유니캐스트 혹은 멀티캐스트 데이터 채널을 생성한다.

만약 네트워크 구성이 복잡하거나 방화벽이 활성화되어 있으면, Discovery가 정상적으로 진행되지 않을 수 있다. 따라서 방화벽 설정에서 DDS 관련 포트를 열어 두거나, 외부 멀티캐스트를 허용하는 등의 사전 작업이 필요하다.

#### 간단한 토폴로지 예시

멀티로봇 환경에서 흔히 볼 수 있는 최소 구성 예시는 다음과 같다:

{% @mermaid/diagram content="flowchart LR
A\[로봇 A] -- 토픽/서비스 --> B\[로봇 B]
B -- 응답/피드백 --> A" %}

* 로봇 A에서 위치(position), 속도(velocity) 정보를 퍼블리시(publish)하고, 로봇 B에서는 이를 구독(subscribe)하여 A와 충돌이 없도록 경로를 계획한다.
* 로봇 B에서 센서 정보를 토픽으로 퍼블리시하거나, 특정 액션을 요청하면 로봇 A가 이를 처리하고 응답할 수도 있다.

이때 두 로봇은 다음과 같은 노드 구성을 가질 수 있다.

* 로봇 A
  * odometry\_publisher 노드
  * lidar\_subscriber 노드
  * path\_action\_server 노드
* 로봇 B
  * lidar\_publisher 노드
  * odom\_subscriber 노드
  * path\_action\_client 노드

서로 사용하는 토픽 이름, QoS 설정, 액션 서버/클라이언트 인터페이스가 호환되면 별도의 추가 설정 없이도 통신이 이루어진다.

#### 네트워크 설정 시 고려 사항

멀티로봇 시스템이 유선 LAN, Wi-Fi, 5G 등 다양한 네트워크 환경에 놓일 수 있으므로, 물리 계층부터 ROS2 내부 설정까지 다음 사항을 점검한다.

1. **IP 대역 및 서브넷**: 로봇들 간 IP 주소대가 다르다면 라우팅을 통해 서로 간 패킷이 전달될 수 있도록 설정해야 한다.
2. **네트워크 지연(latency)과 패킷 손실율**: 로봇 제어와 같이 실시간성을 요구하는 메시지가 많다면, 네트워크 QoS(예: latency 보장, 대역폭 보장)가 중요한 이슈가 된다.
3. **도메인 ID 설정**: 협업하는 로봇은 같은 도메인 ID를 공유해야 Discovery가 원활하다.
4. **방화벽/라우터 설정**: DDS Discovery에 필요한 멀티캐스트 포트(기본적으로 7400\~7500 대역 등)가 막혀 있지 않은지 확인한다.
5. **데이터 암호화**: 보안이 필요한 경우 SROS2(Secure ROS2) 설정을 통해 DDS 보안 계층(Access Control, Cryptographic Plugin)을 적용한다.

#### QoS 선택 전략: 신뢰도(Reliability), 내구성(Durability), 히스토리(History)

멀티로봇 간의 통신 품질을 개선하기 위해서는 QoS 설정이 중요하다. ROS2에서 QoS는 주로 다음과 같은 파라미터로 구성된다.

1. **신뢰도(Reliability)**
   * Reliable: 메시지 유실이 없도록 보장하며, 수신자가 메시지를 놓치면 재전송한다. 단, 네트워크 부하나 지연이 늘어날 수 있다.
   * Best Effort: 재전송 없이 전송자의 ‘최선의 노력’으로만 메시지를 보낸다. 지연을 줄이고 싶을 때 또는 대역폭이 낮은 통신 환경에서 유리하다.
2. **내구성(Durability)**
   * Transient Local: 퍼블리셔(생성자)가 살아있는 동안, 메시지 버퍼를 유지해서 새롭게 구독자가 등장했을 때 과거 메시지를 요청할 수 있게 한다.
   * Volatile: 메시지가 발행된 순간, 구독자가 없으면 해당 메시지는 사라진다.
3. **히스토리(History)**
   * Keep All: 가능한 모든 메시지를 저장하여 구독자에게 전달한다. 메모리 사용량이 증가할 수 있다.
   * Keep Last: 최근 $N$개의 메시지만 저장한다. $N$은 사용자 정의이다.

위 QoS 파라미터들은 로봇 간 통신에 있어 다음과 같이 선택될 수 있다.

* 상태 정보(odometry, 로봇 위치 등)처럼 최신 데이터만 중요하고 과거 이력을 모두 유지할 필요가 없다면, **Best Effort + Volatile + Keep Last(1)** 방식을 사용한다.
* 중요한 제어 명령이나 장애 감지 이벤트 등 유실이 매우 위험한 메시지인 경우, **Reliable + Transient Local**을 고려한다.

#### 멀티로봇 간 네임스페이스(Namespace) 활용

ROS2는 멀티로봇 사용 사례에 맞춰 노드와 토픽 이름을 네임스페이스로 구분하는 것을 권장한다.

* 예:
  * 로봇 A: `/robotA/cmd_vel`, `/robotA/odom`
  * 로봇 B: `/robotB/cmd_vel`, `/robotB/odom`

이렇게 구분하면 동일한 노드/토픽 이름을 쓰면서도, 내부적으로는 다른 리소스로 인식하여 충돌을 피할 수 있다. 협업이 필요한 토픽은 상위 네임스페이스에서 관리하거나, 멀티로봇 간 공유 토픽을 별도로 두어 사용한다.

#### 기본 예시: 두 로봇의 이동 제어 메시지 설정

ROS2 노드 설계를 통해 두 로봇 A, B가 상호 간 이동 상태를 주고받는 예시를 들어 보면 다음과 같은 구조를 잡을 수 있다.

* 로봇 A:
  * `cmd_vel` 토픽(퍼블리셔)
  * `odom` 토픽(퍼블리셔)
* 로봇 B:
  * `cmd_vel` 토픽(퍼블리셔)
  * `odom` 토픽(퍼블리셔)
* 각 로봇에서 서로 상대 로봇의 `odom`을 구독해서 협업한다.

위와 같은 토픽이름 충돌을 막기 위해 네임스페이스를 적용한다면:

* 로봇 A:
  * `/robotA/cmd_vel`, `/robotA/odom`
* 로봇 B:
  * `/robotB/cmd_vel`, `/robotB/odom`

통신 설정 시 꼭 주의해야 할 것은 다음과 같다.

1. 서로가 구독해야 하는 토픽을 같은 이름(네임스페이스 포함)으로 설정하되, 필요한 QoS 수준을 모두 일치시킨다.
2. 메시지 타입(sensor\_msgs/msg/Odometry, geometry\_msgs/msg/Twist 등)이 일치해야 한다.
3. 서로 도메인 ID가 같아야 Discovery가 이뤄진다.

#### DDS 보안 구성 예시

멀티로봇 간에 중요한 데이터를 주고받을 때, DDS 보안을 적용할 수 있다. 이를 위해서는 SROS2를 활용하여 인증서(keystore)와 정책 파일을 발급하고, 각 로봇의 노드에 이를 설정한다.

설정 절차는 대략 다음과 같다.

**SROS2 설치**: ROS2 Humble 환경에서 `sros2` 패키지를 설치한다.

```bash
sudo apt-get install ros-humble-sros2
```

**보안 파라미터 디렉토리 생성**:

```bash
mkdir -p ~/my_robot_keystore
```

**보안 아티팩트 생성**:

```bash
ros2 security create_keystore ~/my_robot_keystore
ros2 security create_key ~/my_robot_keystore /robotA
ros2 security create_key ~/my_robot_keystore /robotB
```

**보안 정책 파일(permissions.xml) 편집**: 노드별로 접근 가능한 토픽, 서비스 등을 정의한다.

**ROS2 실행 시 보안 설정 적용**:

```bash
export ROS_SECURITY_ENABLE=true
export ROS_SECURITY_STRATEGY=Enforce
export ROS_SECURITY_KEYSTORE=~/my_robot_keystore
ros2 run [패키지] [노드_executable] --ros-args --enclave /robotA
```

이렇게 설정하면, DDS 통신이 암호화 채널을 통해 이뤄지므로 무단 패킷 캡처나 가로채기를 방지할 수 있다.

#### 초보적 동적 재구성(Dynamic Reconfigure)

ROS2에는 ROS1의 동적 재구성처럼 실시간으로 노드 파라미터나 QoS 설정을 수정하기 위한 매커니즘이 있다. 멀티로봇 통신 상황에서 노드의 동작 중에 다음 항목을 재설정할 수 있다.

* 데이터 전송 주기(Publish Rate)
* QoS 이력 크기(History Depth)
* PID 제어 파라미터 등

다만 로봇 간의 마찰 없이 동적 파라미터 재설정이 가능하려면, 먼저 노드가 이 기능을 명시적으로 구현해야 하며, 파라미터 이벤트를 수신하는 노드가 이를 적절히 반영하도록 설계되어야 한다.

#### 네트워크 트래픽 모니터링과 디버깅

멀티로봇 환경에서 여러 노드가 동시에 통신하므로, 실제 패킷 흐름과 지연을 관찰하고 디버깅하는 과정을 거쳐야 한다. 대표적인 방법은 다음과 같다.

1. **Wireshark**
   * DDS 패킷을 캡처하여 멀티캐스트 또는 유니캐스트 트래픽이 어떻게 흐르는지 볼 수 있다.
   * Discovery 관련 패킷(RTPS)이나 토픽 데이터 패킷을 필터링하여, 네트워크 상 통신이 적절히 이뤄지는지 검사한다.
2. **ROS2 CLI(command-line interface) 명령**
   * `$ ros2 topic list`를 통해 현재 인식되고 있는 토픽 목록을 확인한다.
   * `$ ros2 node list`로 동일 도메인 내 노드들이 정상적으로 발견(Discovery)되는지 점검한다.
   * `$ ros2 topic echo /robotA/odom` 형태로 실제 수신되는 메시지를 모니터링할 수 있다.
3. **ROS2 Bag**
   * `$ros2 bag record -a` 명령을 통해 특정 시간 동안 모든 토픽을 기록한 뒤, `$ ros2 bag play`로 재생해보며 메시지 이상 유무를 확인한다.
   * 로그를 활용해 통신 지연(초당 메시지 수, 특정 시점의 끊김 여부) 등을 상세 분석할 수 있다.
4. **노드 상태 점검**
   * `$ ros2 node info <node_name>` 명령으로 해당 노드가 어떤 토픽을 퍼블리시·구독하는지, QoS는 어떻게 설정되었는지를 확인한다.
   * `$ ros2 doctor` 명령으로 ROS2 환경 전반의 설정, 네트워크 환경 등을 진단해볼 수 있다.

이런 도구들을 통해 어떤 로봇(노드)이 Discovery에서 빠지는지, 혹은 QoS가 충돌해서 통신이 안 되는지 등을 구체적으로 추적 가능하다.

#### 시간 동기화(NTP)와 멀티로봇 협업

멀티로봇 환경에서 협업이나 데이터 융합(특히 센서 데이터)을 위해서는 시간 동기화가 필수적이다. 예컨대 카메라 영상과 LiDAR 데이터를 합성하거나, 로봇 간 충돌 방지를 위해 서로의 위치를 동일한 타임스탬프로 비교할 때, 시간이 어긋나 있으면 정확한 판단이 어렵다.

NTP( Network Time Protocol ):

* ROS2 노드 실행 전, 각 로봇의 시스템 시간을 동일하게 맞춰둔다.
* 일반적으로 로컬 NTP 서버를 두거나, 인터넷 연결이 가능하다면 공인 NTP 서버(예: time.google.com)를 활용할 수 있다.

NTP 구성 예:

```bash
# /etc/ntp.conf 예시
server 0.ubuntu.pool.ntp.org iburst
server 1.ubuntu.pool.ntp.org iburst
```

Chrony:

* NTP를 대체 또는 보완하기 위한 경량화 패키지. 내장된 PID 제어 알고리즘으로 정확도가 높고, 부팅 후 빠르게 안정화되는 특징이 있다.
* `/etc/chrony/chrony.conf` 파일에서 서버 주소를 지정하고, `$ systemctl enable chrony && systemctl start chrony` 명령으로 사용한다.

ROS2 토픽에는 메시지 헤더 안에 타임스탬프가 들어가는 경우가 많으므로, 이를 서로 다른 로봇에서 비교하려면 시간이 동일 기준을 가져야 한다. 이를 위해 항상 멀티로봇 전체 시스템의 시간을 주기적으로 점검하고 동기화하는 절차를 습관화하는 것이 좋다.

#### NAT, 브리지, VPN을 통한 원격 로봇 연결

멀티로봇 시스템이 물리적으로 같은 LAN에 있지 않고, 분산 환경에서 운영될 때는 NAT(Network Address Translation)나 VPN(Virtual Private Network)을 고려해야 한다. DDS Discovery와 데이터 전송이 정상 동작하려면, DDS 포트(기본 7400\~7500 UDP 포트 등)가 상호 열려 있어야 하고, 멀티캐스트도 중간에서 차단되지 않아야 한다.

1. **NAT 문제**
   * 로봇이 사설 IP(예: 192.168.x.x)를 쓰고 있고, 본부(원격지)에서는 공인 IP를 통해 접속해야 할 때는 포트 포워딩(Port Forwarding)을 설정해야 한다.
   * DDS Discovery 패킷이 외부로 나가지 못할 수 있으므로, RTPS Relay나 ROS2 DDS Router 기능을 써서 중계한다.
2. **VPN**
   * OpenVPN, WireGuard 등 VPN 솔루션을 사용해, 로봇과 본부 PC를 하나의 가상 LAN으로 연결한다.
   * VPN 터널 내에서는 사설 IP를 동일하게 공유하므로 DDS Discovery가 비교적 수월해진다.
3. **브리지(Bridge)나 브로커**
   * ROS1 시절에는 `ros_bridge`를 사용해 원격 연결을 우회했으나, ROS2는 DDS 기반으로 자체 멀티캐스트를 사용하므로 네트워크 브리지 수준에서 멀티캐스트를 전달해야 한다.
   * 필요하다면 별도의 브로커를 두어, 중요한 토픽만 선별적으로 리레이(relay)할 수도 있다.

이러한 구성은 로봇의 운영 장소나 클라우드 연동 여부에 따라 복잡해질 수 있으므로, 시스템 설계 시 네트워크 토폴로지를 미리 충분히 검토해야 한다.

#### 리소스 제한 환경에서의 멀티로봇 통신

소형 임베디드 보드(예: Raspberry Pi, Jetson Nano 등)를 사용하거나, 네트워크 대역폭이 제한된 상황(LoRa, 지하 광산 Wi-Fi 등)에서는 DDS 기본 설정만으로는 통신 효율이 떨어질 수 있다. 이를 개선하기 위한 방안은 다음과 같다.

1. **QoS 최적화**
   * Best Effort 전송을 활용하여 재전송 오버헤드를 줄인다.
   * History Depth를 최소화(예: 1)하여 메모리 사용량을 줄인다.
2. **메시지 주기 조절**
   * 센서 주파수가 너무 높으면 네트워크 부하가 커진다. 적절한 주기로 다운샘플링해 전송한다.
   * 예: LiDAR가 10Hz로 구동되지만 실제 통신은 2Hz 정도면 충분한 경우, 노드 내부에서 메시지를 샘플링하여 퍼블리시한다.
3. **메시지 압축**
   * 카메라 영상이나 대용량 이미지를 전송해야 하는 경우, `image_transport` 등을 사용해 압축(예: JPEG, PNG)하여 대역폭을 줄인다.
   * CPU가 허용한다면 영상 압축 알고리즘(H264, H265 등)을 적용해 훨씬 낮은 대역폭으로 전송 가능하다.
4. **분산 처리**
   * 로봇마다 자율주행 알고리즘을 모두 수행하기 어려우면, 일부 처리를 외부 서버(Edge Server)에 위임하여 통신량을 줄인다.
   * 예: Edge Server가 LiDAR SLAM을 수행하고, 로봇은 요약된 위치 정보만 수신한다.

이처럼 제한된 자원에서의 통신은 QoS 튜닝과 메시지 경량화가 필수적이다.

#### 액션(Action)과 서비스(Service)의 멀티로봇 활용

멀티로봇 환경에서 특정 동작을 요청하고 결과를 기다려야 하는 경우, 토픽 기반의 단방향 통신만으로는 부족할 수 있다. 이럴 때는 액션(Action)과 서비스(Service)를 적절히 활용한다.

1. **서비스(Service)**
   * 요청과 응답이 명확히 한 번씩 일어나는 구조다.
   * 단시간에 처리 가능한 작업(예: 센서 값 한 번 읽기, 단순 계산 요청)에 적합하다.
   * 로봇 A가 로봇 B에게 “현재 배터리 상태를 알려달라”고 요청하면, 로봇 B가 배터리 상태를 확인해 즉시 응답하는 형태가 가능하다.
   * QoS 설정은 액션과 유사하게 여러 파라미터를 지정할 수 있지만, 기본적으로 서비스 호출 자체가 동기적인 특성을 가지므로, 호출 지연이나 실패에 대한 예외 처리가 중요하다.
2. **액션(Action)**
   * 골(Goal)을 전송하고, 중간 피드백(Feedback)을 받으며, 최종 결과(Result)를 수신한다.
   * 경로 추종, 파지(grasping) 작업처럼 어느 정도 시간이 걸리는 작업에 적합하다.
   * 액션 서버(로봇 B)가 하나의 복잡한 작업을 처리하는 동안, 액션 클라이언트(로봇 A)는 다른 노드들에게서 오는 메시지도 동시에 처리할 수 있다(비동기 구조).
   * 액션 통신 역시 내부적으로는 DDS를 통한 토픽과 서비스가 결합된 형태로 구현된다. 설정 방법은 다음과 같다.
     * 액션 정의 파일(.action)에 Goal, Feedback, Result 메시지 타입을 기술한다.
     * 액션 서버는 Goal 토픽을 구독, Feedback 토픽을 퍼블리시, Result를 서비스 호출 형태로 반환한다.
     * 액션 클라이언트는 Goal을 전송하고, Feedback 구독, Result를 요청 및 수신한다.
3. **멀티로봇 시나리오 예**
   * 로봇 A가 로봇 B에게 특정 지점까지 이동하라는 이동(Move) 액션을 보낸다.
   * 로봇 B는 이동 중 경로 이탈 여부, 예상 도착 시간 등을 실시간으로 Feedback 메시지로 전달한다.
   * 이동이 완료되면 Result 메시지로 최종 도착 지점 상태를 보고한다.
   * 로봇 A는 액션의 Goal Cancel 기능을 통해 이동 취소를 요청할 수도 있다.

액션과 서비스를 이용하면, 단순 토픽 퍼블리시/구독 패턴보다 훨씬 구조화된 통신이 가능하다. 하지만 서비스나 액션에서 QoS를 잘못 설정하면 응답이 제대로 수신되지 않는 상황이 생길 수 있다. 따라서 신뢰도(Reliable) 등을 신중히 선택해야 한다.

#### 라이프사이클(Lifecycle) 노드와 멀티로봇 구성

ROS2는 노드의 상태(생성, 활성화, 비활성화, 종료 등)를 엄격하게 관리하는 라이프사이클(Lifecycle) 개념을 지원한다. 멀티로봇 운영 시 여러 노드를 동적(온디맨드)으로 활성화하거나, 오류 시 안전하게 노드를 비활성화하기 위해 쓰일 수 있다.

* **라이프사이클 상태 전이**
  * `unconfigured` → `inactive` → `active` 등 단계별로 노드가 상태를 바꾸면서 내부 리소스(토픽, 파라미터 등)를 준비 또는 해제한다.
  * 관리 노드(Manager)는 서비스 호출 방식으로 라이프사이클 노드의 상태 전이를 지시할 수 있다.
* **장점**
  * 로봇 부팅 시점에 모든 노드가 동시에 활성화되면, DDS Discovery와 초기 설정이 복잡해질 수 있다. 라이프사이클 노드를 이용해 순차적으로 활성화하면 안정적이다.
  * 오류가 난 노드를 빠르게 `inactive` 상태로 바꾼 뒤, 재설정(파라미터 수정 등)하고 다시 `active`로 전환할 수 있다.
* **예시**
  * 로봇 A가 SLAM 라이프사이클 노드를 보유하고 있고, 주변 환경이 적절치 않으면 일시적으로 SLAM 노드를 비활성화(`inactive`) 상태로 둔다.
  * 로봇 B에서 “이동 지시” 액션을 보낼 때, SLAM 노드가 필요해지면 로봇 A가 슬램 노드를 `active` 상태로 전환한다.

이처럼 라이프사이클 노드를 통해 복잡한 멀티로봇 시스템에서도 노드별 자원 사용을 제어하고 장애 상황에 탄력적으로 대응할 수 있다.

#### Launch 파일을 통한 멀티로봇 배포

ROS2에서는 여러 노드를 한번에 실행하고, 파라미터나 리매핑, 네임스페이스 설정 등을 관리할 때 `launch` 파일을 사용한다. 멀티로봇 시나리오에서는 다음과 같은 방식을 적용할 수 있다.

Q**공통 Launch 파일과 로봇별 Launch 파일**:

* 공통 Launch 파일: 로봇 구분 없이 모든 시스템에 필요한 공통 노드(예: 모니터링 노드)를 정의한다.
* 로봇별 Launch 파일: 각 로봇에 필요한 센서 드라이버, 제어 노드 등을 정의하고, 네임스페이스나 파라미터를 차별화한다.

**네임스페이스 동적 설정**: Launch 파일에서 `DeclareLaunchArgument` 등을 사용해 로봇 이름(예: `robot_name:=robotA`)을 파라미터로 받아, 노드 네임스페이스를 동적으로 설정할 수 있다. 예시:

```python
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node

def generate_launch_description():
    robot_name_arg = DeclareLaunchArgument('robot_name', default_value='robotA')
    robot_name = LaunchConfiguration('robot_name')

    odom_pub = Node(
        package='my_robot_pkg',
        executable='odom_publisher',
        name='odom_pub',
        namespace=robot_name
    )

    return LaunchDescription([
        robot_name_arg,
        odom_pub
    ])
```

`$ ros2 launch my_robot_pkg multi_robot.launch.py robot_name:=robotB` 명령으로 실행하면, 노드가 `/robotB/odom_pub` 네임스페이스로 기동된다.

**멀티로봇 동시 실행**:

* 각각의 로봇에 대해 다른 터미널에서 위 Launch 파일을 호출하면서, `robot_name`을 다르게 주어 동시에 실행할 수 있다.
* 물리적으로 다른 호스트(PC)에서 같은 Launch 파일을 구동해도 되며, 네트워크만 공유되면 DDS Discovery를 통해 상호 인식된다.

#### ROS2 실행 환경 자동화

멀티로봇 운영 시 로봇 개수가 많아질수록, 매번 일일이 SSH 접속해 Launch 파일을 실행하기는 번거롭다. 이런 경우 다음과 같은 자동화 방법을 고려할 수 있다.

1. **Ansible, Fabric, SaltStack 등**
   * 다수 로봇 호스트에 SSH를 통해 일괄적으로 명령을 전달하는 툴이다.
   * 로봇별 IP 주소를 인벤토리에 기록해 두고, 원하는 스크립트를 한 번에 실행한다.
2. **Docker / Kubernetes**
   * 컨테이너 환경에서 ROS2 노드를 패키징해 배포하면, 종속성이 서로 다른 여러 로봇에게도 일관된 환경을 제공할 수 있다.
   * Kubernetes를 사용하면 로봇(노드)을 “파드(Pod)”로 운영할 수도 있다. 다만 물리적 하드웨어 리소스(센서, 모터 등) 접근을 고려해야 하므로 구성 난이도가 높다.
3. **Systemd 서비스 등록**
   * 임베디드 리눅스 시스템에서 부팅 시 자동으로 ROS2 노드를 실행하고 싶다면, systemd에 서비스를 등록한다.
   * `/etc/systemd/system/robotA.service` 같은 파일에 로봇 노드 실행 스크립트를 지정하고 `systemctl enable robotA.service`로 설정한다.

#### 장애 대응 전략과 고가용성(High Availability)

멀티로봇 시스템은 단일 로봇 고장보다 더 복잡한 장애 상황이 발생할 수 있으므로, 이를 사전에 예방하거나 신속하게 복구하는 전략이 필요하다.

1. **노드 수준의 장애 대응**
   * 특정 노드(예: 센서 드라이버)가 다운되면, 자율적으로 재시작을 수행하도록 노드 관리 스크립트나 수퍼바이저(Supervisor)를 둘 수 있다.
   * 라이프사이클(Lifecycle) 노드가 `inactive` 상태에서 예외 처리를 거친 후 `active`로 돌아오도록 설계하면, 전체 ROS 네트워크를 재기동할 필요 없이 로컬 장애만 해결할 수 있다.
2. **로봇 수준의 장애 대응**
   * 로봇이 통째로 전원 이상, 네트워크 단절 등으로 오프라인될 경우, 나머지 로봇들이 해당 로봇의 역할을 인계받을 수 있는지(협업 구조)를 고려해야 한다.
   * 예: 로봇 A가 SLAM 맵 서버 역할을 하고 있었다면, 로봇 B가 대체 서버를 기동할 수 있도록 대기 모드의 노드를 준비해 둘 수 있다.
3. **고가용성(High Availability) 통신**
   * 네트워크 스위치나 AP(Access Point)가 장애를 일으킬 경우를 대비해 중복 경로(Redundant Path)나 이중화된 네트워크 장비를 준비할 수 있다.
   * DDS 레벨에서도 멀티캐스트 그룹을 분산하거나, 여러 유니캐스트 경로를 설정해 장애 시 대체 경로로 전송을 시도하는 미들웨어 옵션이 있을 수 있다.
4. **로그/모니터링 시스템**
   * ROS2 노드에서 발생하는 에러 메시지나 워닝, 토픽 상태 등을 일괄적으로 모니터링할 로깅 시스템(EFK 스택, Prometheus 등)을 도입하면, 장애 발생 시점을 신속히 파악할 수 있다.
   * 로깅 시, CPU나 메모리 사용량, 토픽 트래픽 양까지 함께 수집하여 병목 지점을 찾는다.

#### 시뮬레이션 기반 멀티로봇 통신 테스트

실제 물리 로봇이 여러 대 필요할 때, 비용이나 환경 제약이 있을 수 있으므로 시뮬레이터를 활용해 멀티로봇 통신 테스트를 할 수 있다.

1. **Gazebo, Ignition(ign-gazebo)**
   * 가상 환경에서 여러 대의 로봇(UGV, UAV 등)을 동시에 스폰(spawn)하고, 각각의 센서(카메라, LiDAR, IMU 등) 토픽을 퍼블리시한다.
   * 로봇별 네임스페이스를 부여하여, 실제 물리 로봇 운영과 거의 유사한 토픽/서비스 구조를 갖도록 구성한다.
2. **합성된 네트워크 지연/손실 테스트**
   * 시뮬레이터와 실제 네트워크를 연동하거나, 가상 네트워크 에뮬레이터(tc, netem 등)를 사용해 지연(latency), 패킷 손실율을 인위적으로 늘려볼 수 있다.
   * 예: `$ sudo tc qdisc add dev eth0 root netem delay 100ms loss 5%` 형태로 네트워크를 제어해 보고, 로봇 간 협업 알고리즘이 어떻게 반응하는지 점검한다.
3. **대규모 스케일 테스트**
   * 10대 이상의 로봇 시나리오를 시뮬레이션으로 미리 검증하면서, Discovery 지연이나 토픽 트래픽 폭주 현상을 관찰할 수 있다.
   * DDS 미들웨어에 따라 최대 동시 노드 수에 차이가 있으므로, 시뮬레이션에서 이를 파악하고 실제 현장 적용 시 미들웨어 선택과 네트워크 구조를 최적화한다.

#### 멀티로봇 간 협업 알고리즘 예시

ROS2 통신 기능을 토대로, 다음과 같은 알고리즘을 구현할 수 있다.

1. **스완밍(Swarming)**
   * 다수 로봇이 서로의 상대적 위치를 교환하며, 특정 대형(Formation)을 유지한다.
   * 각 로봇은 주기적으로 자신의 위치를 퍼블리시하고, 다른 로봇의 위치를 구독해 경로 생성 알고리즘(예: 인공 잠재장, 분산 합의 알고리즘 등)을 수행한다.
   * QoS는 위치 정보가 최신성을 유지하도록 Best Effort + Keep Last(1) 정도로 충분할 수 있다.
2. **탐색(Exploration)**
   * 여러 로봇이 지도 작성(SLAM)과 동시에 미지 영역을 분산 탐색한다.
   * 중앙 서버(혹은 로봇 중 한 대)가 탐색 영역을 할당(Action)하고, 각 로봇은 SLAM 노드를 통해 맵 업데이트를 공유한다.
   * 맵 데이터나 위치 정보를 Reliable QoS로 설정해, 유실 없이 공유되도록 한다.
3. **작업 분담(Task Allocation)**
   * 멀티로봇 작업(운반, 공정 로봇 등) 시, 작업 큐(Task Queue)를 두고 로봇들이 자율적으로 작업 할당을 요청한다.
   * QoS는 중요도가 높은 메시지(작업 할당 요청, 승인)는 Reliable로, 빈번한 상태 업데이트(단순 Heartbeat)는 Best Effort로 분리해 네트워크 부하를 줄인다.

이처럼 알고리즘마다 통신 특성(실시간성, 메시지 신뢰도, 빈도)이 달라지므로, ROS2 QoS와 멀티 노드 구조를 최적화하는 것이 중요하다.

#### 테스트 및 검증 체크리스트

멀티로봇 노드 통신 설정을 마친 뒤, 실제로 배포하기 전에는 아래와 같은 항목을 점검해야 한다.

1. **Discovery 확인**
   * `$ros2 node list` 결과에 각 로봇의 노드가 모두 보이는지, `$ ros2 topic list`에서 의도했던 토픽이 잘 인식되는지 확인한다.
2. **QoS 호환성 점검**
   * QoS mismatch로 인해 토픽이 구독되지 않는 경우가 없는지, `$ ros2 topic info --verbose <topic_name>` 등을 이용해 퍼블리셔-서브스크라이버가 일치하는지 확인한다.
3. **통신 지연/버퍼 오버런**
   * 실제 환경(예: Wi-Fi 간섭이 많은 공장)에서 메시지 지연이 발생하거나 손실이 심한지 모니터링한다.
   * `$ros2 topic hz <topic_name>`로 토픽 퍼블리시 빈도, `$ ros2 topic delay <topic_name>`로 지연 정도를 측정한다.
4. **로봇 고유 파라미터 확인**
   * 네임스페이스가 정확하게 설정되어 있는지, 잘못된 토픽 이름 충돌로 인해 메시지가 엉뚱한 로봇에게 가는지 확인한다.
   * 필요 시 `$ros2 param list`, `$ ros2 param get <node> <param_name>` 등을 써서 로봇별 파라미터 세팅을 점검한다.
5. **장애 발생 시나리오 시뮬레이션**
   * 특정 로봇이 일시적으로 오프라인될 때, 나머지 시스템이 정상 동작을 유지하는지(토픽 전송이 중단되지 않는지) 확인한다.
   * 노드 재시작 시 Discovery에 다시 합류해 정상적으로 통신을 재개하는지 검사한다.

위 과정들을 종합적으로 실행해 보고, 이상 현상이 발견되면 네트워크 설정, QoS 수정, 노드 구조 재설계 등을 통해 최적화한다.
