# ROS2 Humble 설치 후 확인 및 문제 해결 기본 팁

#### ROS2 Humble 버전 확인

ROS2 Humble이 정상적으로 설치되었는지 확인하기 위해서는 먼저 설치된 ROS2 버전을 확인해야 한다. 다음 명령어로 현재 로드된 ROS2 버전을 확인할 수 있다.

```
ros2 version
```

위 명령어로 버전이 정상적으로 표시되지 않으면 설치 경로 및 환경 변수가 올바르게 설정되었는지 우선 점검한다.

**ROS2 설치 경로 확인**

ROS2는 일반적으로 다음 경로에 설치된다.

* Ubuntu: `/opt/ros/humble`
* Windows: `C:\dev\ros2\humble`
* MacOS: `/Users/<사용자이름>/ros2_humble/` (혹은 Homebrew를 이용한 경우 `/opt/homebrew/opt/ros-humble` 경로 등)

설치 경로를 찾기 어렵거나 권한 문제가 의심된다면, 설치 관리자(apt, choco 등)를 통해 다시 확인한다.

#### ROS2 환경 변수 설정 확인

ROS2를 사용하기 위해서는 설치 후 매 세션마다 ROS2 환경 변수 설정이 필요하다. `$ROS_DISTRO`와 같은 핵심 환경 변수가 제대로 설정되어 있는지 반드시 확인해야 한다.

**환경 변수 로드하기**

ROS2를 설치한 후 아래 명령어를 통해 ROS2 설치가 제공하는 setup 스크립트를 실행하면, 필요한 환경 변수가 로드된다.

```
source /opt/ros/humble/setup.bash
```

다른 쉘을 사용 중이거나 자동화를 위해서는 `.zshrc`, `.bashrc`에 위 명령어를 추가해 매번 입력 없이 자동으로 로드되도록 설정한다.

**환경 변수 확인하기**

다음 명령어로 환경 변수들이 제대로 설정되었는지 간단히 점검할 수 있다.

```
printenv | grep ROS
```

`ROS_DISTRO=humble` 등이 정상적으로 출력되면, ROS2 Humble 관련 환경 변수가 적용된 것이다.

**간단한 수식 예시**

ROS2에서 필요한 환경 변수와 사용자 정의 환경 변수를 단순 벡터 형태로 생각하면 다음과 같다.

$$
\mathbf{x}*{env} = \mathbf{x}*{ROS} + \mathbf{x}\_{USER}
$$

이때 $\mathbf{x}*{env}$는 최종적으로 적용된 환경 변수들의 집합이고, $\mathbf{x}*{ROS}$는 ROS 설치에 의해 등록된 변수의 집합, $\mathbf{x}\_\text{USER}$는 사용자가 별도로 설정한 변수의 집합이다.

#### ROS2 Doctor 활용

ROS2의 기본 진단 도구인 `ros2 doctor`를 이용하면 시스템 환경, ROS2 네트워크 상태 등의 전반적 점검이 가능하다.

```
ros2 doctor --report
```

* **ROS2 버전**: 설치된 ROS2 버전을 확인한다.
* **Network**: Multicast 및 UDP 통신이 제한되어 있지 않은지 점검한다.
* **RMW**: 어떤 RMW(ROS Middleware)가 적용되어 있는지 보고한다.

만약 여기서 경고나 오류가 발생한다면, 해당 메시지 내용을 자세히 살펴보고 네트워크 설정, 방화벽 설정, RMW 설정 등을 점검해야 한다.

#### colcon 명령어 확인

ROS2 패키지를 빌드할 때는 주로 `colcon build` 명령어를 사용한다. ROS2 Humble 설치 과정에서 `colcon`도 함께 설치되었는지 확인하고, 제대로 동작하는지 시험한다.

```
colcon --version
```

출력이 정상이라면 colcon이 설치 및 경로 설정이 되어 있는 것이다. 만약 여기서 `'colcon: command not found'` 같은 오류가 발생한다면, `python3-colcon-common-extensions` 등의 의존성 패키지가 누락되었거나 `PATH`가 제대로 설정되지 않았는지 살핀다.

#### 간단 빌드 테스트

