쇼핑몰 로봇 프로젝트를 진행하면서 로봇과 서버 간 통신을 위한 custom message가 필요했습니다. "Python 패키지니까 msg 파일만 만들면 되겠지?"라고 생각했지만... 현실은 빌드 에러의 연속이었습니다.
CMake Error: Could not find package configuration file provided by "rosidl_default_generators"
시도: msg 파일만 만들고 빌드
결과: CMake가 메시지 생성 도구를 찾지 못함
# package.xml에 의존성 추가 후 재빌드
CMakeLists.txt doesn't define rosidl_generate_interfaces
시도: package.xml만 수정
결과: CMakeLists.txt 설정 부족
source install/setup.bash
python3 test_publisher.py
# 에러 메시지
ModuleNotFoundError: No module named 'mall_e_controller.msg'
시도: 빌드는 성공했지만 Python에서 import 실패
원인: <member_of_group> 태그 누락
.msg 파일 (정의)
↓
rosidl (빌드 도구) ← CMake 기반
↓
C++/Python 코드 자동 생성
↓
패키지에서 import해서 사용
# 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
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 지원이 안 된다.<?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를 못 찾음.원인: 환경 변수 미로드 또는 빌드 실패
해결:
환경변수를 다시 빌드해 봅시다.
# 환경 변수 다시 로드
source install/setup.bash
# 전체 재빌드
rm -rf build/ install/ log/
colcon build --packages-select mall_e_controller
source install/setup.bash
원인: package.xml에 <member_of_group> 누락
해결:
<!-- package.xml에 추가 -->
<member_of_group>rosidl_interface_packages</member_of_group>
원인: package.xml 의존성 누락
해결:
<!-- package.xml에 추가 -->
<build_depend>rosidl_default_generators</build_depend>
<exec_depend>rosidl_default_runtime</exec_depend>
원인: CMakeLists.txt에 메시지 생성 명령 누락
해결:
# CMakeLists.txt에 추가
find_package(rosidl_default_generators REQUIRED)
rosidl_generate_interfaces(${PROJECT_NAME}
"msg/RobotMessage.msg"
)
원인: 빌드 캐시 문제
해결:
cd ~/robotics_ws
rm -rf build/ install/ log/
colcon build --packages-select mall_e_controller
source install/setup.bash
사실 이 빌드 캐시 문제가 많이 발생했습니다 하하... 프로젝트 기본설정할 때 클린빌드는 꼭 해야 하는 것 같습니다.
메시지 타입은 언어 중립적이라 빌드 시스템 필수. Python 코드만 있어도 메시지 생성엔 CMake 필요합니다.
msg 파일 + CMakeLists.txt + package.xml 모두 제대로 설정해야 합니다. 하나라도 빠지면 빌드 실패 또는 import 실패합니다.
워크스페이스 루트에서 빌드해야 합니다. src 내부에서 빌드하면 충돌이 발생합니다. 설정 변경 후엔 반드시 재빌드 + source 해야 합니다.
설정 변경 후 안 되면 캐시 삭제가 해결사입니다. rm -rf build/ install/ log/
이게 없으면 다른 패키지에서 메시지를 못 찾습니다. 빌드는 성공해도 import 실패하는 주범입니다.
ROS2에서 Python으로 개발한다고 해서 빌드 시스템을 무시할 수는 없습니다. 특히 custom message를 만들 때는:
이 5가지를 모두 챙겨야 성공합니다.
처음엔 "Python인데 왜 CMake가 필요해?"라고 생각했지만, ROS2의 메시지 시스템이 언어 중립적으로 설계되어 있다는 걸 이해하고 나니 구조가 명확해졌습니다.
같은 문제로 고생하고 계신 분들께 도움이 되길 바랍니다!
참고 자료: