우분투 24.04 ROS 2 Jazzy 설치: apt 저장소 등록부터 talker/listener 테스트, rosdep·colcon, 자주 나는 오류

이 글의 핵심

ROS 2 Jazzy는 우분투 24.04(noble)용으로 빌드된 LTS 배포판이라, 22.04에서는 apt로 설치되지 않습니다. 이 글은 로케일 확인 → universe 활성화 → ros2-apt-source 패키지로 저장소·서명 키 등록 → ros-jazzy-desktop 설치 → setup.bash 소싱 → talker/listener 확인 → rosdep·colcon 작업 공간 준비 순서로 진행하고, 각 단계에서 자주 보는 오류 메시지와 해결법, 완전히 지우는 방법까지 다룹니다.

ROS 2를 처음 설치할 때 가장 많이 막히는 지점은 의외로 ROS 자체가 아니라 우분투 쪽입니다. 우분투 버전과 ROS 배포판의 짝이 안 맞거나, 예전 블로그 글의 GPG 키 등록 명령을 그대로 따라 했다가 apt update가 실패하거나, 설치는 끝났는데 ros2: command not found가 뜨는 식입니다. 이 글은 공식 설치 문서의 apt(deb 패키지) 방식을 따라가면서, 각 명령이 왜 필요한지와 빠뜨리면 어떤 오류가 나는지를 함께 설명합니다.

기준 환경: Ubuntu 24.04 LTS(코드명 noble) 데스크톱, amd64(x86_64) 또는 arm64. ROS 2 배포판은 Jazzy Jalisco이고, 셸은 기본 bash입니다. 2026년 10월 기준 공식 문서의 절차를 바탕으로 했으며, 저장소 등록 방식은 앞으로도 바뀔 수 있으니 오류가 나면 docs.ros.org의 Jazzy 설치 문서를 함께 확인하는 것을 권합니다.

Jazzy는 24.04, Humble은 22.04: 짝을 먼저 확인해야 하는 이유

ROS 2 바이너리 패키지는 특정 우분투 버전 하나를 대상으로 빌드됩니다. 패키지가 의존하는 시스템 라이브러리(파이썬, Boost, OpenCV, Qt 등)의 버전이 우분투 릴리스마다 다르기 때문입니다. 그래서 LTS 배포판끼리 짝이 정해져 있습니다.

ROS 2 배포판출시지원 종료대상 우분투 (Tier 1)시스템 파이썬
Humble Hawksbill (LTS)2022년 5월2027년 5월22.04 jammy3.10
Jazzy Jalisco (LTS)2024년 5월2029년 5월24.04 noble3.12
Kilted Kaiju2025년 5월2026년 11월24.04 noble3.12

짝을 어기면 어떻게 되는지는 간단합니다. packages.ros.org 저장소에는 우분투 코드명별로 디렉터리가 나뉘어 있고, noble 디렉터리에는 ros-humble-* 패키지가, jammy 디렉터리에는 ros-jazzy-* 패키지가 아예 없습니다. 그래서 22.04에서 Jazzy를 설치하려 하거나 24.04에서 Humble을 설치하려 하면 저장소를 제대로 등록했어도 다음 오류가 납니다.

E: Unable to locate package ros-jazzy-desktop

억지로 다른 버전의 .deb를 받아 설치하려 하면 의존성 지옥에 빠지고, 시스템 파이썬 버전이 달라서 설령 설치되더라도 정상 동작을 기대하기 어렵습니다. 24.04에서 Humble이 꼭 필요하다면(예: 회사 로봇 코드가 Humble 기준) 소스 빌드보다는 ros:humble Docker 이미지 안에서 쓰는 쪽이 훨씬 현실적입니다. Docker로 ROS 환경을 분리하는 방법은 ROS2 시뮬레이션 환경 Docker + Gazebo 설정에서 다룹니다.

내 우분투 버전은 다음 명령으로 확인합니다.

lsb_release -a
# 또는
cat /etc/os-release | grep -E 'VERSION=|CODENAME'

