Package Configuration Files
package.xml Examples
ROS1 package.xml (Format 2) |
ROS2 package.xml (Format 3) |
<?xml version="1.0"?>
<package format="2">
<name>my_ros1_package</name>
<version>0.1.0</version>
<description>
A package for ROS1
</description>
<maintainer email="user@example.com">Your Name</maintainer>
<license>BSD</license>
<url type="website">http://wiki.ros.org/my_ros1_package</url>
<author email="user@example.com">Your Name</author>
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<build_depend>rospy</build_depend>
<build_depend>std_msgs</build_depend>
<exec_depend>roscpp</exec_depend>
<exec_depend>rospy</exec_depend>
<exec_depend>std_msgs</exec_depend>
<export>
<!-- Other tools can request additional information be placed here -->
</export>
</package>
|
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>my_ros2_package</name>
<version>0.1.0</version>
<description>
A package for ROS2
</description>
<maintainer email="user@example.com">Your Name</maintainer>
<license>Apache License 2.0</license>
<url type="website">https://github.com/user/my_ros2_package</url>
<author email="user@example.com">Your Name</author>
<buildtool_depend>ament_cmake</buildtool_depend>
<depend>rclcpp</depend>
<depend>std_msgs</depend>
<exec_depend>ros2launch</exec_depend>
<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>
<export>
<build_type>ament_cmake</build_type>
</export>
</package>
|
ROS1 package.xml for Python package |
ROS2 package.xml for Python package |
<?xml version="1.0"?>
<package format="2">
<name>my_ros1_py_pkg</name>
<version>0.1.0</version>
<description>
A Python package for ROS1
</description>
<maintainer email="user@example.com">Your Name</maintainer>
<license>BSD</license>
<buildtool_depend>catkin</buildtool_depend>
<build_depend>rospy</build_depend>
<build_depend>std_msgs</build_depend>
<exec_depend>rospy</exec_depend>
<exec_depend>std_msgs</exec_depend>
<export>
<!-- Other tools can request additional information be placed here -->
</export>
</package>
|
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>my_ros2_py_pkg</name>
<version>0.1.0</version>
<description>
A Python package for ROS2
</description>
<maintainer email="user@example.com">Your Name</maintainer>
<license>Apache License 2.0</license>
<exec_depend>rclpy</exec_depend>
<exec_depend>std_msgs</exec_depend>
<test_depend>ament_copyright</test_depend>
<test_depend>ament_flake8</test_depend>
<test_depend>ament_pep257</test_depend>
<test_depend>python3-pytest</test_depend>
<export>
<build_type>ament_python</build_type>
</export>
</package>
|
ROS1 package.xml with conditional dependencies |
ROS2 package.xml with conditional dependencies |
<!-- Not supported in ROS1 -->
|
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>cross_compatible_pkg</name>
<version>0.1.0</version>
<description>
A package compatible with both ROS1 and ROS2
</description>
<maintainer email="user@example.com">Your Name</maintainer>
<license>Apache License 2.0</license>
<buildtool_depend condition="$ROS_VERSION == 1">catkin</buildtool_depend>
<buildtool_depend condition="$ROS_VERSION == 2">ament_cmake</buildtool_depend>
<depend condition="$ROS_VERSION == 1">roscpp</depend>
<depend condition="$ROS_VERSION == 2">rclcpp</depend>
<depend>std_msgs</depend> <!-- Common dependency for both ROS versions -->
<export>
<build_type condition="$ROS_VERSION == 1">catkin</build_type>
<build_type condition="$ROS_VERSION == 2">ament_cmake</build_type>
</export>
</package>
|
setup.py Examples
ROS1 setup.py |
ROS2 setup.py |
## ! DO NOT MANUALLY INVOKE THIS setup.py, USE CATKIN INSTEAD
from distutils.core import setup
from catkin_pkg.python_setup import generate_distutils_setup
# fetch values from package.xml
setup_args = generate_distutils_setup(
packages=['my_ros1_py_pkg'],
package_dir={'': 'src'},
)
setup(**setup_args)
|
from setuptools import setup
import os
from glob import glob
package_name = 'my_ros2_py_pkg'
setup(
name=package_name,
version='0.1.0',
packages=[package_name],
data_files=[
# Include our package.xml file
('share/ament_index/resource_index/packages',
['resource/' + package_name]),
('share/' + package_name, ['package.xml']),
# Include all launch files.
(os.path.join('share', package_name, 'launch'),
glob(os.path.join('launch', '*.launch.py'))),
],
install_requires=['setuptools'],
zip_safe=True,
maintainer='Your Name',
maintainer_email='user@example.com',
description='A Python package for ROS2',
license='Apache License 2.0',
tests_require=['pytest'],
entry_points={
'console_scripts': [
'talker = my_ros2_py_pkg.publisher_node:main',
'listener = my_ros2_py_pkg.subscriber_node:main',
],
},
)
|
setup.cfg Example (ROS2 only)
[develop]
script-dir=$base/lib/my_ros2_py_pkg
[install]
install-scripts=$base/lib/my_ros2_py_pkg
Key Differences in Configuration Files
Feature |
ROS1 |
ROS2 |
package.xml Format |
Format 1 or 2 |
Format 3 (adds conditional dependencies) |
Python Package Processing |
Limited by catkin, uses catkin_pkg.python_setup.generate_distutils_setup |
Full setuptools functionality, direct setup() call |
Executable Registration |
Scripts are placed in a scripts/ directory and made executable |
Uses Python entry_points in setup.py |
Data Files |
Usually handled in CMakeLists.txt |
Specified in setup.py data_files list |
setup.cfg |
Not typically used |
Required for Python packages to specify script installation directory |
Build Tool Declaration |
Always catkin |
ament_cmake for C++, ament_python for Python |
Cross-ROS Compatibility |
Not supported |
Supported with conditional expressions in package.xml format 3 |
CMakeLists.txt Comparison
Feature |
ROS1 (Catkin) |
ROS2 (Ament) |
Minimum Structure |
cmake_minimum_required(VERSION 2.8.3)
project(my_package)
find_package(catkin REQUIRED COMPONENTS
roscpp
std_msgs
)
catkin_package()
include_directories(
include
${catkin_INCLUDE_DIRS}
)
add_executable(my_node src/my_node.cpp)
target_link_libraries(my_node
${catkin_LIBRARIES}
)
install(TARGETS my_node
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
|
cmake_minimum_required(VERSION 3.8)
project(my_package)
# Default to C++14
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)
add_executable(my_node src/my_node.cpp)
target_include_directories(my_node PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
ament_target_dependencies(my_node
rclcpp
std_msgs
)
install(TARGETS my_node
DESTINATION lib/${PROJECT_NAME}
)
ament_package()
|
Package Dependencies |
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
geometry_msgs
)
|
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)
find_package(geometry_msgs REQUIRED)
|
Include Directories |
include_directories(
include
${catkin_INCLUDE_DIRS}
)
|
# Per-target approach (preferred)
target_include_directories(my_target PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
|
Link Libraries |
target_link_libraries(my_node
${catkin_LIBRARIES}
)
|
# Target-specific dependencies using modern CMake
target_link_libraries(my_node
PUBLIC
${std_msgs_TARGETS}
another_lib::another_lib
)
|
Package Export |
catkin_package(
INCLUDE_DIRS include
LIBRARIES my_library
CATKIN_DEPENDS roscpp std_msgs
DEPENDS system_lib
)
|
# Not explicitly required with target-based approach
# Dependencies are handled through ament_target_dependencies
# and target_link_libraries
# To export dependencies:
ament_export_targets(export_my_package HAS_LIBRARY_TARGET)
ament_export_dependencies(rclcpp std_msgs)
|
Message Generation |
find_package(catkin REQUIRED COMPONENTS
std_msgs
message_generation
)
add_message_files(
FILES
MyMessage.msg
)
add_service_files(
FILES
MyService.srv
)
generate_messages(
DEPENDENCIES
std_msgs
)
catkin_package(
CATKIN_DEPENDS message_runtime std_msgs
)
|
find_package(rosidl_default_generators REQUIRED)
find_package(std_msgs REQUIRED)
rosidl_generate_interfaces(${PROJECT_NAME}
"msg/MyMessage.msg"
"srv/MyService.srv"
DEPENDENCIES std_msgs
)
# To use interfaces in the same package:
rosidl_target_interfaces(my_node ${PROJECT_NAME} "rosidl_typesupport_cpp")
# In package.xml:
# <member_of_group>rosidl_interface_packages</member_of_group>
# <build_depend>rosidl_default_generators</build_depend>
# <exec_depend>rosidl_default_runtime</exec_depend>
|
Installation |
install(TARGETS my_node my_library
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
install(DIRECTORY include/${PROJECT_NAME}/
DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
FILES_MATCHING PATTERN "*.h"
)
install(DIRECTORY launch/
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/launch
)
|
install(TARGETS my_node my_library
EXPORT export_my_package
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION lib/${PROJECT_NAME}
)
install(
DIRECTORY include/
DESTINATION include
)
install(
DIRECTORY launch
DESTINATION share/${PROJECT_NAME}
)
|
Testing |
if(CATKIN_ENABLE_TESTING)
catkin_add_gtest(my_test test/test.cpp)
target_link_libraries(my_test ${catkin_LIBRARIES})
endif()
|
if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
find_package(ament_cmake_gtest REQUIRED)
ament_lint_auto_find_test_dependencies()
ament_add_gtest(my_test test/test.cpp)
target_link_libraries(my_test
my_library
)
endif()
|
Finalization |
# Not required, handled by catkin_package()
|
# Always required as the last CMake command
ament_package()
|
Python Modules Support |
catkin_python_setup()
# Refers to setup.py in the package
|
# For pure Python packages: use ament_python build type
# For mixed C++/Python packages:
find_package(ament_cmake_python REQUIRED)
ament_python_install_package(${PROJECT_NAME})
# Install Python executables
install(PROGRAMS
scripts/my_python_script.py
DESTINATION lib/${PROJECT_NAME}
)
|
Key Differences in CMakeLists.txt
Aspect |
ROS1 (Catkin) |
ROS2 (Ament) |
CMake Version |
Typically 2.8.3+ |
Typically 3.5+ (3.8+ for newer distributions) |
Build System |
catkin |
ament_cmake, ament_python |
Dependency Handling |
Centralized through catkin |
Per-package find_package calls |
Include Paths |
Global via include_directories |
Per-target via target_include_directories |
Library Linking |
Often uses ${catkin_LIBRARIES} |
Modern CMake target-based approach |
Package Export |
Through catkin_package() |
Through ament_export_* functions |
Message Generation |
Multi-step with add_*_files and generate_messages |
Single call to rosidl_generate_interfaces |
Installation Paths |
Uses CATKIN_* variables |
More direct paths, lib/${PROJECT_NAME} |
Final Function |
None required (catkin_package is typically not at the end) |
ament_package() required at the end |
留言
張貼留言