ROS2 Python 패키지에서 Custom Message 빌드 관련 트러블 슈팅

hyoin·2026년 2월 15일

ROS2 부트캠프

목록 보기
7/11
post-thumbnail

1. 들어가며

쇼핑몰 로봇 프로젝트를 진행하면서 로봇과 서버 간 통신을 위한 custom message가 필요했습니다. "Python 패키지니까 msg 파일만 만들면 되겠지?"라고 생각했지만... 현실은 빌드 에러의 연속이었습니다.

2. 문제 상황: 빌드 에러의 연속

첫 번째 에러: Could not find package "rosidl_default_generators"

CMake Error: Could not find package configuration file provided by "rosidl_default_generators"

시도: msg 파일만 만들고 빌드
결과: CMake가 메시지 생성 도구를 찾지 못함

두 번째 에러: rosidl_generate_interfaces 정의되지 않음

# package.xml에 의존성 추가 후 재빌드
CMakeLists.txt doesn't define rosidl_generate_interfaces

시도: package.xml만 수정
결과: CMakeLists.txt 설정 부족

세 번째 에러: No module named 'mall_e_controller.msg'

source install/setup.bash
python3 test_publisher.py

# 에러 메시지
ModuleNotFoundError: No module named 'mall_e_controller.msg'

시도: 빌드는 성공했지만 Python에서 import 실패
원인: <member_of_group> 태그 누락

3. 원인 분석: Python 패키지 ≠ CMakeLists.txt 불필요

핵심 깨달음

  • ROS2에서 msg/srv/action은 언어 중립적
  • Python 패키지여도 메시지 타입 생성은 빌드 시스템 필요
  • rclpy는 생성된 메시지를 사용하는 것일 뿐, 메시지를 만들어 주진 않음

구조 이해

.msg 파일 (정의)
    ↓
rosidl (빌드 도구) ← CMake 기반
    ↓
C++/Python 코드 자동 생성
    ↓
패키지에서 import해서 사용

Python vs C++ 패키지 차이

  • Python 코드: setup.py로 관리
  • 메시지 타입: CMakeLists.txt로 관리

4. 해결 과정: 세 가지 필수 설정 + 올바른 빌드

4-1. msg 파일 작성

# mall_e_controller/msg/RobotMessage.msg

# Header
string message_id
int32 timestamp_sec
int32 timestamp_nsec
string robot_id
string message_type
int32 priority

# Body
string robot_status
float32 battery_pct

4-2. CMakeLists.txt 설정

cmake_minimum_required(VERSION 3.8)
project(mall_e_controller)

# 컴파일러 설정
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wall -Wextra -Wpedantic)
endif()

# 필수 패키지 찾기
find_package(ament_cmake REQUIRED)
find_package(ament_cmake_python REQUIRED) # Python 지원을 위해
find_package(rclpy REQUIRED)

# 메시지 생성 도구
find_package(rosidl_default_generators REQUIRED)

# 메시지 파일 등록 - 이게 빠지면 메시지 생성 안 됨!
rosidl_generate_interfaces(${PROJECT_NAME}
  "msg/RobotMessage.msg" # 패키지를 루트로 삼아야 함.
)

# Python 패키지 설정
ament_python_install_package(${PROJECT_NAME})

ament_package()

내가 했던 실수:

  • rosidl_generate_interfaces() 빠뜨림: msg 파일을 C++/Python 코드로 변환하는 작업이 불가능
  • 메시지 경로 실수: 패키지를 루트로 삼아야 한다.
  • find_package(ament_cmake_python REQUIRED) 누락: python 지원이 안 된다.

4-3. package.xml 설정

<?xml version="1.0"?>
<package format="3">
  <name>mall_e_controller</name>
  <version>0.0.1</version>
  <description>Mall robot controller</description>
  <maintainer email="you@example.com">Your Name</maintainer>
  <license>Apache License 2.0</license>
  
  <!-- 빌드 도구 -->
  <buildtool_depend>ament_cmake</buildtool_depend>
  <buildtool_depend>ament_cmake_python</buildtool_depend>
  
  <!-- 메시지 생성 의존성 - 이거 없으면 빌드 실패! -->
  <build_depend>rosidl_default_generators</build_depend>
  <exec_depend>rosidl_default_runtime</exec_depend>
  
  <!-- 이게 없으면 다른 패키지에서 메시지 못 찾음! -->
  <member_of_group>rosidl_interface_packages</member_of_group>
  
  <!-- Python 의존성 -->
  <depend>rclpy</depend>
  
  <export>
    <build_type>ament_cmake</build_type>
  </export>