VERSION_CODENAME=noble이 보이면 이 글의 절차를 그대로 따르면 됩니다. 우분투 버전과 지원 기간 전반에 대해서는 우분투 버전 정리를 참고하세요. 아키텍처도 확인해 둘 만합니다. Jazzy의 Tier 1 바이너리는 amd64와 arm64용이며, 32비트 ARM(armhf)용 apt 패키지는 제공되지 않습니다. 라즈베리 파이에 설치한다면 64비트 우분투 이미지를 써야 합니다.

로케일을 UTF-8로 맞추기

공식 문서의 첫 단계는 로케일 확인입니다. 일부 ROS 도구와 파이썬 코드는 시스템 인코딩이 UTF-8이라고 가정하고 문자열을 다루기 때문에, POSIX나 C 로케일인 최소 설치 서버나 Docker 컨테이너에서는 런치 파일이나 로그 출력에서 인코딩 오류가 날 수 있습니다. 데스크톱 우분투를 한국어로 설치했다면 이미 ko_KR.UTF-8일 가능성이 높은데, 이것도 UTF-8이므로 그대로 둬도 됩니다.

locale

출력의 LANG과 LC_ALL이 ...UTF-8로 끝나지 않으면 다음과 같이 설정합니다.

sudo apt update && sudo apt install locales
sudo locale-gen en_US en_US.UTF-8
sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
export LANG=en_US.UTF-8

locale   # 다시 확인

update-locale은 다음 로그인부터 적용되므로, 현재 터미널에는 export LANG=...로 바로 반영해 둡니다.

universe 저장소 활성화

ROS 2 패키지는 우분투 공식 저장소 중 커뮤니티가 관리하는 universe 영역의 패키지에 많이 의존합니다. 데스크톱 설치에서는 보통 이미 켜져 있지만, 클라우드 서버 이미지나 최소 설치에서는 꺼져 있을 수 있습니다. 꺼진 상태로 진행하면 ROS 저장소는 잘 등록되는데 ros-jazzy-desktop 설치 단계에서 의존 패키지를 찾지 못해 has no installation candidate나 unmet dependencies 오류가 납니다.

sudo apt install software-properties-common
sudo add-apt-repository universe

이미 켜져 있으면 “already enabled” 류의 메시지만 나오고 아무 일도 일어나지 않으니, 확신이 없으면 그냥 실행해도 됩니다.

ROS 2 apt 저장소 등록: ros2-apt-source 패키지 방식

여기가 이 글에서 가장 중요한 부분입니다. 예전에는 서명 키 파일을 curl로 내려받고 sources.list.d에 한 줄짜리 .list 파일을 직접 만드는 방식이었는데, 2025년부터 공식 문서는 ros2-apt-source라는 .deb 패키지를 설치하는 방식으로 바뀌었습니다.

현재 공식 방법

sudo apt update && sudo apt install curl -y

