ROS1 vs ROS2 Comprehensive Comparison (4)

Creating Custom Interfaces (Messages and Services) Comparison

Feature ROS1 ROS2
Package Type Any catkin package can contain messages Must be an ament_cmake package (even for Python nodes)
Directory Structure
my_package/
  ├── msg/
  │   └── MyMessage.msg
  ├── srv/
  │   └── MyService.srv
  ├── CMakeLists.txt
  └── package.xml
      
my_package/
  ├── msg/
  │   └── MyMessage.msg
  ├── srv/
  │   └── MyService.srv
  ├── CMakeLists.txt
  └── package.xml
      
Best Practice Often mixed with node code in the same package Create a dedicated *_interfaces package (separate from node code)
Naming Convention Often named *_msgs for message packages Preferably named *_interfaces for interface packages
File Format (.msg)
# MyMessage.msg
Header header  # Optional standard header
int32 my_int   # Fields with their types
string my_string
      
# MyMessage.msg
std_msgs/Header header  # Full namespace required
int32 my_int
string my_string
      
File Format (.srv)
# MyService.srv
int32 a
int32 b
---
int32 sum
      
# MyService.srv
int32 a
int32 b
---
int32 sum
      
Variable Naming Allows camelCase or snake_case Only snake_case allowed (camelCase is prohibited)
Default Values Not supported for primitive fields Supported for primitive fields
package.xml Configuration
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
      
<buildtool_depend>rosidl_default_generators</buildtool_depend>
<exec_depend>rosidl_default_runtime</exec_depend>
<member_of_group>rosidl_interface_packages</member_of_group>
      
CMakeLists.txt Configuration (Messages)
find_package(catkin REQUIRED COMPONENTS
  std_msgs
  message_generation
)

add_message_files(
  FILES
  MyMessage.msg
)

generate_messages(
  DEPENDENCIES
  std_msgs
)

catkin_package(
  CATKIN_DEPENDS message_runtime std_msgs
)
      
find_package(ament_cmake REQUIRED)
find_package(rosidl_default_generators REQUIRED)
find_package(std_msgs REQUIRED)

rosidl_generate_interfaces(${PROJECT_NAME}
  "msg/MyMessage.msg"
  DEPENDENCIES
  std_msgs
)

ament_package()
      
CMakeLists.txt Configuration (Services)
find_package(catkin REQUIRED COMPONENTS
  std_msgs
  message_generation
)

add_service_files(
  FILES
  MyService.srv
)

generate_messages(
  DEPENDENCIES
  std_msgs
)

catkin_package(
  CATKIN_DEPENDS message_runtime std_msgs
)
      
find_package(ament_cmake REQUIRED)
find_package(rosidl_default_generators REQUIRED)
find_package(std_msgs REQUIRED)

rosidl_generate_interfaces(${PROJECT_NAME}
  "srv/MyService.srv"
  DEPENDENCIES
  std_msgs
)

ament_package()
      
Using Custom Messages (C++)
#include <my_package/MyMessage.h>

my_package::MyMessage msg;
msg.my_int = 42;
msg.my_string = "hello";
      
#include <my_package/msg/my_message.hpp>

auto msg = my_package::msg::MyMessage();
msg.my_int = 42;
msg.my_string = "hello";
      
Using Custom Messages (Python)
from my_package.msg import MyMessage

msg = MyMessage()
msg.my_int = 42
msg.my_string = "hello"
      
from my_package.msg import MyMessage

msg = MyMessage()
msg.my_int = 42
msg.my_string = "hello"
      
Package Dependencies for Using Interfaces
# package.xml
<build_depend>my_package</build_depend>
<exec_depend>my_package</exec_depend>

# CMakeLists.txt
find_package(catkin REQUIRED COMPONENTS
  my_package
)
      
# package.xml
<depend>my_package</depend>

# CMakeLists.txt (for C++)
find_package(my_package REQUIRED)

# For accessing interfaces in the same package:
rosidl_target_interfaces(your_node
  ${PROJECT_NAME} "rosidl_typesupport_cpp"
)
      
Checking Interface Definition rosmsg show my_package/MyMessage
rossrv show my_package/MyService
ros2 interface show my_package/msg/MyMessage
ros2 interface show my_package/srv/MyService
Listing Available Interfaces rosmsg list
rossrv list
ros2 interface list
Finding Packages with Interface rosmsg packages
rossrv packages
ros2 interface packages

Key Differences in Custom Interface Creation

Aspect ROS1 ROS2
Message Generation System Uses message_generation and message_runtime packages Uses rosidl_default_generators and rosidl_default_runtime packages
Header Import Uses Header header directly in .msg files Requires explicit std_msgs/Header header with namespace in .msg files
C++ Header Paths #include <package_name/MessageName.h> #include <package_name/msg/message_name.hpp> (with msg/ in path)
C++ Type Names package_name::MessageName package_name::msg::MessageName (with msg:: namespace)
Build Process Multi-step with separate add_message_files and generate_messages Single call to rosidl_generate_interfaces
Interface File Naming Common to use same filename in different packages (but can cause collisions) Uses namespaces to avoid collisions
Recommended Package Structure Often mixed interfaces with node code Dedicated interface packages separate from node code
Variable Naming Rules Flexible, allows various naming styles Strict, only snake_case allowed for field names

留言

這個網誌中的熱門文章

Tuing PID parameters in QGroundcontrol (2)

Useful PX4 Parameters

Matlab Pixhawk Support Package installation (Windows)