ROS2가 잘 설치되었는지, colcon이 정상적으로 동작하는지를 확인하기 위해 예제 패키지를 빌드해본다. 다음과 같이 `demo_nodes_cpp` 패키지가 이미 설치되어 있는지 확인할 수 있다.

```
ros2 pkg list | grep demo_nodes_cpp
```

결과가 나오면, ros2 코어 예제 패키지가 설치된 것이다. 만약 demo\_nodes\_cpp가 뜨지 않는다면 `ros-humble-demos` 패키지가 누락되었을 가능성이 있다.

**개념 흐름도**

{% @mermaid/diagram content="flowchart LR
A\["ROS2 Humble 설치"]
B\["환경 변수 설정"]
C\["colcon 설치 확인"]
D\["빌드 테스트"]
A --> B
B --> C
C --> D" %}

위 순서대로 설치 검증 과정을 거치면, 큰 문제 없이 ROS2 Humble의 기본 환경이 준비된 것이다.

#### Topic 및 Node 동작 확인

ROS2가 제대로 동작하는지 추가로 확인하고 싶다면, ROS2가 제공하는 기본 명령어를 통해 Topic과 Node 목록을 확인해볼 수 있다.

```
ros2 topic list
ros2 node list
```

* **ros2 topic list**: 현재 활성화되어 있는 Topic 목록을 보여준다.
* **ros2 node list**: 현재 실행 중인 Node 목록을 확인할 수 있다.

정상적으로 실행 중인 ROS2 Node가 없는 상태라면 빈 목록이 출력될 수 있다. 따라서 확인 전, 예제 노드를 간단히 실행해두는 것이 좋다.

**Talker/Listener 예제 실행**

ROS2 설치 시 함께 설치된 예제 패키지인 `demo_nodes_cpp`나 `demo_nodes_py`의 talker와 listener 노드를 실행해볼 수 있다.

```
# 터미널 1
ros2 run demo_nodes_cpp talker
# 터미널 2
ros2 run demo_nodes_cpp listener
```

* **talker**가 `/chatter`라는 Topic을 통해 정기적으로 메시지를 발행(publish)한다.
* **listener**는 동일한 Topic을 구독(subscribe)하며 메시지를 수신한다.

이때, 메시지가 정상적으로 송수신되는지 확인하고, 아래 명령어를 통해 Topic과 Node 목록에도 talker, listener가 포함되는지 확인한다.

```
ros2 topic list
ros2 node list
```

#### Domain ID 설정 확인

ROS2 DDS(Dataplicity Discovery Service)를 통해 네트워크 레벨에서 참여 노드를 구분할 때 `ROS_DOMAIN_ID`가 중요한 역할을 한다. 기본값은 0으로 설정된다.

```
echo $ROS_DOMAIN_ID
```

* 여러 로봇 혹은 여러 개발 환경을 분리하고 싶다면 서로 다른 Domain ID를 부여한다.
* Domain ID가 다르면 서로 통신이 불가능하므로, 협업 과정에서 Domain ID가 통일되어 있는지 반드시 확인해야 한다.

#### DDS 벤더(RMW) 문제 해결

ROS2는 DDS 구현체(RMW, ROS Middleware)를 다르게 사용할 수 있다. 기본적으로는 CycloneDDS나 FastDDS를 많이 사용한다. 특정 DDS에서 네트워크 문제가 발생하거나, 다른 DDS를 사용해야 할 경우 다음 환경 변수를 점검한다.

```
printenv | grep RMW
```

* **RMW\_IMPLEMENTATION**: 사용할 RMW 라이브러리를 지정한다. 예) `rmw_fastrtps_cpp`, `rmw_cyclonedds_cpp`

필요에 따라 변경하고 싶다면 다음과 같이 설정한다.

```
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
```

그 후, 다시 setup.bash를 불러오거나 터미널을 재시작해 반영한다.

#### DDS 포트 설정

같은 네트워크 환경에서 포트 충돌로 인해 통신 장애가 발생할 수도 있다. 예를 들어, CycloneDDS의 경우 설정 파일(기본적으로 `/etc/cyclonedds/cyclonedds.xml` 또는 사용자 홈 디렉터리 내 `.cyclonedds.xml`)에서 포트를 세부 조정할 수 있다.

```xml
<CycloneDDS>
  <Domain id="0">
    <Transport>udp4</Transport>
    <Discovery>
      <Tag>ROS2 Cyclone DDS</Tag>
      <AnnouncePeriod>100ms</AnnouncePeriod>
    </Discovery>
    <Internal>
      <MetaMulticastPort>7401</MetaMulticastPort>
      <MetaUnicastPort>7402</MetaUnicastPort>
    </Internal>
  </Domain>
</CycloneDDS>
```

포트가 겹치지 않도록 적절히 설정한 후, ROS2 노드를 재시작해 충돌이 해결되는지 확인한다.

#### 네트워크 방화벽 점검

기업 내 VLAN 환경 등에서는 멀티캐스트 및 특정 UDP 포트를 막아 놓는 경우가 많다. `ros2 doctor --report`나 DDS 설정에서 멀티캐스트가 차단되었는지, 포트 사용이 가능한지 다시 한 번 검토해야 한다.

* **UDP 포트 개방**: CycloneDDS나 FastDDS가 사용하는 포트를 방화벽에서 허용해야 한다.
* **Multicast 라우팅**: 일부 네트워크 장비에서 멀티캐스트를 차단할 수 있으므로, 필요한 경우 Broadcast 혹은 Unicast Discovery 설정을 병행한다.

#### 추가 디버깅 툴

ROS2 네트워크 환경에서 데이터가 제대로 흘러가는지, 특정 토픽이 누락되는지 등을 쉽게 모니터링하기 위해 다음 도구들을 사용할 수 있다.

rqt\_graph: Topic과 Node의 연결 상태를 그래프로 시각화한다.

```
ros2 run rqt_graph rqt_graph
```

rqt\_console: ROS2 로그 메시지를 실시간으로 모니터링한다.

```
ros2 run rqt_console rqt_console
```

rviz2: 센서 데이터나 3D 환경을 시각화한다.

```
ros2 run rviz2 rviz2
```

이들 툴을 사용하면 특정 노드나 토픽이 정상 동작하지 않거나, 메시지가 어디서 누락되고 있는지 직관적으로 파악할 수 있다.

#### Docker 환경에서의 문제 해결

개발 환경을 Docker로 구성하는 경우, 컨테이너와 호스트 간 네트워크 설정이 복잡해질 수 있다. 특히 다음 요소를 점검한다.

1. **Bridge Network**: Docker Bridge를 이용할 때, 컨테이너 간 멀티캐스트 통신이 정상 동작하는지 확인한다.
2. **Host Network**: 개발 시에는 호스트 네트워크 모드를 사용해 복잡성을 줄일 수도 있다.
3. **ROS\_DOMAIN\_ID**: 여러 컨테이너가 서로 다른 Domain ID를 사용하면 통신이 되지 않는다.

**컨테이너 간 Node 확인**

예를 들어, talker를 컨테이너 A에서 실행하고 listener를 컨테이너 B에서 실행한다면, 서로 통신 가능한지 아래와 같이 터미널을 분리해 테스트한다.

```
# 컨테이너 A
ros2 run demo_nodes_cpp talker
# 컨테이너 B
ros2 run demo_nodes_cpp listener
```

* 컨테이너 A, B 모두 동일한 `ROS_DOMAIN_ID`인지 확인한다.
* Docker network 설정에서 UDP 멀티캐스트가 차단되지 않았는지 확인한다.

#### Python 버전 충돌 문제

ROS2 Humble은 Python3를 기반으로 동작한다. Ubuntu 22.04 기준으로 기본 Python 버전도 Python3이므로 큰 문제가 없지만, 다음 사항을 점검해보자.

**파이썬 버전 확인**

```
python3 --version
```

ROS2 Humble은 Python 3.10 이상(혹은 배포에 따라 3.9 이상)이 적절하다.

**가상환경 문제** Anaconda 혹은 다른 가상환경(venv)을 사용하는 경우, ROS2 환경 스크립트와 충돌이 발생할 수 있다.