export ROS_APT_SOURCE_VERSION=$(curl -s https://api.github.com/repos/ros-infrastructure/ros-apt-source/releases/latest | grep -F "tag_name" | awk -F\" '{print $4}')

curl -L -o /tmp/ros2-apt-source.deb "https://github.com/ros-infrastructure/ros-apt-source/releases/download/${ROS_APT_SOURCE_VERSION}/ros2-apt-source_${ROS_APT_SOURCE_VERSION}.$(. /etc/os-release && echo ${UBUNTU_CODENAME:-${VERSION_CODENAME}})_all.deb"

sudo dpkg -i /tmp/ros2-apt-source.deb

명령이 길지만 하는 일은 세 가지입니다. GitHub API로 ros-apt-source의 최신 릴리스 태그를 알아내고, 내 우분투 코드명(noble)에 맞는 .deb 파일을 내려받은 뒤, dpkg로 설치합니다. 이 패키지가 설치되면 ROS 저장소 주소를 담은 apt 소스 파일과 서명 키링이 시스템에 자리 잡습니다.

이 방식의 장점은 키 관리가 패키지 업데이트로 넘어간다는 점입니다. 서명 키가 만료되거나 교체되면 새 버전의 ros2-apt-source 패키지가 나오고, 일반적인 sudo apt upgrade로 키도 함께 갱신됩니다. 사용자가 키 파일을 다시 받을 필요가 없습니다.

ROS_APT_SOURCE_VERSION이 빈 값이면 GitHub API 호출이 실패한 것입니다. 회사망 프록시나 짧은 시간에 너무 많은 요청을 보내 API 사용량 제한에 걸린 경우에 생깁니다. echo $ROS_APT_SOURCE_VERSION으로 값을 확인하고, 비어 있으면 브라우저에서 ros-infrastructure/ros-apt-source 저장소의 Releases 페이지를 열어 최신 태그를 직접 넣으면 됩니다.

예전 curl 키 방식이 깨지는 이유

2025년 이전에 쓰인 블로그 글과 강의 자료에는 대부분 다음 명령이 나옵니다.

# 예전 방식 - 지금은 쓰지 마세요
sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null

이 방식은 키 파일을 한 번 복사해 두는 구조라, 저장소 서명 키가 만료되면 사용자가 직접 키를 다시 받기 전까지 apt update가 계속 실패합니다. 실제로 2025년 6월 ROS 저장소 서명 키가 만료되면서 이 방식으로 설정한 수많은 PC와 CI, Docker 이미지에서 다음과 같은 오류가 한꺼번에 발생했고, 이를 계기로 공식 문서가 ros2-apt-source 방식으로 바뀌었습니다.

W: GPG error: http://packages.ros.org/ros2/ubuntu noble InRelease: The following signatures were invalid: EXPKEYSIG F42ED6FBAB17C654 Open Robotics <[email protected]>
E: The repository 'http://packages.ros.org/ros2/ubuntu noble InRelease' is not signed.

키 파일 자체를 받지 않았거나 경로가 틀린 경우에는 비슷한 형태로 NO_PUBKEY가 나옵니다.

W: GPG error: http://packages.ros.org/ros2/ubuntu noble InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY F42ED6FBAB17C654

두 경우 모두 해결책은 같습니다. 예전 방식으로 만든 파일을 지우고 위의 ros2-apt-source 방식으로 다시 등록합니다.

sudo rm -f /etc/apt/sources.list.d/ros2.list
sudo rm -f /usr/share/keyrings/ros-archive-keyring.gpg
# 그다음 위의 ros2-apt-source 설치 명령 실행
sudo apt update

예전 파일을 지우지 않고 새 패키지를 설치하면, 같은 저장소 주소가 서로 다른 키링 경로로 두 번 등록되어 apt가 다음과 같이 거부합니다.

E: Conflicting values set for option Signed-By regarding source http://packages.ros.org/ros2/ubuntu/ noble: /usr/share/keyrings/ros-archive-keyring.gpg != ...
E: The list of sources could not be read.

이 오류가 나면 ls /etc/apt/sources.list.d/로 ROS 관련 파일을 확인하고, ros2-apt-source 패키지가 만든 것이 아닌 예전 ros2.list를 지우면 됩니다. Dockerfile이나 Ansible 스크립트에 예전 키 방식이 남아 있다면 이번 기회에 함께 바꿔 두는 것이 좋습니다. 그렇지 않으면 다음 키 교체 때 같은 일이 반복됩니다.

desktop, ros-base, ros-dev-tools 중 무엇을 설치할까

저장소를 등록했으면 패키지 목록을 갱신하고 시스템을 먼저 최신으로 올립니다.

sudo apt update
sudo apt upgrade

apt upgrade를 빼먹으면 안 되는 이유가 있습니다. ROS 패키지는 최신 상태의 우분투를 기준으로 빌드되기 때문에, 갓 설치한 24.04 이미지처럼 오래된 시스템 패키지가 남아 있으면 ROS 패키지를 설치하면서 핵심 시스템 패키지가 제거되는 상황이 생길 수 있다고 공식 문서가 경고합니다. 설치 중 apt가 많은 패키지를 “제거(REMOVED)“하겠다고 나오면 일단 멈추고 apt upgrade부터 했는지 확인하세요.

이제 설치할 메타패키지를 고릅니다.

패키지들어 있는 것적합한 경우
ros-jazzy-desktopros-base + RViz2, rqt 도구, 데모 노드, 튜토리얼개발용 PC, 처음 배우는 경우
ros-jazzy-ros-base통신 라이브러리(rclcpp, rclpy), 메시지, CLI 도구. GUI 없음로봇 본체, 서버, Docker 이미지
ros-dev-toolscolcon, rosdep, vcstool 등 빌드·개발 도구직접 패키지를 빌드하는 모든 환경
sudo apt install ros-jazzy-desktop
sudo apt install ros-dev-tools

처음 배우는 단계라면 desktop을 설치하세요. 아래에서 쓸 talker/listener 데모 노드와 RViz2가 desktop에 들어 있어서, ros-base만 설치하면 튜토리얼을 따라가다 Package 'demo_nodes_cpp' not found 같은 오류를 보게 됩니다. 반대로 라즈베리 파이 같은 로봇 본체에는 ros-base만 두고, 시각화는 같은 네트워크의 개발 PC에서 하는 구성이 흔합니다. 용량 차이는 상당하므로 저장 공간이 빠듯한 보드에서는 의미가 있습니다.

ros-dev-tools는 따로 설치해야 한다는 점을 놓치기 쉽습니다. desktop을 설치해도 colcon과 rosdep은 들어오지 않으므로, 나중에 작업 공간을 빌드하려 할 때 colcon: command not found가 뜹니다. Gazebo 시뮬레이터도 desktop에 포함되지 않으며, 필요하면 ros-jazzy-ros-gz를 별도로 설치합니다.

setup.bash를 source해야 ros2 명령이 생긴다

설치 직후 터미널에서 ros2를 입력하면 대부분 이런 결과를 봅니다.

ros2: command not found

설치가 실패한 것이 아닙니다. ROS 2는 시스템의 /usr/bin이 아니라 /opt/ros/jazzy 아래에 설치되고, 이 경로를 PATH, PYTHONPATH, LD_LIBRARY_PATH, AMENT_PREFIX_PATH 같은 환경 변수에 추가하는 스크립트를 실행해야 명령과 라이브러리가 보입니다. 이렇게 설계된 이유는 여러 배포판을 한 시스템에 공존시키고, 사용자 작업 공간을 그 위에 겹쳐(overlay) 쓰기 위해서입니다.

source /opt/ros/jazzy/setup.bash
ros2 --help

source는 현재 셸에만 적용되므로 새 터미널을 열 때마다 다시 해야 합니다. 매번 입력하기 번거로우면 ~/.bashrc에 추가합니다.

echo "source /opt/ros/jazzy/setup.bash" >> ~/.bashrc

몇 가지 주의할 점이 있습니다. zsh를 쓴다면 setup.bash 대신 setup.zsh를 source해야 하며, bash용 스크립트를 zsh에서 읽으면 경로가 일부만 설정되어 이상한 오류가 납니다. 또 .bashrc에 Humble과 Jazzy를 둘 다 source하는 줄이 남아 있으면 마지막 것이 덮어쓰면서 환경 변수가 섞이므로, 한 셸에는 배포판 하나만 source하는 것이 원칙입니다. 지금 어떤 배포판이 잡혀 있는지는 printenv ROS_DISTRO로 확인할 수 있습니다.

Anaconda나 Miniconda의 base 환경이 자동 활성화되어 있으면 python3가 conda의 파이썬을 가리켜, ROS의 파이썬 노드 실행 시 ModuleNotFoundError: No module named 'rclpy' 같은 오류가 날 수 있습니다. ROS 작업을 하는 터미널에서는 conda deactivate로 빠져나오거나 conda config --set auto_activate_base false로 자동 활성화를 끄는 것이 안전합니다.

talker와 listener로 설치 확인하기

터미널 두 개를 열고 각각 setup.bash를 source한 상태에서 실행합니다.

# 터미널 1: C++ 퍼블리셔
ros2 run demo_nodes_cpp talker
# 터미널 2: 파이썬 서브스크라이버
ros2 run demo_nodes_py listener

터미널 1에 Publishing: 'Hello World: 1'이, 터미널 2에 I heard: [Hello World: 1]이 이어서 찍히면 설치가 정상입니다. C++ 노드와 파이썬 노드를 일부러 섞은 이유는 두 언어의 클라이언트 라이브러리(rclcpp, rclpy)와 그 아래 DDS 통신 계층이 모두 동작하는지를 한 번에 확인하기 위해서입니다.

보조 확인 명령도 알아 두면 문제를 좁힐 때 편합니다.

ros2 node list          # /talker, /listener가 보여야 함
ros2 topic list         # /chatter가 보여야 함
ros2 topic echo /chatter
ros2 doctor --report    # 배포판, RMW, 네트워크 정보 요약

talker는 찍히는데 listener에 아무것도 오지 않는다면 아래 “노드끼리 서로 못 찾을 때” 절로 가면 됩니다.

rosdep 초기화와 colcon 작업 공간

튜토리얼을 넘어 직접 패키지를 만들거나 GitHub의 ROS 패키지를 빌드하려면 작업 공간(workspace)과 rosdep이 필요합니다. rosdep은 패키지의 package.xml에 적힌 의존성 이름을 보고 우분투 apt 패키지나 pip 패키지로 바꿔 설치해 주는 도구입니다. 의존성을 하나하나 찾아 apt로 설치하지 않아도 되게 해 줍니다.

sudo rosdep init
rosdep update

rosdep init은 시스템 전체에 기본 소스 목록 파일(/etc/ros/rosdep/sources.list.d/20-default.list)을 만드는 작업이라 sudo가 필요하고, 한 시스템에서 한 번만 하면 됩니다. 반면 rosdep update는 사용자 홈의 캐시(~/.ros/rosdep)를 갱신하므로 sudo 없이 실행해야 합니다. sudo rosdep update를 하면 캐시가 root 소유로 만들어져, 이후 일반 사용자로 실행할 때 권한 오류가 납니다. 이미 그렇게 했다면 sudo rosdep fix-permissions 후 rosdep update를 다시 실행합니다.

두 번째로 sudo rosdep init을 실행하면 다음 오류가 나는데, 이미 초기화되어 있다는 뜻일 뿐이라 무시하고 rosdep update만 하면 됩니다.

ERROR: default sources list file already exists:
	/etc/ros/rosdep/sources.list.d/20-default.list
Please delete if you wish to re-initialize

이제 작업 공간을 만들고 빌드해 봅니다. 공식 예제 저장소의 패키지를 하나 받아 빌드하는 예입니다.

mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
git clone https://github.com/ros/ros_tutorials.git -b jazzy

cd ~/ros2_ws
rosdep install -i --from-path src --rosdistro jazzy -y
colcon build --symlink-install

rosdep install은 반드시 작업 공간 최상위에서 --from-path src로 실행합니다. -i(--ignore-src)는 작업 공간 안에 소스로 이미 있는 패키지를 apt로 중복 설치하지 않게 하는 옵션입니다. --symlink-install은 파이썬 파일이나 런치 파일을 복사하지 않고 심볼릭 링크로 연결해, 수정할 때마다 다시 빌드하지 않아도 되게 해 줍니다.

빌드한 패키지를 쓰려면 작업 공간의 setup 파일도 source해야 합니다. 이때 빌드를 실행한 그 터미널이 아니라 새 터미널에서 source하는 것이 공식 권장입니다. 같은 터미널에서 overlay를 source한 채로 다시 빌드하면 환경이 꼬여 원인을 찾기 어려운 빌드 문제가 생길 수 있기 때문입니다.

# 새 터미널에서
source /opt/ros/jazzy/setup.bash   # underlay
source ~/ros2_ws/install/setup.bash  # overlay
ros2 run turtlesim turtlesim_node

colcon build를 src 폴더 안에서 실행하는 실수도 흔합니다. 그러면 src 안에 build, install, log 폴더가 생기고 다음 빌드 때 colcon이 그것까지 패키지로 탐색하려 합니다. 항상 작업 공간 최상위(~/ros2_ws)에서 실행하고, 잘못 생긴 폴더는 지우면 됩니다.

설치 중 자주 만나는 오류와 해결

E: Unable to locate package ros-jazzy-desktop

원인은 대체로 네 가지 중 하나이며, 위에서부터 순서대로 확인하면 됩니다.

  1. 우분투 버전이 24.04가 아닙니다. lsb_release -cs가 noble인지 확인합니다. jammy라면 Jazzy가 아니라 Humble을 설치하거나 우분투를 올려야 합니다.
  2. 저장소 등록 후 sudo apt update를 하지 않았습니다.
  3. apt update 출력에 packages.ros.org 관련 GPG 오류가 있어 ROS 저장소 목록이 무시되었습니다. 이 경우 위의 서명 키 절로 돌아갑니다.
  4. 지원하지 않는 아키텍처입니다. dpkg --print-architecture가 armhf나 i386이면 apt 바이너리가 없습니다.

저장소가 실제로 잡혔는지는 다음 명령으로 확인할 수 있습니다.

apt-cache policy ros-jazzy-desktop

Candidate: 줄에 버전이 나오고 아래에 http://packages.ros.org/ros2/ubuntu noble/main이 보이면 저장소는 정상입니다.

GPG NO_PUBKEY / EXPKEYSIG

앞에서 설명한 대로 예전 키 파일 방식의 흔적입니다. 예전 .list와 키링 파일을 지우고 ros2-apt-source로 다시 등록하세요. 이미 ros2-apt-source를 쓰고 있는데 키 만료 오류가 난다면, 패키지 자체가 오래된 것이므로 위의 설치 명령을 다시 실행해 최신 버전으로 교체하면 됩니다. apt upgrade가 키 오류 때문에 저장소를 못 읽어 새 버전을 못 받는 상황이 있을 수 있어서, 이럴 때는 GitHub에서 직접 받는 쪽이 확실합니다.

노드끼리 서로 못 찾을 때

같은 PC에서는 잘 되는데 노트북과 로봇 사이, 또는 PC 두 대 사이에서 ros2 topic list에 상대 토픽이 안 보이는 경우입니다. ROS 2는 기본 미들웨어인 DDS가 UDP 멀티캐스트로 같은 네트워크의 참여자를 자동 발견(discovery)하는 구조라, 다음 항목들이 영향을 줍니다. Jazzy의 기본 RMW 구현은 Fast DDS(rmw_fastrtps_cpp)이며, 발견 과정의 세부 동작은 ROS2 통신의 실체: RMW 계층과 Fast DDS에서 자세히 다룹니다.

ROS_DOMAIN_ID가 다르면 서로 보이지 않습니다. 도메인 ID는 같은 네트워크에서 ROS 그룹을 논리적으로 나누는 번호이고, 기본값은 0입니다. 한쪽 .bashrc에만 export ROS_DOMAIN_ID=30 같은 줄이 있으면 둘은 다른 세계에 있는 셈입니다. 양쪽에서 printenv ROS_DOMAIN_ID로 같은지 확인합니다. 리눅스에서는 0~101 범위를 쓰는 것이 안전하다고 공식 문서가 안내합니다.

방화벽이 DDS 트래픽을 막을 수 있습니다. 우분투 데스크톱은 기본적으로 ufw가 꺼져 있지만, 켜 두었다면 멀티캐스트와 DDS가 쓰는 UDP 포트가 막혀 발견이 실패합니다. 신뢰할 수 있는 내부망이라면 상대 기기 IP나 서브넷의 UDP를 허용하는 것이 간단합니다.

sudo ufw status
# 예: 같은 서브넷의 UDP 허용
sudo ufw allow from 192.168.0.0/24 proto udp

멀티캐스트가 실제로 통하는지는 ROS 2에 들어 있는 테스트 명령으로 확인할 수 있습니다. 한쪽에서 수신, 다른 쪽에서 송신을 실행해 메시지가 도착하는지 봅니다.

ros2 multicast receive   # 기기 A
ros2 multicast send      # 기기 B

여기서 메시지가 안 오면 ROS 문제가 아니라 네트워크 문제입니다. 공유기의 AP 격리(클라이언트 격리) 기능, 게스트 Wi-Fi, 회사망 정책, WSL2의 NAT 네트워크, VirtualBox의 NAT 어댑터 등이 흔한 원인입니다. 가상 머신이라면 네트워크 어댑터를 브리지 모드로 바꿔 보세요.

ROS_LOCALHOST_ONLY는 Jazzy에서 더 이상 권장되지 않습니다. Humble 시절 자료에는 같은 PC 안에서만 통신하도록 export ROS_LOCALHOST_ONLY=1을 쓰라는 안내가 많은데, Jazzy에서 이 변수는 deprecated되었고 ROS_AUTOMATIC_DISCOVERY_RANGE와 ROS_STATIC_PEERS로 대체되었습니다. 예전 설정이 .bashrc에 남아 있으면 다른 기기와 통신이 안 되는 원인이 되므로 먼저 지우세요.

# 같은 PC 안에서만 발견 (예전 ROS_LOCALHOST_ONLY=1에 해당)
export ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST

# 같은 서브넷 전체에서 발견 (기본값)
export ROS_AUTOMATIC_DISCOVERY_RANGE=SUBNET

# 자동 발견을 끄고 지정한 주소하고만 통신
export ROS_AUTOMATIC_DISCOVERY_RANGE=OFF
export ROS_STATIC_PEERS="192.168.0.20;192.168.0.21"

ROS_STATIC_PEERS는 멀티캐스트가 막힌 네트워크에서 상대 IP를 직접 지정할 때 유용합니다. 값은 세미콜론으로 구분합니다.

마지막으로, 환경 변수를 바꿨는데도 ros2 topic list 결과가 그대로라면 ROS 2 CLI가 백그라운드에서 띄워 두는 데몬이 예전 발견 결과를 캐시하고 있을 수 있습니다. ros2 daemon stop 후 다시 실행하면 새 설정으로 다시 발견합니다.

다음 단계, 그리고 깨끗하게 지우는 방법

설치와 talker/listener 확인까지 끝났다면, 공식 문서의 Beginner: CLI tools 튜토리얼(turtlesim으로 노드·토픽·서비스·파라미터 개념 익히기)부터 따라가는 것이 가장 효율적입니다. 어떤 자료를 어떤 순서로 보면 좋은지는 ROS2 독학 자료 정리에, 자율주행 로봇 쪽으로 진로를 생각한다면 전체 학습 순서는 자율주행 로봇 독학 로드맵에 정리해 두었습니다.

설치를 잘못해서 처음부터 다시 하고 싶거나 더 이상 쓰지 않는다면 공식 문서의 제거 절차를 따르면 됩니다. 먼저 Jazzy 패키지를 모두 지웁니다.

sudo apt remove ~nros-jazzy-* && sudo apt autoremove

~n은 apt의 패턴 문법으로, 이름이 ros-jazzy-로 시작하는 패키지 전부를 뜻합니다. 저장소 설정까지 지우려면 ros2-apt-source 패키지를 제거하고 목록을 다시 갱신합니다.

sudo apt remove ros2-apt-source
sudo apt update
sudo apt autoremove
sudo apt upgrade   # ROS 저장소에서 받은 시스템 패키지를 우분투 버전으로 되돌림

마지막 apt upgrade는 ROS 저장소가 우분투 저장소보다 새 버전으로 제공하던 일부 패키지가 있을 경우 정리하기 위한 것입니다. 이 밖에 ~/.bashrc에 추가한 source /opt/ros/jazzy/setup.bash 줄, ROS_DOMAIN_ID 같은 환경 변수, rosdep 설정(/etc/ros/rosdep, ~/.ros), 작업 공간 폴더는 apt가 건드리지 않으므로 필요하면 직접 지웁니다. 특히 .bashrc의 source 줄을 남겨 두면 이후 모든 터미널에서 “No such file or directory” 경고가 뜨니 함께 정리하는 것이 좋습니다.