대상: 다른 사람이 만든 ROS 패키지를 빠르게 분석하고, 어떤 기능을 하는지 구조를 파악하고 싶은 개발자
환경: Ubuntu 20.04 / ROS Noetic / catkin
1. 문제/주제 요약
ROS 패키지를 오픈소스 저장소(GitHub 등)에서 받았을 때,
파일이 너무 많아서 “도대체 이게 무슨 기능을 하는 패키지인지”
한눈에 파악하기 어려운 경우가 많습니다.
그런데 사실 CMakeLists.txt와 package.xml 두 파일만 보면,
그 패키지가 어떤 역할을 하는지, ROS에서 어떻게 쓰이는지 거의 다 알 수 있습니다.
이 글에서는 그 두 파일을 기준으로
패키지의 기능·의존성·빌드 구조를 읽는 방법을 설명합니다.
2. 패키지 구성 복습
ROS 패키지의 기본 구조는 다음과 같습니다:
my_robot_pkg/
├── CMakeLists.txt
├── package.xml
├── src/
├── include/
├── launch/
├── scripts/
└── msg/ srv/ (있을 수도 있음)
이 중 CMakeLists.txt와 package.xml은
패키지의 “정체성”을 결정짓는 두 핵심 파일입니다.
3. package.xml로 기능 추측하기
package.xml은 메타데이터 + 의존성 정보를 담고 있습니다.
먼저 아래 예제를 봅시다:
<package format="2">
<name>lidar_driver</name>
<version>1.2.0</version>
<description>LIDAR sensor driver package</description>
<maintainer email="dev@robot.com">Robot Dev</maintainer>
<license>BSD</license>
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<build_depend>sensor_msgs</build_depend>
<build_depend>std_srvs</build_depend>
<exec_depend>roscpp</exec_depend>
<exec_depend>sensor_msgs</exec_depend>
<exec_depend>std_srvs</exec_depend>
</package>
🔍 읽는 요령
| 정보 | 의미 |
|---|---|
<name> | 패키지 이름 (rosrun, roslaunch에서 쓰임) |
<description> | 기능 요약 — 이름보다 더 중요 |
<build_depend> | 빌드 시 필요한 라이브러리 (코드에서 #include) |
<exec_depend> | 실행 시 필요한 ROS 노드나 메시지 패키지 |
<license> | 코드 재사용 가능 여부 (MIT, BSD, Apache 등) |
👉 이 예제만 봐도, lidar_driver는roscpp, sensor_msgs, std_srvs에 의존하므로
센서 데이터를 ROS 메시지로 퍼블리시하거나 서비스로 제어하는 드라이버형 패키지임을 추측할 수 있습니다.
4. CMakeLists.txt로 기능 구체화하기
CMakeLists.txt는 실제 빌드 대상(노드, 라이브러리, 메시지 등) 을 정의합니다.
예제:
cmake_minimum_required(VERSION 3.0.2)
project(lidar_driver)
find_package(catkin REQUIRED COMPONENTS
roscpp
sensor_msgs
std_srvs
)
catkin_package(
CATKIN_DEPENDS roscpp sensor_msgs std_srvs
)
include_directories(
include
${catkin_INCLUDE_DIRS}
)
add_executable(lidar_node src/lidar_node.cpp)
target_link_libraries(lidar_node ${catkin_LIBRARIES})
install(TARGETS lidar_node
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
🔍 읽는 요령
| 코드 라인 | 의미 | 기능 추론 |
|---|---|---|
find_package(... roscpp ...) | C++ 노드임 | Python 노드 아님 |
sensor_msgs | 센서 데이터 퍼블리시 | /scan 등 토픽 발행 예상 |
std_srvs | 서비스 호출/제공 | “센서 on/off” 같은 제어 인터페이스 |
add_executable(lidar_node src/lidar_node.cpp) | 실행 노드 이름 | rosrun lidar_driver lidar_node 로 실행 가능 |
catkin_package(...) | 다른 패키지가 의존할 수 있게 내보냄 | 재사용 가능 드라이버 형태 |
👉 여기서 src/lidar_node.cpp라는 단일 노드를 빌드한다는 점,roscpp + sensor_msgs + std_srvs를 쓴다는 점으로
C++ 기반 LIDAR 데이터 퍼블리셔 + 서비스 제어 노드라는 게 바로 보입니다.
5. 응용: 메시지/서비스 패키지 식별
메시지 정의 패키지(msg/, srv/)는
CMakeLists에 아래 코드가 들어갑니다.
add_message_files(
FILES
MotorStatus.msg
)
add_service_files(
FILES
SetSpeed.srv
)
generate_messages(
DEPENDENCIES std_msgs
)
catkin_package(
CATKIN_DEPENDS message_runtime std_msgs
)
이런 구조라면 해당 패키지는 데이터 타입 정의 전용 패키지입니다.
즉, 실행 가능한 노드는 없고,
다른 패키지가 motor_msgs/MotorStatus 형태로 import할 수 있게 됩니다.
6. 예제별 구조 읽는 감각
| CMakeLists/패키지 패턴 | 의미 |
|---|---|
add_executable() 여러 개 있음 | 노드 여러 개 제공 (예: talker, listener) |
rospy 포함 + scripts 폴더 있음 | Python 기반 노드 |
message_generation, add_message_files() 있음 | 메시지 타입 정의 패키지 |
actionlib_msgs 의존 | Action 서버/클라이언트 기능 |
dynamic_reconfigure 포함 | 런타임 파라미터 조정 가능 |
gazebo_ros 포함 | 시뮬레이션용 플러그인 또는 노드 |
tf2_ros 포함 | 좌표 변환 브로드캐스터/리스너 패키지 |
7. 실무 예시 — rosserial_arduino
GitHub에서 rosserial_arduino 패키지를 받았다고 가정하면,package.xml과 CMakeLists.txt만으로도 아래처럼 읽을 수 있습니다:
rospy,roscpp,std_msgs,serial포함 → PC ↔ 마이크로컨트롤러 통신add_executable(rosserial_node src/rosserial_node.cpp)→ PC 쪽 중계 노드 존재- 메시지 파일 없음 → 자체 데이터 타입 정의 안 함
catkin_package()→ 다른 패키지에서 의존 가능
👉 결론: “시리얼 통신 기반 ROS 데이터 중계 패키지”
8. 추가 팁 / 자주 하는 실수
- ⚠️
CMakeLists.txt에add_executable이 없으면 실행 노드가 없는 경우가 많습니다.
(msg/srv정의 패키지일 확률 높음) - ⚠️
package.xml에message_generation이 있는데CMakeLists.txt에generate_messages()가 없으면 빌드 에러 발생 - ✅ GitHub에서 패키지를 클론할 때, 이 두 파일만 먼저 확인하면
의존 패키지를 미리 설치할 수 있습니다.rosdep install --from-paths src --ignore-src -r -y
9. 정리
package.xml→ 이 패키지가 무엇을 쓰는지(의존성, 언어, 목적)CMakeLists.txt→ 이 패키지가 무엇을 하는지(빌드 대상, 노드, 메시지)- 이 두 파일만 보면 패키지의 기능과 구조를 거의 완벽하게 파악할 수 있다.
- 익숙해지면
src/코드를 열지 않아도,
“이건 센서 드라이버네”, “이건 메시지 정의 패키지네” 감이 바로 온다.