* 가상환경이 활성화된 상태에서 ROS2를 사용한다면, ROS2 패키지들이 해당 가상환경의 site-packages를 찾지 못하거나, 반대로 의도치 않은 라이브러리를 로드하게 될 수 있다.
* 가상환경을 사용하기 전, ROS2 환경 스크립트(`setup.bash`)가 가상환경보다 먼저 로드되는지 순서를 확인한다.

**Python PATH 점검**

```
printenv | grep PYTHONPATH
```

* ROS2는 설치 시 특정 site-packages 경로를 PYTHONPATH에 추가해둔다.
* 가상환경 혹은 사용자가 추가한 경로가 먼저 잡혀 있으면, ROS2 Python 라이브러리가 정상 인식되지 않을 수 있다.

#### QoS(품질서비스) 관련 문제

ROS2의 다양한 QoS 설정은 노드 간 통신이 기대와 다르게 동작할 때 흔히 원인이 된다.

Reliability: `reliable` vs `best_effort`

* Sensor data 등 빠른 전송이 필요한 경우 `best_effort`를 쓰지만, 신뢰성 보장이 필요한 경우 `reliable` 모드를 사용한다.

Durability: `volatile` vs `transient_local`

* 늦게 구독(subscribe)을 시작해도 이전에 발행된 메시지를 받고 싶다면 `transient_local` 설정이 필요하다.

History: `keep_last` vs `keep_all`

* 버퍼 크기 등에 따라 메시지 누락이 발생할 수 있다.

노드 간 QoS 설정이 서로 호환되지 않으면 ROS2에서 토픽이 보이더라도 메시지 전달이 이루어지지 않을 수 있다.

```
ros2 topic echo /example_topic --qos-reliability best_effort
```

등을 통해 QoS를 달리하여 메시지가 수신되는지 점검할 수도 있다.

#### tf2 및 time 동기화 문제

ROS2에서는 `tf2` 라이브러리를 통해 좌표 변환(Transform)을 다룬다. 노드 간 시간 동기화가 정확히 이루어지지 않으면 TF Tree가 정상적으로 구성되지 않을 수 있으므로 다음 사항을 주의 깊게 살펴보자.

1. System Clock
   * 실제 하드웨어 로봇에서 NTP 등을 통해 시간을 맞추지 않으면, 센서 데이터 타임스탬프와 ROS2 시스템 시간이 불일치하여 TF Tree가 깨지거나 늦게 업데이트될 수 있다.
2. sim\_time

   (시뮬레이션 시간 사용)

   * Gazebo나 Ignition, Webots와 같은 시뮬레이터를 쓸 때는 `/use_sim_time` 파라미터를 `true`로 설정하여 시뮬레이터가 발행하는 시간 정보를 사용한다.
   * 만약 실제 시뮬레이터가 돌고 있지 않은데 `/use_sim_time`를 켜둔다면, 노드들이 '정지된 시간'을 참조하여 오작동할 수 있다.

#### ros2 param 문제 해결

ROS2 노드에 파라미터를 동적으로 전달하고, 파라미터가 실제 적용되었는지 확인하려면 `ros2 param` 명령어를 사용한다.

```
ros2 param list
ros2 param get <노드이름> <파라미터이름>
ros2 param set <노드이름> <파라미터이름> <값>
```

* 파라미터 서버(Node 개념) 없이도 개별 노드가 파라미터를 갖고 있다.
* 파라미터가 존재하지 않는다면, 해당 노드가 해당 파라미터를 선언하지 않았거나 동적 파라미터 수정을 허용하지 않는 것이다.

#### 의존성 누락 확인

ROS2 패키지 의존성이 누락되어 빌드가 실패하거나 런타임에 문제가 생기는 경우가 있다. `colcon build` 과정에서 `Could not find a package configuration file` 또는 `missing dependency` 오류가 발생할 수 있다.

apt로 설치: ROS2 코어/공식 패키지에서 제공하는 의존성:

```
sudo apt update
sudo apt install ros-humble-<package-name>
```

vcs import

* 서드파티 소스 패키지를 따로 가져올 때는 `.repos` 파일을 이용한다.
* `.repos`에 기재되지 않은 의존 패키지가 있을 수 있으므로, 패키지 문서의 의존 정보를 확인한다.

#### 빌드 캐시 정리

