ROS1 vs ROS2 Comprehensive Comparison (3)

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

留言

這個網誌中的熱門文章

Useful PX4 Parameters

Tuing PID parameters in QGroundcontrol (2)

Matlab Pixhawk Support Package installation (Windows)