ROS 1 的迁移到ROS 2指南
前言
有两种不同类型的包迁移:
- 将现有软件包的源代码从 ROS 1 迁移到 ROS 2,目的是使源代码的重要部分保持相同或至少相似。 一个例子可能是 pluginlib ,其中源代码在同一存储库的不同分支中维护,并且通常可以在必要时在这些分支之间移植补丁。
- 为 ROS 2 实现与 ROS 1 包相同或相似的功能,但假设源代码将显着不同。 这方面的一个例子可能是 roscpp ROS 1 rclcpp ,它们是独立的存储库,不共享任何代码。
本文重点介绍前一种情况,并描述将 ROS 1 包迁移到 ROS 2 的高级步骤。 它的目标不是一步一步的迁移说明,也不是 最终 “解决方案”。 未来版本的目标是使迁移更顺畅、更省力,直至为 ROS 1 和 ROS 2 维护来自同一分支的单个包。
来源官网:http://docs.ros.org/en/rolling/Contributing/Migration-Guide.html
一、先决条件
在能够将 ROS 1 包迁移到 ROS 2 之前,它的所有依赖项必须在 ROS 2 中可用。
二、迁移步骤
1.Package manifests
ROS 2 不支持包规范的格式 1,但仅支持较新的格式版本(2 和更高版本)。 因此,如果 package.xml 文件使用格式 1,则必须将其至少更新为格式 2。由于 ROS 1 支持所有格式,因此在 ROS 1 包中执行该转换是安全的。
ROS 2 中的某些包可能具有不同的名称,因此可能需要相应地更新依赖项。
2.元功能包Metapackages
ROS 2 没有用于元包的特殊包类型。 元包仍然可以作为仅包含运行时依赖项的常规包存在。 从 ROS 1 迁移元包时,只需删除包清单中的 标记。
3.消息、服务和操作定义
消息文件必须以 .msg 结尾,并且必须位于 msg 子文件夹中。 服务文件必须以 .srv 结尾,并且必须位于子文件夹 srv 中。 动作文件必须以 .action 结尾,并且必须位于子文件夹动作中。
这些文件可能需要更新以符合 ROS 接口定义。 一些原始类型已被删除,并且在 ROS 1 中作为内置类型的类型 duration 和 time 已被替换为正常的消息定义,并且必须从 builtin_interfaces 包中使用。 还有一些命名约定比 ROS 1 中的更严格。
在 package.xml 中:
添加 <buildtool_depend>rosidl_default_generators</buildtool_depend>。
添加 <exec_depend>rosidl_default_runtime</exec_depend>。
对于每个依赖的消息包,添加 <depend>message_package</depend>。
在CMakeLists.txt 中:
ROS 2 必须要 C++14或以上版本(已默认):
set(CMAKE_CXX_STANDARD 14)
添加 find_package(rosidl_default_generators REQUIRED)
对于每个依赖的消息包,添加 find_package(message_package REQUIRED) 并将对 generate_messages 的
CMake 函数调用替换为 rosidl_generate_interfaces。
这将替换所有可以删除的消息和服务文件的 add_message_files 和 add_service_files 列表。
4.构建系统 Build system
ROS 2 中的构建系统称为 ament,构建工具是 colcon。 Ament 建立在 CMake 之上: ament_cmake 提供 CMake 函数,使编写 CMakeLists.txt 文件更容易。
5.编译工具 Build tool
ROS 2 使用命令行工具 colcon 来构建和安装一组包,而不是使用 catkin_make、catkin_make_isolated 或 catkin build 。
6. 纯 Python 包
如果 ROS 1 包仅使用 CMake 来调用 setup.py 文件并且不包含 Python 代码之外的任何内容(例如,也没有消息、服务等),则应在 ROS 2 中将其转换为纯 Python 包:
- 在 package.xml 文件中更新或添加构建类型
<export>
<build_type>ament_python</build_type>
</export>
- 删除 CMakeLists.txt 文件
- 将 setup.py 文件更新为标准 Python 设置脚本
ROS 2 仅支持 Python 3。 虽然每个包都可以选择也支持 Python 2,但如果它使用其他 ROS 2 包提供的任何 API,则必须使用 Python 3 调用可执行文件。
6.更新 CMakeLists.txt 以使用 ament_cmake
应用以下更改以使用 ament_cmake 而不是 catkin:
- 在 package.xml 文件导出部分设置构建类型:
<export>
<build_type>ament_cmake</build_type>
</export>
- 用 catkin 和 COMPONENTS 替换 find_package 调用:
find_package(ament_cmake REQUIRED)
find_package(component1 REQUIRED)
# ...
find_package(componentN REQUIRED)
-
使用以下命令移动和更新 catkin_package 调用:
在所有目标都已注册之后调用 ament_package。 ament_package 的唯一有效参数是 CONFIG_EXTRAS。 所有其他参数都由单独的函数覆盖,这些函数都需要在ament_package 之前调用: 1、 使用 ament_export_dependencies(...) 来替代CATKIN_DEPENDS ... 2、使用ament_export_include_directories(...)来替代INCLUDE_DIRS ... 3、使用ament_export_libraries(...)来替代LIBRARIES ...
-
将 rosidl_generate_interfaces 替换 add_message_files、add_service_files 和 generate_messages
1、第一个参数是 target_name。 如果你只构建一个库,那就是 ${PROJECT_NAME} 2、包根目录后面编写消息文件列表: 如果将多次使用文件名列表,以清楚起见,建议编写一个消息文件列表并将列表传递给函数。 3、最后的多值关键字参数 fpr generate_messages 是 DEPENDENCIES,它需要依赖消息包的列表:
rosidl_generate_interfaces(${PROJECT_NAME}
${msg_files}
DEPENDENCIES std_msgs
)