colcon 빌드 과정에서 이전 빌드 캐시가 꼬여 예기치 못한 에러가 발생하기도 한다. 아래와 같이 빌드 결과물과 설치 디렉터리를 삭제 후 다시 빌드를 시도해볼 수 있다.

```
rm -rf build/ install/ log/
colcon build
```

* **build/**: 소스 코드를 빌드하여 컴파일 산출물이 들어 있는 디렉터리
* **install/**: 패키지 설치 결과물(실행 파일, 라이브러리, 파이썬 모듈 등)
* **log/**: 빌드 로그 및 에러 로그

위 디렉터리를 지우면, 완전히 새 빌드를 진행하므로 문제 해결의 단서가 될 수 있다.

#### C++ ABI 호환성 이슈

ROS2 Humble에서 제공되는 C++ 라이브러리와 사용자가 설치한 C++ 라이브러리가 버전이 맞지 않으면 런타임 충돌이 발생할 수 있다.

* 일반적으로 Ubuntu 22.04에서는 GCC 11을 사용한다.
* 서드파티 라이브러리(예: PCL, OpenCV 등)를 다른 경로에서 빌드해 설치했다면, ROS2가 참조하는 ABI와 달라서 문제가 생길 수 있다.

**해결 방법**

* 되도록이면 ROS2용 apt 패키지를 사용하고, 빌드 시에는 호환되는 GCC 버전을 사용한다.
* 서드파티를 별도로 빌드할 경우, ROS2 Humble과 동일한 도구 체인을 사용하도록 주의한다.

#### Launch 파일 문제

ROS2는 `launch` 시스템으로 여러 노드를 한 번에 실행할 수 있다. launch 파일에서 파라미터 설정, 환경 변수 주입, 리맵 등을 수행하는데, 문법 오류나 패키지 경로가 올바르지 않으면 노드가 뜨지 않을 수 있다.

```python
from launch import LaunchDescription
from launch_ros.actions import Node

def generate_launch_description():
    return LaunchDescription([
        Node(
            package='demo_nodes_cpp',
            executable='talker',
            name='talker',
            output='screen'
        ),
        Node(
            package='demo_nodes_cpp',
            executable='listener',
            name='listener',
            output='screen'
        )
    ])
```

* **package**: ROS2에서 인식되는 패키지 이름
* **executable**: `ros2 pkg executables <패키지명>`으로 확인 가능한 노드 실행 파일 이름
* **output**: `'screen'`을 통해 콘솔에 직접 로그가 출력되는지 확인할 수 있다.

만약 launch 파일 실행 시 아무 메시지 없이 종료되면, launch 파일 내 오탈자나 `Node` 설정 오류가 없는지 점검한다.

#### Visual Studio Code (VSCode) 연동 문제

VSCode에서 ROS2 Humble을 개발 환경으로 설정하는 경우, 아래 항목들을 점검한다.

1. ROS Extension
   * Open Robotics가 제공하는 VSCode용 ROS 확장(extension)을 설치하면, ROS 메타 정보를 인식해주는 편의 기능이 제공된다.
2. Dev Containers
   * Docker를 사용한다면 `.devcontainer/devcontainer.json` 등을 설정하여 컨테이너 안에서 VSCode를 사용할 수 있다.
3. C/C++ IntelliSense
   * ROS2 헤더 파일 경로(`/opt/ros/humble/include` 등)를 `c_cpp_properties.json` 혹은 C/C++ 설정에서 추가로 지정해야 한다.

#### SROS2 보안 설정

ROS2는 DDS를 기반으로 하며, 필요할 경우 DDS 자체 보안 기능(Access Control, Cryptography, Logging)을 활용할 수 있다. ROS2에서도 **SROS2**라는 패키지를 통해, 노드 간 통신을 암호화하고 인증서를 사용하여 통신 상대를 제한할 수 있다.

보안 확장 패키지 설치

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

보안 디렉터리 생성: 안전한 노드별 정책 파일과 인증서를 관리하기 위해서는 적절한 디렉터리 구조를 갖춰야 한다. 예:

```
sros2 create_keystore ~/sros2_demo_keystore
```

**정책 파일 편집**: `yaml` 형태의 정책 파일을 통해 각 노드가 어떤 Topic에 접근할 수 있는지, 어떤 권한으로 통신하는지를 설정한다.

보안 활성화: 아래와 같이 환경 변수를 설정하고 노드를 실행하면 보안 모드가 활성화된다.

```
export ROS_SECURITY_ENABLE=true
export ROS_SECURITY_STRATEGY=Enforce
export ROS_SECURITY_KEYSTORE=~/sros2_demo_keystore
```

SROS2를 활성화하면, 인증서나 권한이 없는 노드는 해당 Topic에 접근할 수 없게 된다. 협업이나 기업 네트워크에서 중요한 데이터를 다룰 때 SROS2를 설정해두면, 무단 접근이나 중간자 공격에 대한 위험을 줄일 수 있다.

#### Cross-compiling

임베디드 장치나 ARM 기반 SoC에서 ROS2 Humble을 구동하기 위해서는 **크로스 컴파일**(cross-compiling)이 필요할 때가 많다.

**Sysroot 준비**: 목표 플랫폼(예: 라즈베리 파이 등)의 라이브러리, 헤더 파일이 포함된 sysroot 디렉터리를 구축한다.

CMake 툴체인 파일 `colcon` 빌드 시, 다음과 같이 툴체인 파일을 지정한다.

```
colcon build \
  --merge-install \
  --cmake-args \
    -DCMAKE_TOOLCHAIN_FILE=/path/to/toolchain.cmake \
    -DCMAKE_SYSROOT=/path/to/sysroot
```

의존성 확인

* 크로스 컴파일 이전에 apt나 SDK로 필요한 ROS2 의존 패키지를 모두 설치해야 한다.
* 네트워크 관련 DDS 설정이나 하드웨어 드라이버(USB, CAN 등) 설정은 목표 장치에 맞춰 별도로 진행한다.

성공적으로 빌드한 후, 목표 장치에서 해당 패키지를 실행해 네트워크 환경, 파일 경로가 정상적인지 최종 점검한다.

#### Real-time Linux

센서 데이터를 고속 처리하거나, 제어 루프 안정성을 위해 **실시간 Linux**(RT Preempt 커널 등)를 사용하는 경우도 있다.

RT Preempt 패치: Ubuntu 22.04용 저지연 커널(low-latency) 또는 RT Preempt 커널을 직접 빌드한다.

스케줄러 우선순위 조정: ROS2 노드 프로세스에 대해 `chrt` 명령어 등을 이용해 우선순위를 높게 부여할 수 있다. 예:

```
sudo chrt -f 90 ros2 run <패키지명> <노드>
```

DDS 설정

* CycloneDDS나 FastDDS에서 실시간 스레드 우선순위를 조정 가능하다.
* 또한 실시간 환경에서 Lock-Free 구조(Shared Memory, Zero-Copy)를 활용하면 지연 시간이 줄어들 수 있다.

#### Bag 레코딩(ros2 bag)

ROS2에서는 **ros2 bag**을 이용하여 토픽 데이터를 기록(Record)하고, 이후 재생(Playback)할 수 있다.

기록:

```
ros2 bag record /example_topic /another_topic
```

* 기본적으로 sqlite3 백엔드를 사용하며, 다른 스토리지 백엔드도 선택 가능하다.

재생:

```
ros2 bag play <bag파일경로>
```

* 기록 당시의 타임스탬프를 기반으로, 동일한 간격으로 메시지를 재생한다.

검증:

* `ros2 topic echo /example_topic` 등을 통해, bag이 정상적으로 재생되고 있는지 실시간 확인한다.
* QoS 문제가 있을 경우, 재생된 메시지가 구독 노드에 도달하지 않을 수 있으므로, 필요하다면 `--qos-*` 옵션을 사용해 QoS 설정을 맞춘다.

분석:

* recorded bag 파일을 오프라인에서 분석함으로써, 실시간 디버깅이 어려운 상황에서도 후처리를 통해 문제점을 찾을 수 있다.

#### Gazebo / Ignition 시뮬레이션 문제

ROS2 Humble에서 Gazebo(또는 Ignition) 시뮬레이터를 사용할 때, 다음과 같은 문제가 자주 발생한다.

**플러그인 버전 충돌**:

* Gazebo나 Ignition에서 제공하는 ROS2 플러그인(예: `ros_gz_sim`, `ros_gz_plugins`) 버전이 ROS2 Humble 버전과 맞지 않을 수 있다.
* `sudo apt install ros-humble-gazebo-ros-pkgs ros-humble-ros-gz-sim` 등을 이용하여 배포판에 맞는 패키지를 설치한다.

**시뮬레이터와 시간 동기**:

* 시뮬레이터를 사용하면 `/clock` 토픽이 발행되고, ROS2 노드들은 실제 시스템 시간이 아닌 시뮬레이터 시간을 사용한다.
* `use_sim_time` 파라미터가 `true`인지 확인하고, 다른 노드들이 이 시간을 참조하도록 설정한다.

**TF Tree 누락**:

* URDF, SDF 모델이 로딩되었는데 로봇 조인트나 링크의 TF가 시뮬레이터에서 발행되지 않는다면, 관련 플러그인을 확인한다.
* 예: Gazebo에서 `robot_state_publisher`를 함께 실행하거나, Ignition에서 `ign-gazebo`용 TF 브로드캐스팅 플러그인을 추가한다.

**센서 데이터 문제**:

* 카메라, LiDAR 등의 센서가 출력하는 토픽이 ros2 topic list에 보이지 않는다면, 시뮬레이터 플러그인 설정(`.sdf` 또는 `.xacro`)을 재검토한다.
* GPU 가속, CUDA 버전 이슈 등 하드웨어 종속적인 문제가 발생할 수도 있으므로, 해당 센서 플러그인이 필요한 라이브러리를 제대로 찾고 있는지 확인한다.

#### Nav2 (네비게이션 스택) 문제

ROS2 Humble에서 Nav2 패키지를 사용할 때 발생할 수 있는 대표적인 문제들이다.

**Nav2 구성 요소 누락**:

```
sudo apt install ros-humble-navigation2 ros-humble-nav2-bringup
```

* 꼭 필요한 bringup, BT(Action) 플러그인, SLAM 패키지 등이 설치되어 있는지 확인한다.

**TF 변환 누락**:

* Nav2는 `odom -> base_link` 및 `base_link -> sensor_frame` 변환을 필수로 요구한다.
* `ros2 run tf2_tools view_frames.py` 등으로 TF Tree를 시각화하고, 누락된 변환이 있는지 살핀다.

**맵 서버 설정**:

* Nav2에서 맵 서버가 올바른 지도(.yaml, .pgm) 파일을 로드하지 못하면, global costmap이 비어 있거나 초기 위치 설정(AMCL) 단계에서 문제가 발생한다.
* `nav2_params.yaml` 파일의 경로, `map_server:` 섹션 내 파라미터, 해상도(resolution), origin, free/occupied threshold 등을 점검한다.

**동적 파라미터(Behavior Tree) 충돌**:

* Nav2는 Behavior Tree(리커버리 행동, 목표 도달 판단 등)를 동적으로 변경할 수 있다.
* `bt_navigator` 노드에서 에러가 발생하거나 의도치 않은 동작을 한다면, BT XML 파일 구조(특히 파라미터 이름, action server 이름)를 재확인한다.

#### ROS2 Tracing을 활용한 성능 분석

고성능 애플리케이션에서 노드 간 통신 지연이나 콜백 처리 시간을 정밀하게 분석하려면, **ROS2 Tracing** 툴(`ros2_tracing`)을 사용할 수 있다.

설치:

```
sudo apt install ros-humble-ros2tracing
```

추적(Tracing) 시작:

`ros2 trace` 명령으로 노드 실행 전후에 트레이싱을 시작/종료할 수 있다. 예:

```
ros2 trace -s my_trace
# 다른 터미널에서 ros2 run demo_nodes_cpp talker
```

결과 분석

* 결과는 LTTng(Linux Trace Toolkit next generation) 형식으로 저장된다.
* `ros2 trace analyze my_trace` 등을 통해, ros2 콜백의 실행 시간, topic publish와 subscribe 사이의 지연 등을 시각적으로 파악할 수 있다.

#### rclcpp/rclpy 로깅

ROS2 C++ API(`rclcpp`), Python API(`rclpy`)에서 다음과 같이 로깅 매크로/함수를 사용한다.

```cpp
RCLCPP_INFO(this->get_logger(), "Hello from C++");
RCLCPP_WARN(this->get_logger(), "Warning: Something might be wrong");
RCLCPP_ERROR(this->get_logger(), "Error: Something went wrong!");
self.get_logger().info("Hello from Python")
self.get_logger().warn("Warning: Something might be wrong")
self.get_logger().error("Error: Something went wrong!")
```

* 로깅 레벨은 `info`, `warn`, `error`, `debug`, `fatal` 등이 있으며, 런타임에 파라미터로 레벨을 조정할 수도 있다.
* 이를 통해 문제 발생 시 정확한 메시지를 남겨, 디버깅 시간을 단축할 수 있다.

#### rclcpp Executor 설정

C++ 노드에서 Executor(스레드 관리자)를 적절히 구성하지 않으면, 콜백 호출 순서가 꼬이거나 성능이 저하될 수 있다.

1. SingleThreadedExecutor

   (기본값)

   * 모든 콜백이 단일 스레드에서 처리됨. 동시성은 낮지만 디버깅이 용이하다.
2. MultiThreadedExecutor
   * 여러 스레드로 콜백을 병렬 처리한다. 실시간 성능이나 대역폭이 큰 센서 처리에 적합하다.
3. StaticSingleThreadedExecutor
   * 초기 노드 등록 후 변경이 없을 때, 고정된 구성으로 약간의 오버헤드를 줄일 수 있다.

콜백 처리 중 공유 리소스 잠금, thread-safe 자료구조 사용 등을 면밀히 고려하지 않으면, 멀티스레드 환경에서 레이스 컨디션이 발생할 수 있으므로 주의한다.

#### ros1\_bridge 관련 문제

ROS1(Melodic, Noetic 등)과 ROS2(Humble) 간 메시지 교환이 필요한 경우, `ros1_bridge` 패키지를 이용할 수 있다.

1. 공통 메시지 타입
   * 브리지를 자동으로 생성하려면, ROS1과 ROS2에서 동일한 메시지 타입(버전)이 설치되어 있어야 한다.
   * 예: `std_msgs`, `sensor_msgs`, `nav_msgs` 등
2. ROS\_DOMAIN\_ID vs ROS\_MASTER\_URI
   * ROS1은 `ROS_MASTER_URI`로, ROS2는 `ROS_DOMAIN_ID`로 서로 다른 네트워크 방식을 사용한다.
   * ros1\_bridge 노드가 양쪽을 중계하기 위해서는 ROS1 Master에 연결하고, 동시에 ROS2 DDS 네트워크에 참여해야 한다.
3. 빌드 시점
   * ros1\_bridge는 ROS1과 ROS2 설치 환경이 모두 충돌 없이 구성되어 있어야 빌드가 성공한다.
   * ROS1용 workspace, ROS2용 workspace를 별도 관리하면서 `source /opt/ros/noetic/setup.bash && source /opt/ros/humble/setup.bash` 형태로 브리지를 빌드한다.

#### 기타 자주 묻는 문제

* CLI Autocompletion
  * ROS2 CLI의 자동완성 기능이 동작하지 않을 경우, 쉘 설정 파일(`.bashrc` 등)에 `source /opt/ros/humble/setup.bash`가 제대로 추가되어 있는지 재확인한다.
* GLIBC/GCC 호환성
  * Ubuntu 22.04가 아닌 다른 버전(또는 리눅스 배포판)에서 ROS2 Humble을 시도할 경우, C 라이브러리나 GCC 버전이 맞지 않아 설치가 어려울 수 있다. 공식 지원 버전을 사용하거나 Docker 이미지(official ROS2 image)를 사용하는 것이 안전하다.
* GUI 종속 라이브러리
  * rqt, rviz2 등 그래픽 툴 사용 시, GUI 관련 종속 라이브러리(Qt, Ogre 등)가 제대로 설치되지 않았다면 실행이 실패한다. `sudo apt install ros-humble-rviz2 ros-humble-rqt*`를 통해 필요한 패키지를 일괄 설치해본다.
