从ROS 1迁移指南 [待校准@799]
目录
有两种不同的包迁移: [待校准@800]
将现有包的源文件代码从ROS 1迁移到ROS 2,目的是使源文件代码的很大一部分保持不变或至少保持相似。这方面的一个例子可以是 pluginlib ,其中源文件代码保存在同一仓库的不同分支中,并且通常在必要时可以在这些分支之间移植补丁。 [待校准@801]
为ROS 2实现ROS 1包的相同或相似功能,但假设源文件将有很大的不同。这方面的一个例子可能是ROS 2中的 roscpp in ROS 1 and rclcpp ,它是独立的仓库,不共享任何代码。 [待校准@802]
本文重点介绍前一种情况,并介绍将ROS 1包迁移到ROS 2的高级步骤。它的目标不是一步一步的迁移指令,也不被认为是最终的 "solution" 。未来的版本将旨在使迁移更加顺畅,减少工作量,从而为ROS 1和ROS 2维护来自同一分支的单个包。 [待校准@803]
迁移步骤 [待校准@806]
包装清单 [待校准@807]
ROS 2不支持包规格的格式1,只支持更新的格式版本 (2和更高版本)。因此,如果 package.xml
文件使用格式1,它必须至少更新为格式2。因为ROS 1支持所有格式,所以在ROS 1包中执行转换是安全的。 [待校准@808]
某些包在ROS 2中可能具有不同的名称,因此可能需要相应地更新依赖项。 [待校准@809]
元包 [待校准@810]
ROS 2没有元包的特殊包类型。元包仍然可以作为仅包含运行时依赖项的常规包存在。从ROS 1迁移元包时,只需删除包清单中的 <metapackage />
标签。 [待校准@811]
消息、服务和动作定义 [待校准@812]
消息文件必须以 .msg
结尾,并且必须位于子文件夹 msg
。服务文件必须以 .srv
结尾,并且必须位于 srv
子文件夹中。Action文件必须结束 .action
必须位于子文件夹 action
。 [待校准@813]
这些文件可能需要更新以符合 ROS Interface definition 。一些原始类型已被删除,ROS 1中内置类型的 duration
和 time
类型已被普通消息定义替换,必须从 builtin_interfaces 包中使用。此外,一些命名约定比ROS 1更严格。 [待校准@814]
在你的 package.xml
里: [待校准@815]
加入
<buildtool_depend>rosidl_default_generators</buildtool_depend>
。 [待校准@816]加入
<exec_depend>rosidl_default_runtime</exec_depend>
。 [待校准@817]对于每个依赖消息包,添加
<depend>message_package</depend>
。 [待校准@818]
在你的 CMakeLists.txt
里: [待校准@819]
从启用c14 14开始 [待校准@820]
set(CMAKE_CXX_STANDARD 14)
添加
find_package(rosidl_default_generators REQUIRED)
[待校准@821]对于每个依赖消息包,添加
find_package(message_package REQUIRED)
,并用rosidl_generate_interfaces
替换调用generate_messages
的CMake函数。 [待校准@822]
这将取代所有可以删除的消息和服务文件的 add_message_files
和 add_service_files
列表。 [待校准@823]
构建系统 [待校准@824]
ROS 2中的构建系统被调用 ament ,构建工具是 colcon. ,Ament建立在CMake上: ament_cmake
提供CMake功能,使编写 CMakeLists.txt
文件更容易。 [待校准@825]
构建工具 [待校准@826]
而不是使用 catkin_make
, catkin_make_isolated
或 catkin build
ROS 2使用命令行工具 colcon 建立和安装一组包。 [待校准@827]
纯Python包 [待校准@828]
如果ROS 1包仅使用CMake调用 setup.py
文件,并且不包含除Python代码之外的任何内容 (例如g.也没有消息、服务等。) 它应该在ROS 2中转换为纯Python包: [待校准@829]
更新或添加
package.xml
文件中的构建类型: [待校准@830]<export> <build_type>ament_python</build_type> </export>
删除
CMakeLists.txt
文件 [待校准@831]将
setup.py
文件更新为标准Python安装脚本 [待校准@832]
ROS 2仅支持Python 3。虽然每个包可以选择也支持Python 2,但如果它使用其他ROS 2包提供的任何API,则必须使用Python 3调用可执行文件。 [待校准@833]
更新 * CMakeLists.txt * 以使用 * ament _ cmake * [待校准@834]
应用以下更改以使用 ament_cmake
代替 catkin
: [待校准@835]
在
package.xml
文件导出部分设置构建类型: [待校准@836]<export> <build_type>ament_cmake</build_type> </export>
将
find_package
的调用改为catkin
,将COMPONENTS
的调用改为: [待校准@837]find_package(ament_cmake REQUIRED) find_package(component1 REQUIRED) # ... find_package(componentN REQUIRED)
使用以下命令移动和更新
catkin_package
调用: [待校准@838]而是在所有目标都注册后调用
ament_package
。 [待校准@839][需手动修复的语法] ament_package 唯一有效的论据是
CONFIG_EXTRAS
。所有其他参数都包含在单独的函数中,这些函数都需要在 *ament_package
之前调用: [待校准@840]TODO document ament_export_targets (``ament_export_interfaces`` in Eloquent and older)?
用 rosidl_generate_interfaces 代替
add_message_files
、add_service_files
和generate_messages
的调用。 [待校准@845]第一个论点是
target_name
。如果您是're building just one library it' ${PROJECT_NAME}'' [待校准@846]后跟相对于包根目录的消息文件名列表。 [待校准@847]
如果您将多次使用文件名列表,建议编写一个消息文件列表,并将该列表传递给函数以使其清晰。 [待校准@848]
最终的多值关键字参数fpr
generate_messages
是DEPENDENCIES
,它需要从属消息包的列表。 [待校准@849]rosidl_generate_interfaces(${PROJECT_NAME} ${msg_files} DEPENDENCIES std_msgs )
删除出现的 * devel空间 *。像
CATKIN_DEVEL_PREFIX
这样的相关CMake变量已经不存在了。 [待校准@850][需手动修复的语法]
CATKIN_DEPENDS
和DEPENDS
的参数被传递给新的函数 ament_export_dependencies 。 [待校准@851]CATKIN_GLOBAL_BIN_DESTINATION
:bin
[待校准@852]CATKIN_GLOBAL_INCLUDE_DESTINATION
:include
[待校准@853]CATKIN_GLOBAL_LIB_DESTINATION
:lib
[待校准@854]CATKIN_GLOBAL_LIBEXEC_DESTINATION
:lib
[待校准@855]CATKIN_GLOBAL_SHARE_DESTINATION
:share
[待校准@856]CATKIN_PACKAGE_BIN_DESTINATION
:lib/${PROJECT_NAME}
[待校准@857]CATKIN_PACKAGE_INCLUDE_DESTINATION
:include/${PROJECT_NAME}
[待校准@858]CATKIN_PACKAGE_LIB_DESTINATION
:lib
[待校准@859]CATKIN_PACKAGE_SHARE_DESTINATION
:share/${PROJECT_NAME}
[待校准@860]
单元测试 [待校准@861]
如果您正在使用gtest: [待校准@862]
用 BUILD_TESTING
代替 CATKIN_ENABLE_TESTING
。用 ament_add_gtest
代替 catkin_add_gtest
。 [待校准@863]
- if (CATKIN_ENABLE_TESTING)
- find_package(GTest REQUIRED) # or rostest
- include_directories(${GTEST_INCLUDE_DIRS})
- catkin_add_gtest(${PROJECT_NAME}-some-test src/test/some_test.cpp)
- target_link_libraries(${PROJECT_NAME}-some-test
- ${PROJECT_NAME}_some_dependency
- ${catkin_LIBRARIES}
- ${GTEST_LIBRARIES})
- endif()
+ if (BUILD_TESTING)
+ find_package(ament_cmake_gtest REQUIRED)
+ ament_add_gtest(${PROJECT_NAME}-some-test src/test/test_something.cpp)
+ ament_target_dependencies(${PROJECT_NAME)-some-test
+ "rclcpp"
+ "std_msgs")
+ target_link_libraries(${PROJECT_NAME}-some-test
+ ${PROJECT_NAME}_some_dependency)
+ endif()
在你的 package.xml
中加入 <test_depend>ament_cmake_gtest</test_depend>
。 [待校准@864]
- <test_depend>rostest</test_depend>
+ <test_depend>ament_cmake_gtest</test_depend>
林特 [待校准@327]
在ROS 2中,我们正在努力使用linters维护干净的代码。不同语言的风格在我们的 Developer Guide. 中定义 [待校准@865]
如果你从头开始一个项目,建议遵循风格指南,通过在 if(BUILD_TESTING)
下面添加这些线来打开自动linter单元测试 (直到阿尔法5,这是 AMENT_ENABLE_TESTING
)。 [待校准@866]
find_package(ament_lint_auto REQUIRED)
ament_lint_auto_find_test_dependencies()
您还需要将以下依赖项添加到您的 package.xml
中: [待校准@867]
<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>
更新源文件 [待校准@871]
消息、服务和动作 [待校准@872]
ROS 2消息、服务和动作的命名空间在包名称后使用子命名空间 (分别为 msg
、 srv
或 action
)。因此,一个包含看起来像: #include <my_interfaces/msg/my_message.hpp>
。然后将ctype类型命名为: “my_interface::msg:: mymessage”。 [待校准@873]
共享指针类型在消息结构中作为typedefs提供: “我的接口::msg::MyMessage::SharedPtr `` as well as `` 我的接口::msg::MyMessage:: constsharedptr”。 [待校准@874]
有关更多详细信息,请参阅有关 generated C++ interfaces 的文章。 [待校准@875]
迁移要求包含更改方式: [待校准@876]
// ROS 1 style is in comments, ROS 2 follows, uncommented.
// # include <geometry_msgs/PointStamped.h>
#include <geometry_msgs/msg/point_stamped.hpp>
// geometry_msgs::PointStamped point_stamped;
geometry_msgs::msg::PointStamped point_stamped;
迁移需要代码才能将 msg
命名空间插入所有实例。 [待校准@880]
服务对象的使用 [待校准@881]
ROS 2中的服务调用没有boolean返回值。建议抛出异常,而不是在失败时返回false。 [待校准@882]
// ROS 1 style is in comments, ROS 2 follows, uncommented.
// #include "nav_msgs/GetMap.h"
#include "nav_msgs/srv/get_map.hpp"
// bool service_callback(
// nav_msgs::GetMap::Request & request,
// nav_msgs::GetMap::Response & response)
void service_callback(
const std::shared_ptr<nav_msgs::srv::GetMap::Request> request,
std::shared_ptr<nav_msgs::srv::GetMap::Response> response)
{
// ...
// return true; // or false for failure
}
ros的用法:: 时间 [待校准@883]
对于 “ros:: time” 的用法: [待校准@884]
ros的用法:: 费率 [待校准@890]
有一个等效类型 “rclcpp::Rate `` object which is basically a drop in replacement for `` ros:: rate”。 [待校准@891]
参数
在ROS 1中,参数与允许在运行时通过使用网络api检索参数的中央服务器相关联。在ROS 2中,参数与每个节点相关联,并且在运行时可通过ROS服务进行配置。 [待校准@914]
有关系统模型的更多详细信息,请参见 ROS 2 Parameter design document 。 [待校准@915]
有关CLI工具的工作方式及其与ROS 1工具的区别的更好理解,请参见 ROS 2 CLI usage 。 [待校准@916]
请参阅: doc:'//操作指南/Parameters-YAML-文件-迁移-指南',以了解如何在ROS 2中解析YAML参数文件及其与ROS实现的差异。 [待校准@917]
Launch档案 [待校准@918]
虽然ROS 1中的launch文件始终使用 .xml 文件指定,但ROS 2支持Python脚本以实现更大的灵活性 (见 launch package ) 以及XML和YAML文件。关于将launch文件从ROS 1迁移到ROS 2,请参见 separate tutorial 。 [待校准@919]
示例: 将现有的ROS 1包转换为使用ROS 2 [待校准@920]
假设我们有一个简单的ROS 1包调用ed talker
,它在一个节点中使用 roscpp
,调用ed talker
。此包位于catkin工作区,位于 “~/ros1_talker”。 [待校准@921]
ROS 1代码 [待校准@922]
这是我们catkin工作区的目录布局: [待校准@923]
$ cd ~/ros1_talker
$ find .
.
./src
./src/talker
./src/talker/package.xml
./src/talker/CMakeLists.txt
./src/talker/talker.cpp
以下是这三个文件的内容: [待校准@924]
src/talker/package.xml
: [待校准@925]
<package>
<name>talker</name>
<version>0.0.0</version>
<description>talker</description>
<maintainer email="gerkey@osrfoundation.org">Brian Gerkey</maintainer>
<license>Apache 2.0</license>
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<build_depend>std_msgs</build_depend>
<run_depend>roscpp</run_depend>
<run_depend>std_msgs</run_depend>
</package>
src/talker/CMakeLists.txt
: [待校准@926]
cmake_minimum_required(VERSION 2.8.3)
project(talker)
find_package(catkin REQUIRED COMPONENTS roscpp std_msgs)
catkin_package()
include_directories(${catkin_INCLUDE_DIRS})
add_executable(talker talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
install(TARGETS talker
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})
src/talker/talker.cpp
: [待校准@927]
#include <sstream>
#include "ros/ros.h"
#include "std_msgs/String.h"
int main(int argc, char **argv)
{
ros::init(argc, argv, "talker");
ros::NodeHandle n;
ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
ros::Rate loop_rate(10);
int count = 0;
std_msgs::String msg;
while (ros::ok())
{
std::stringstream ss;
ss << "hello world " << count++;
msg.data = ss.str();
ROS_INFO("%s", msg.data.c_str());
chatter_pub.publish(msg);
ros::spinOnce();
loop_rate.sleep();
}
return 0;
}
迁移到ROS 2 [待校准@933]
让我们从创建一个新的工作空间开始: [待校准@934]
mkdir ~/ros2_talker
cd ~/ros2_talker
我们将把源文件树从我们的ROS 1包复制到那个工作区,在那里我们可以修改它: [待校准@935]
mkdir src
cp -a ~/ros1_talker/src/talker src
现在,我们将修改节点中的ccode代码。调用ed rclcpp
的ROS 2 c library库提供了与 roscpp
提供的API不同的API。两个库之间的概念非常相似,这使得更改相当简单。 [待校准@936]
包含标题 [待校准@937]
取代 ros/ros.h
,它使我们能够访问 roscpp
库API,我们需要包括 rclcpp/rclcpp.hpp
,它使我们能够访问 rclcpp
库API: [待校准@938]
//#include "ros/ros.h"
#include "rclcpp/rclcpp.hpp"
为了得到 std_msgs/String
信息定义,我们需要包括 std_msgs/msg/string.hpp
,而不是 std_msgs/String.h
: [待校准@939]
//#include "std_msgs/String.h"
#include "std_msgs/msg/string.hpp"
更改clibrary库调用s [待校准@940]
我们进行初始化,而不是将节点的名称传递给库初始化调用,然后将节点名称传递给节点对象的创建 (我们可以使用 auto
关键字,因为现在我们需要一个c14 14编译器): [待校准@941]
// ros::init(argc, argv, "talker");
// ros::NodeHandle n;
rclcpp::init(argc, argv);
auto node = rclcpp::Node::make_shared("talker");
发布者和速率对象的创建看起来非常相似,对命名空间和方法的名称进行了一些更改。 [待校准@942]
// ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
// ros::Rate loop_rate(10);
auto chatter_pub = node->create_publisher<std_msgs::msg::String>("chatter",
1000);
rclcpp::Rate loop_rate(10);
为了进一步控制如何处理消息传递,可以传递服务质量 ( QoS
) 配置文件。默认配置文件为 rmw_qos_profile_default
。更多详情,请参见 design document 和 concept overview. [待校准@943]
传出消息的创建在命名空间中不同: [待校准@944]
// std_msgs::String msg;
std_msgs::msg::String msg;
代替 “ros::ok()”,我们调用 “rclcpp::ok()”: [待校准@945]
// while (ros::ok())
while (rclcpp::ok())
在出版循环中,我们像以前一样访问 data
领域: [待校准@946]
msg.data = ss.str();
为了打印控制台消息,我们使用的不是 ROS_INFO()
,而是 RCLCPP_INFO()
及其各种表亲。关键的区别是 RCLCPP_INFO()
把一个日志记录器作为第一个参数。 [待校准@947]
// ROS_INFO("%s", msg.data.c_str());
RCLCPP_INFO(node->get_logger(), "%s\n", msg.data.c_str());
发布消息与之前相同: [待校准@948]
chatter_pub->publish(msg);
旋转 (即让通讯系统处理任何待处理的传入/传出消息) 的不同之处在于,调用现在将节点作为参数: [待校准@949]
// ros::spinOnce();
rclcpp::spin_some(node);
使用rate对象的睡眠保持不变。 [待校准@950]
把它们放在一起,新的 talker.cpp
看起来像这样: [待校准@951]
#include <sstream>
// #include "ros/ros.h"
#include "rclcpp/rclcpp.hpp"
// #include "std_msgs/String.h"
#include "std_msgs/msg/string.hpp"
int main(int argc, char **argv)
{
// ros::init(argc, argv, "talker");
// ros::NodeHandle n;
rclcpp::init(argc, argv);
auto node = rclcpp::Node::make_shared("talker");
// ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
// ros::Rate loop_rate(10);
auto chatter_pub = node->create_publisher<std_msgs::msg::String>("chatter", 1000);
rclcpp::Rate loop_rate(10);
int count = 0;
// std_msgs::String msg;
std_msgs::msg::String msg;
// while (ros::ok())
while (rclcpp::ok())
{
std::stringstream ss;
ss << "hello world " << count++;
msg.data = ss.str();
// ROS_INFO("%s", msg.data.c_str());
RCLCPP_INFO(node->get_logger(), "%s\n", msg.data.c_str());
chatter_pub->publish(msg);
// ros::spinOnce();
rclcpp::spin_some(node);
loop_rate.sleep();
}
return 0;
}
更换 package.xml
[待校准@952]
ROS 2不支持包规格的格式1,只支持更新的格式版本 (2和更高版本)。我们首先在 package
标签中指定格式版本: [待校准@953]
<!-- <package> -->
<package format="2">
ROS 2使用 catkin
的新版本,调用 ament_cmake
,我们在 buildtool_depend
标签中指定: [待校准@954]
<!-- <buildtool_depend>catkin</buildtool_depend> -->
<buildtool_depend>ament_cmake</buildtool_depend>
在我们的构建依赖项中,我们使用的不是 roscpp
,而是 rclcpp
,它提供了我们使用的c ++ API。 [待校准@955]
<!-- <build_depend>roscpp</build_depend> -->
<build_depend>rclcpp</build_depend>
我们在运行依赖项中添加了相同的内容,并从 run_depend
标签更新到 exec_depend
标签 (包格式升级到版本2的一部分): [待校准@956]
<!-- <run_depend>roscpp</run_depend> -->
<exec_depend>rclcpp</exec_depend>
<!-- <run_depend>std_msgs</run_depend> -->
<exec_depend>std_msgs</exec_depend>
在ROS 1,我们使用 <depend>
简化指定依赖编译时和运行时。我们可以在ROS 2中做同样的事情: [待校准@957]
<depend>rclcpp</depend>
<depend>std_msgs</depend>
我们还需要告诉构建工具我们是什么样的包,以便它知道如何构建我们。因为我们使用的是 ament
和CMake,所以我们添加以下行来声明我们的构建类型为 ament_cmake
: [待校准@958]
<export>
<build_type>ament_cmake</build_type>
</export>
综上所述,我们的 package.xml
现在看起来像这样: [待校准@959]
<!-- <package> -->
<package format="2">
<name>talker</name>
<version>0.0.0</version>
<description>talker</description>
<maintainer email="gerkey@osrfoundation.org">Brian Gerkey</maintainer>
<license>Apache License 2.0</license>
<!-- <buildtool_depend>catkin</buildtool_depend> -->
<buildtool_depend>ament_cmake</buildtool_depend>
<!-- <build_depend>roscpp</build_depend> -->
<!-- <run_depend>roscpp</run_depend> -->
<!-- <run_depend>std_msgs</run_depend> -->
<depend>rclcpp</depend>
<depend>std_msgs</depend>
<export>
<build_type>ament_cmake</build_type>
</export>
</package>
Totodo: 仅使用 <depend>
标签显示此文件的更简单版本,该标签由软件包格式的版本2启用 (也在 catkin
中支持,因此,严格来说,与ROS 2正交)。** [待校准@960]
更改CMake代码 [待校准@961]
ROS 2依赖于CMake的更高版本: [待校准@962]
#cmake_minimum_required(VERSION 2.8.3)
cmake_minimum_required(VERSION 3.5)
ROS 2依赖于c14 14标准。根据您使用的编译器,默认情况下可能不会启用对c14 14的支持。使用 gcc
5.3 (这是在Ubuntu Xenial上使用的),我们需要显式启用它,我们通过在文件顶部附近添加这一行来实现: [待校准@963]
set(CMAKE_CXX_STANDARD 14)
在所有平台上工作的首选方式是: [待校准@964]
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
使用 catkin
,我们指定包我们想建立反对通过他们 COMPONENTS
参数当最初找到 catkin
本身。对于 ament_cmake
,我们发现每个包装都是单独的,从 ament_cmake
开始: [待校准@965]
#find_package(catkin REQUIRED COMPONENTS roscpp std_msgs)
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)
可以像以前一样找到系统依赖项: [待校准@966]
find_package(Boost REQUIRED COMPONENTS system filesystem thread)
我们调用 catkin_package()
,为使用我们包的其他包自动生成CMake配置文件。鉴于该调用在指定要构建的目标之前发生,我们现在在 * 目标之后调用类似的 ament_package()
*: [待校准@967]
# catkin_package()
# At the bottom of the file:
ament_package()
唯一需要手动包含的目录是非ament包的本地目录和依赖项: [待校准@968]
#include_directories(${catkin_INCLUDE_DIRS})
include_directories(include ${Boost_INCLUDE_DIRS})
更好的选择是为每个目标单独指定包含目录,而不是为所有目标包含所有目录: [待校准@969]
target_include_directories(target include ${Boost_INCLUDE_DIRS})
类似于我们分别找到每个依赖包的方式,我们需要将每个包链接到构建目标。为了与ament包的依赖包链接,而不是使用 target_link_libraries()
, ament_target_dependencies()
是处理构建标志的一种更简洁、更彻底的方法。它自动调用y处理 _INCLUDE_DIRS
中定义的包含目录和 _LIBRARIES
中定义的链接库。 [待校准@970]
#target_link_libraries(talker ${catkin_LIBRARIES})
ament_target_dependencies(talker
rclcpp
std_msgs)
要与不是ament包的包链接,例如系统依赖项,如 Boost
,或在同一 CMakeLists.txt
中构建的库,请使用 target_link_libraries()
: [待校准@971]
target_link_libraries(target ${Boost_LIBRARIES})
对于安装, catkin
定义变量,如 CATKIN_PACKAGE_BIN_DESTINATION
。对于 ament_cmake
,我们只给出一个相对于安装根的路径,就像可执行文件的 bin
: [待校准@972]
#install(TARGETS talker
# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})
install(TARGETS talker
DESTINATION lib/${PROJECT_NAME})
(可选) 我们可以为下游包安装和导出包含的目录: [待校准@973]
install(DIRECTORY include/
DESTINATION include)
ament_export_include_directories(include)
或者,我们可以导出下游包的依赖项: [待校准@974]
ament_export_dependencies(std_msgs)
把它们放在一起,新的 CMakeLists.txt
看起来像这样: [待校准@975]
#cmake_minimum_required(VERSION 2.8.3)
cmake_minimum_required(VERSION 3.5)
project(talker)
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
#find_package(catkin REQUIRED COMPONENTS roscpp std_msgs)
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)
#catkin_package()
#include_directories(${catkin_INCLUDE_DIRS})
include_directories(include)
add_executable(talker talker.cpp)
#target_link_libraries(talker ${catkin_LIBRARIES})
ament_target_dependencies(talker
rclcpp
std_msgs)
#install(TARGETS talker
# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})
install(TARGETS talker
DESTINATION lib/${PROJECT_NAME})
install(DIRECTORY include/
DESTINATION include)
ament_export_include_directories(include)
ament_export_dependencies(std_msgs)
ament_package()
Totodo: 展示 ament_auto
会是什么样子。** [待校准@976]
更新脚本 [待校准@981]
ROS CLI参数 [待校准@982]
因为 ROS Eloquent, ROS参数应该以 --ros-args
和尾随的 --
为范围 (如果没有参数跟随它,尾随的doubledash可能会被省略)。 [待校准@983]
重新映射名称类似于ROS 1,采用 “from:= to” 的形式,不同之处在于它前面必须有一个 --remap
(或 -r
) 旗。例如: [待校准@984]
ros2 run some_package some_ros_executable --ros-args -r foo:=bar
我们对参数使用类似的语法,使用 --param
(或 -p
) 标志: [待校准@985]
ros2 run some_package some_ros_executable --ros-args -p my_param:=value
请注意,这不同于在ROS 1中使用前导下划线。 [待校准@986]
要更改节点名称,请使用 __node
(ROS 1当量为 __name
): [待校准@987]
ros2 run some_package some_ros_executable --ros-args -r __node:=new_node_name
注意 -r
旗的使用。更改命名空间 __ns
需要相同的重映射标志: [待校准@988]
ros2 run some_package some_ros_executable --ros-args -r __ns:=/new/namespace
在ROS 2中,以下ROS 1键没有等效项: [待校准@989]
[需手动修复的语法]``__log`` (but
--log-config-file
can用于提供日志记录器配置文件) [待校准@990]__ip
[待校准@991]__hostname
[待校准@992]__master
[待校准@993]
有关更多信息,请参见 design document 。 [待校准@994]
快速参考 [待校准@995]
特征 [待校准@996] |
ROS 1 [待校准@997] |
ROS 2 [待校准@998] |
---|---|---|
重新映射 [待校准@999] |
foo:= bar [待校准@1000] |
-r foo:= bar [待校准@1001] |
参数 [待校准@1002] |
_ foo:= bar [待校准@1003] |
-p foo:= bar [待校准@1004] |
节点名称 [待校准@1005] |
__Name := foo [待校准@1006] |
-r __node:= foo [待校准@1007] |
命名空间 [待校准@1008] |
__Ns: = foo [待校准@1009] |
-R__ns: = foo [待校准@1010] |
更多示例和工具 [待校准@1011]
[需手动修复的语法]Launch文件migrator,转换ROS 1XMLlaunch文件ROS 2 Pythonlaunch文件: https://github.com/aws机器人/ros2-launch文件migrator [待校准@1012]
Amazon在工具移植ROS 1机器人ROS 2 https://github.com/awslabs/ ros2-migration-tools/树/主/移植 _ 工具 [待校准@1013]
许可 [待校准@1014]
在ROS 2中,我们推荐的许可证是 Apache 2.0 License. In ROS 1 our recommended license was the 3-Clause BSD License 。 [待校准@1015]
对于任何新项目,我们建议使用Apache 2.0许可证,无论是ROS 1还是ROS 2。 [待校准@1016]
但是,当将代码从ROS 1迁移到ROS 2时,我们不能简单地更改许可证。对于任何先前存在的贡献,必须保留现有许可证。 [待校准@1017]
为此,如果一个包正在迁移,我们建议保留现有的许可证,并在现有的OSI许可证下继续为该包做出贡献,我们希望该许可证是核心元素的BSD许可证。 [待校准@1018]
这将使事情清晰易懂。 [待校准@1019]
更改许可证 [待校准@1020]
可以更改许可证,但是您需要联系所有贡献者并获得许可。对于大多数包来说,这可能是一项巨大的努力,不值得考虑。如果包有一小部分贡献者,那么这可能是可行的。 [待校准@1021]