</package>

내가 했던 실수:

  • <member_of_group>rosidl_interface_packages</member_of_group> 빠뜨림: 다른 패키지에서 msg를 못 찾음.
  • build_depend (컴파일할 때만 필요) 와 exec_depend(실행할 때만 필요) 구분 안 함
  • ament_cmake_python 누락: python 패키지인데 커스텀 메시지를 만들 때 필요

5. 트러블슈팅 정리

문제 1: "No module named '{package_name}.msg'"

원인: 환경 변수 미로드 또는 빌드 실패

해결:
환경변수를 다시 빌드해 봅시다.

# 환경 변수 다시 로드
source install/setup.bash

# 전체 재빌드
rm -rf build/ install/ log/
colcon build --packages-select mall_e_controller
source install/setup.bash

문제 2: "package '{package_name}' not found"

원인: package.xml에 <member_of_group> 누락

해결:

<!-- package.xml에 추가 -->
<member_of_group>rosidl_interface_packages</member_of_group>

문제 3: "CMake Error: Could not find rosidl_default_generators"

원인: package.xml 의존성 누락

해결:

<!-- package.xml에 추가 -->
<build_depend>rosidl_default_generators</build_depend>
<exec_depend>rosidl_default_runtime</exec_depend>

문제 4: "CMakeLists.txt doesn't define rosidl_generate_interfaces"

원인: CMakeLists.txt에 메시지 생성 명령 누락

해결:

# CMakeLists.txt에 추가
find_package(rosidl_default_generators REQUIRED)

rosidl_generate_interfaces(${PROJECT_NAME}
  "msg/RobotMessage.msg"
)

문제 5: 설정 고쳤는데도 계속 같은 에러

원인: 빌드 캐시 문제

해결:

cd ~/robotics_ws
rm -rf build/ install/ log/
colcon build --packages-select mall_e_controller
source install/setup.bash

사실 이 빌드 캐시 문제가 많이 발생했습니다 하하... 프로젝트 기본설정할 때 클린빌드는 꼭 해야 하는 것 같습니다.

6. 배운 점

1. Python 패키지 ≠ CMakeLists.txt 불필요

메시지 타입은 언어 중립적이라 빌드 시스템 필수. Python 코드만 있어도 메시지 생성엔 CMake 필요합니다.

2. 세 가지는 세트로 관리

msg 파일 + CMakeLists.txt + package.xml 모두 제대로 설정해야 합니다. 하나라도 빠지면 빌드 실패 또는 import 실패합니다.

3. 빌드 위치와 순서 중요

워크스페이스 루트에서 빌드해야 합니다. src 내부에서 빌드하면 충돌이 발생합니다. 설정 변경 후엔 반드시 재빌드 + source 해야 합니다.

4. 빌드 캐시 주의

설정 변경 후 안 되면 캐시 삭제가 해결사입니다. rm -rf build/ install/ log/

5. package.xml의 member_of_group이 핵심

이게 없으면 다른 패키지에서 메시지를 못 찾습니다. 빌드는 성공해도 import 실패하는 주범입니다.

10. 마무리

ROS2에서 Python으로 개발한다고 해서 빌드 시스템을 무시할 수는 없습니다. 특히 custom message를 만들 때는:

  • msg 파일 작성 (인터페이스 정의)
  • CMakeLists.txt 설정 (메시지 생성)
  • package.xml 설정 (의존성 + 그룹 등록)
  • 올바른 위치에서 빌드 (워크스페이스 루트)
  • 환경 변수 로드 (source install/setup.bash)

이 5가지를 모두 챙겨야 성공합니다.

처음엔 "Python인데 왜 CMake가 필요해?"라고 생각했지만, ROS2의 메시지 시스템이 언어 중립적으로 설계되어 있다는 걸 이해하고 나니 구조가 명확해졌습니다.

같은 문제로 고생하고 계신 분들께 도움이 되길 바랍니다!


참고 자료:

profile
배워야 할 게 많은 개발자... 하지만 공부를 포기하지 않지!!

0개의 댓글