Dashing Diademata (dashing)

Dashing Diademata is the fourth release of ROS 2.

支持的平台

Dashing Diademata 主要支持以下平台:

一级平台:

  • Ubuntu 18.04 (Bionic): amd64 and arm64

  • Mac macOS 10.12 (Sierra)

  • Windows 10 (Visual Studio 2019)

二级平台:

  • Ubuntu 18.04 (Bionic): arm32

三级平台:

  • Debian Stretch (9): amd64, arm64 and arm32

  • OpenEmbedded Thud (2.6) / webOS OSE: arm32 and x86

有关 RMW 实现、编译器/解释器版本和系统依赖项版本的更多信息,请参阅 REP 2000

安装

Install Dashing Diademata

此 ROS 2 版本中的新功能

我们想重点介绍一些功能和改进:

  • 组件 现在是编写节点的推荐方式。

它们可以独立使用,也可以在进程内组合使用,并且这两种方式都完全受 launch 文件的支持。 * 进程内通信 <../Tutorials/Demos/Intra-Process-Communication>`(仅限 C++)已得到改进 - 无论是在延迟方面还是在最小化副本方面。 * Python 客户端库已更新以匹配大多数 C++ 等效库,并且已经实现了一些与内存使用和性能相关的重要错误修复和改进。 * 参数现在是 ROS 1 中 ``dynamic_reconfigure` 的完整替代方案,包括范围或只读等约束。 * 通过依赖 IDL 4.2 <https://www.omg.org/spec/IDL/4.2>`__(的一个子集)作为消息生成管道,现在可以使用 `.idl`` 文件(除了 .msg / .srv / .action 文件)。 此更改支持普通字符串的可选 UTF-8 编码以及 UTF-16 编码的多字节字符串(请参阅``宽字符串设计文章 <https://design.ros2.org/articles/wide_strings.html>`__)。 * 与 actionscomponents 相关的命令行工具。 * 支持 Deadline、Lifespan 和 Liveliness 服务质量设置。 * MoveIt 2 alpha 版本

请参阅 GitHub 上的“Dashing 元票证 <https://github.com/ros2/ros2/issues/607>”,其中包含更多信息以及带有更多详细信息的特定票证的引用。

自 Crystal 发布以来的变化

声明参数

从 Dashing 开始,参数的行为发生了一些变化,这也导致了一些新的 API 和其他 API 的弃用。 有关 API 更改的更多信息,请参阅下面的“rclcpp”和“rclpy”部分。

获取和设置未声明的参数

从 Dashing 开始,现在需要在访问或设置参数之前声明参数。

在 Dashing 之前,您可以调用 get_parameter(name) 并获取一个值(如果之前已设置)或 PARAMETER_NOT_SET 类型的参数。

您还可以随时调用 set_parameter(name, value),即使该参数之前未设置。

从 Dashing 开始,您需要先声明一个参数,然后才能获取或设置它。

如果您尝试获取或设置未声明的参数,您将会得到一个异常,例如 ParameterNotDeclaredException,或者在某些情况下,您将以各种方式传达不成功的结果(有关更多详细信息,请参阅特定函数)。

但是,您可以获得通过在创建节点时使用 allow_undeclared_pa​​rameters 选项来恢复旧行为(大多数情况下,请参阅下一段中的注释)。 您可能希望这样做以避免暂时更改代码,或者为了满足一些不常见的用例。 例如,“全局参数服务器”或“参数黑板”可能希望允许外部节点在不先声明新参数的情况下自行设置新参数,因此它可以使用 allow_undeclared_pa​​rameters 选项来实现这一点。 但是,在大多数情况下,不建议使用此选项,因为它会使其余参数 API 不太安全,容易出现参数名称拼写错误和“设置前使用”逻辑错误等错误。

请注意,使用 allow_undeclared_pa​​rameters 将使您获得大多数旧行为,特别是针对“get”和“set”方法,但它不会将与参数相关的所有行为更改恢复为 ROS Crystal 的状态。 为此,您还需要将 automatically_declare_parameters_from_overrides 选项设置为 true,如下文 使用 YAML 文件 <parameter-configuration-using-a-yaml-file> 进行参数配置` 中所述。

使用 ParameterDescriptor 声明参数

在使用参数之前声明参数的另一个好处是,它允许您同时声明参数描述符。

现在,在声明参数时,您可以包含自定义“ParameterDescriptor”以及名称和默认值。 “ParameterDescriptor”在“rcl_interfaces/msg/ParameterDescriptor”中定义为一条消息,包含元数据(如“description”)和约束(如“read_only”或“integer_range”)。 这些约束可用于在设置参数时拒绝无效值和/或作为外部工具的提示,提示哪些值对于给定参数有效。 “read_only”约束将防止参数的值在声明后发生变化,并防止其被取消声明。

作为参考,以下是截至撰写本文时的“ParameterDescriptor”消息的链接:

https://github.com/ros2/rcl_interfaces/blob/0aba5a142878c2077d7a03977087e7d74d40ee68/rcl_interfaces/msg/ParameterDescriptor.msg#L1

使用 YAML 文件进行参数配置

从 Dashing 开始,YAML 配置文件中的参数(例如通过命令行参数 __params:= 传递给节点的参数)仅用于在声明参数时覆盖参数的默认值。

在 Dashing 之前,您通过 YAML 文件传递​​的任何参数都将隐式设置在节点上。

自 Dashing 以来,情况不再如此,因为需要声明参数才能在节点上显示给外部观察者,例如 ros2 param list

创建节点时,可以使用 automatically_declare_parameters_from_overrides 选项实现旧行为。

如果将此选项设置为 true,则在构建节点时会自动声明输入 YAML 文件中的所有参数。 这可能可用于避免对现有代码进行重大更改或满足特定用例。 例如,“全局参数服务器”可能希望在启动时使用任意参数进行播种,而这些参数无法提前声明。 但是,大多数情况下不建议使用此选项,因为它可能导致在 YAML 文件中设置参数,并假设节点将使用它,即使节点实际上没有使用它。 我们希望将来有一个检查器,如果您将参数传递给节点,而它没有预料到,它会向您发出警告。 YAML 文件中的参数将继续影响参数首次声明时的值。

ament_cmake

CMake 函数“ament_index_has_resource”返回“TRUE”或“FALSE”。 从“此版本 <https://github.com/ament/ament_cmake/pull/155>”开始,如果找到资源,它将返回前缀路径,否则返回“FALSE”。

如果您在 CMake 条件中使用返回值,如下所示:

ament_index_has_resource(var ...)
if(${var})

您需要更新条件以确保它将字符串值视为“TRUE”:

if(var)

rclcpp

Node::get_node_names() 的行为变化

函数 NodeGraph::get_node_names(),以及 Node::get_node_names(),现在返回一个 std::vector<std::string>,其中包含完全限定的节点名称及其命名空间,而不仅仅是节点名称。

更改了将选项传递给节点的方式

rclcpp::Node() 构造函数的扩展参数(除名称和命名空间外)已被替换为 rclcpp::NodeOptions 结构。

有关选项的结构和默认值的详细信息,请参阅 ros2/rclcpp#622

如果您使用 rclcpp::Node() 的任何扩展参数,如下所示:

auto context = rclcpp::contexts::default_context::get_global_default_context();
std::vector<std::string> args;
std::vector<rclcpp::Parameter> params = { rclcpp::Parameter("use_sim_time", true) };
auto node = std::make_shared<rclcpp::Node>("foo_node", "bar_namespace", context, args, params);

您需要更新才能使用“NodeOptions”结构

std::vector<std::string> args;
std::vector<rclcpp::Parameter> params = { rclcpp::Parameter("use_sim_time", true) };
rclcpp::NodeOptions node_options;
node_options.arguments(args);
node_options.parameter_overrides(params);
auto node = std::make_shared<rclcpp::Node>("foo_node", "bar_namespace", node_options);

创建发布者和订阅的变更

Dashing 中对创建发布者和订阅进行了一些新变更:

  • QoS 设置现在使用新的 rclcpp::QoS 类传递,并且 API 鼓励用户至少指定历史深度。

  • 选项现在作为对象传递,即 rclcpp::PublisherOptionsrclcpp::SubscriptionOptions

所有变更都向后兼容(无需更改代码),但已弃用几种现有的调用样式。

鼓励用户更新到新签名。


过去,在创建发布者或订阅时,您可以不指定任何 QoS 设置(例如,只提供发布者的主题名称),也可以指定“qos 配置文件”数据结构(类型为 rmw_qos_profile_t),其中已设置所有设置。

现在,您必须使用新的 rclcpp::QoS 对象来指定您的 QoS 以及至少 QoS 的历史记录设置。

这鼓励用户在使用 KEEP_LAST 时指定历史记录深度,而不是将其默认为可能合适也可能不合适的值。

在 ROS 1 中,这被称为 queue_size,它在 C++ 和 Python 中都是必需的。

我们正在更改 ROS 2 API 以恢复此要求。


此外,以前在创建发布者或订阅时可以传递的任何选项现在分别封装在 rclcpp::PublisherOptionsrclcpp::SubscriptionOptions 类中。 这样可以缩短签名,使用起来更方便,并且可以在不破坏 API 的情况下添加新的未来选项。


一些用于创建发布者和订阅者的签名现已弃用,并添加了新的签名以允许您使用新的 rclcpp::QoS 和发布者/订阅选项类。

这些是新的和推荐的 API:

template<
  typename MessageT,
  typename AllocatorT = std::allocator<void>,
  typename PublisherT = ::rclcpp::Publisher<MessageT, AllocatorT>>
std::shared_ptr<PublisherT>
create_publisher(
  const std::string & topic_name,
  const rclcpp::QoS & qos,
  const PublisherOptionsWithAllocator<AllocatorT> & options =
  PublisherOptionsWithAllocator<AllocatorT>()
);

template<
  typename MessageT,
  typename CallbackT,
  typename AllocatorT = std::allocator<void>,
  typename SubscriptionT = rclcpp::Subscription<
    typename rclcpp::subscription_traits::has_message_type<CallbackT>::type, AllocatorT>>
std::shared_ptr<SubscriptionT>
create_subscription(
  const std::string & topic_name,
  const rclcpp::QoS & qos,
  CallbackT && callback,
  const SubscriptionOptionsWithAllocator<AllocatorT> & options =
  SubscriptionOptionsWithAllocator<AllocatorT>(),
  typename rclcpp::message_memory_strategy::MessageMemoryStrategy<
    typename rclcpp::subscription_traits::has_message_type<CallbackT>::type, AllocatorT
  >::SharedPtr
  msg_mem_strat = nullptr);

以下是已弃用的:

template<
  typename MessageT,
  typename AllocatorT = std::allocator<void>,
  typename PublisherT = ::rclcpp::Publisher<MessageT, AllocatorT>>
[[deprecated("use create_publisher(const std::string &, const rclcpp::QoS &, ...) instead")]]
std::shared_ptr<PublisherT>
create_publisher(
  const std::string & topic_name,
  size_t qos_history_depth,
  std::shared_ptr<AllocatorT> allocator);

template<
  typename MessageT,
  typename AllocatorT = std::allocator<void>,
  typename PublisherT = ::rclcpp::Publisher<MessageT, AllocatorT>>
[[deprecated("use create_publisher(const std::string &, const rclcpp::QoS &, ...) instead")]]
std::shared_ptr<PublisherT>
create_publisher(
  const std::string & topic_name,
  const rmw_qos_profile_t & qos_profile = rmw_qos_profile_default,
  std::shared_ptr<AllocatorT> allocator = nullptr);

template<
  typename MessageT,
  typename CallbackT,
  typename Alloc = std::allocator<void>,
  typename SubscriptionT = rclcpp::Subscription<
    typename rclcpp::subscription_traits::has_message_type<CallbackT>::type, Alloc>>
[[deprecated(
  "use create_subscription(const std::string &, const rclcpp::QoS &, CallbackT, ...) instead"
)]]
std::shared_ptr<SubscriptionT>
create_subscription(
  const std::string & topic_name,
  CallbackT && callback,
  const rmw_qos_profile_t & qos_profile = rmw_qos_profile_default,
  rclcpp::callback_group::CallbackGroup::SharedPtr group = nullptr,
  bool ignore_local_publications = false,
  typename rclcpp::message_memory_strategy::MessageMemoryStrategy<
    typename rclcpp::subscription_traits::has_message_type<CallbackT>::type, Alloc>::SharedPtr
  msg_mem_strat = nullptr,
  std::shared_ptr<Alloc> allocator = nullptr);

template<
  typename MessageT,
  typename CallbackT,
  typename Alloc = std::allocator<void>,
  typename SubscriptionT = rclcpp::Subscription<
    typename rclcpp::subscription_traits::has_message_type<CallbackT>::type, Alloc>>
[[deprecated(
  "use create_subscription(const std::string &, const rclcpp::QoS &, CallbackT, ...) instead"
)]]
std::shared_ptr<SubscriptionT>
create_subscription(
  const std::string & topic_name,
  CallbackT && callback,
  size_t qos_history_depth,
  rclcpp::callback_group::CallbackGroup::SharedPtr group = nullptr,
  bool ignore_local_publications = false,
  typename rclcpp::message_memory_strategy::MessageMemoryStrategy<
    typename rclcpp::subscription_traits::has_message_type<CallbackT>::type, Alloc>::SharedPtr
  msg_mem_strat = nullptr,
  std::shared_ptr<Alloc> allocator = nullptr);

QoS 传递方式的改变最有可能对用户产生影响。

对于发布商来说,典型的改变如下:

- pub_ = create_publisher<std_msgs::msg::String>("chatter");
+ pub_ = create_publisher<std_msgs::msg::String>("chatter", 10);

订阅如下:

- sub_ = create_subscription<std_msgs::msg::String>("chatter", callback);
+ sub_ = create_subscription<std_msgs::msg::String>("chatter", 10, callback);

如果您不知道要使用什么深度,并且现在也不关心(可能只是原型设计),那么我们建议使用“10”,因为这是之前的默认值,应该保留现有行为。

有关如何选择合适深度的更多深入文档即将发布。

这是一个稍微复杂一些的更改示例,旨在避免使用新弃用的 API:

- // Creates a latched topic
- rmw_qos_profile_t qos = rmw_qos_profile_default;
- qos.depth = 1;
- qos.durability = RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL;
-
  model_xml_.data = model_xml;
  node_handle->declare_parameter("robot_description", model_xml);
  description_pub_ = node_handle->create_publisher<std_msgs::msg::String>(
-   "robot_description", qos);
+   "robot_description",
+   // Transient local is similar to latching in ROS 1.
+   rclcpp::QoS(1).transient_local());

请参阅引入 QoS 更改的拉取请求(以及连接的拉取请求)以获取更多示例和详细信息:

由于声明参数更改而导致的更改

有关实际行为更改的详细信息,请参阅上面的`声明参数`_。

rclcpp::Node 的接口中有几个新的 API 调用:

  • 声明给定名称、可选默认值、可选描述符的参数并返回实际设置的值的方法:

    const rclcpp::ParameterValue &
    rclcpp::Node::declare_parameter(
      const std::string & name,
      const rclcpp::ParameterValue & default_value = rclcpp::ParameterValue(),
      const rcl_interfaces::msg::ParameterDescriptor & parameter_descriptor =
      rcl_interfaces::msg::ParameterDescriptor());
    
    template<typename ParameterT>
    auto
    rclcpp::Node::declare_parameter(
      const std::string & name,
      const ParameterT & default_value,
      const rcl_interfaces::msg::ParameterDescriptor & parameter_descriptor =
      rcl_interfaces::msg::ParameterDescriptor());
    
    template<typename ParameterT>
    std::vector<ParameterT>
    rclcpp::Node::declare_parameters(
      const std::string & namespace_,
      const std::map<std::string, ParameterT> & parameters);
    
    template<typename ParameterT>
    std::vector<ParameterT>
    rclcpp::Node::declare_parameters(
      const std::string & namespace_,
      const std::map<
        std::string,
        std::pair<ParameterT, rcl_interfaces::msg::ParameterDescriptor>
      > & parameters);
    
  • 取消声明参数并检查参数是否已声明的方法:

    void
    rclcpp::Node::undeclare_parameter(const std::string & name);
    
    bool
    rclcpp::Node::has_parameter(const std::string & name) const;
    
  • 一些以前不存在的便捷方法:

    rcl_interfaces::msg::SetParametersResult
    rclcpp::Node::set_parameter(const rclcpp::Parameter & parameter);
    
    std::vector<rclcpp::Parameter>
    rclcpp::Node::get_parameters(const std::vector<std::string> & names) const;
    
    rcl_interfaces::msg::ParameterDescriptor
    rclcpp::Node::describe_parameter(const std::string & name) const;
    
  • 一种设置回调的新方法,每当参数发生变化时就会调用该方法,让您有机会拒绝它:

    using OnParametersSetCallbackType =
      rclcpp::node_interfaces::NodeParametersInterface::OnParametersSetCallbackType;
    
    OnParametersSetCallbackType
    rclcpp::Node::set_on_parameters_set_callback(
      OnParametersSetCallbackType callback);
    

还有几种已弃用的方法:

template<typename ParameterT>
[[deprecated("use declare_parameter() instead")]]
void
rclcpp::Node::set_parameter_if_not_set(
  const std::string & name,
  const ParameterT & value);

template<typename ParameterT>
[[deprecated("use declare_parameters() instead")]]
void
rclcpp::Node::set_parameters_if_not_set(
  const std::string & name,
  const std::map<std::string, ParameterT> & values);

template<typename ParameterT>
[[deprecated("use declare_parameter() and it's return value instead")]]
void
rclcpp::Node::get_parameter_or_set(
  const std::string & name,
  ParameterT & value,
  const ParameterT & alternative_value);

template<typename CallbackT>
[[deprecated("use set_on_parameters_set_callback() instead")]]
void
rclcpp::Node::register_param_change_callback(CallbackT && callback);

内存策略

接口 rclcpp::memory_strategy::MemoryStrategy 在各种方法签名中使用 typedef WeakNodeVector

从 Dashing 开始,typedef 已更改为 WeakNodeList,并且各种方法中的参数类型也随之更改。

任何自定义内存策略都需要更新以匹配修改后的接口。

相关 API 更改可在 ros2/rclcpp#741 中找到。

rclcpp_components

在 Dashing 中实现组合的正确方法是利用 rclcpp_components 包。

必须对节点进行以下更改才能正确实现运行时组合:

Node 必须有一个接受的构造函数``rclcpp::NodeOptions``:

class Listener: public rclcpp::Node {
  Listener(const rclcpp::NodeOptions & options)
  : Node("listener", options)
  {
  }
};

C++ 注册宏(如果存在)需要更新以使用 rclcpp_components 等效项。 如果不存在,则必须在一个翻译单元中添加注册宏。

// Insert at bottom of translation unit, e.g. listener.cpp
#include "rclcpp_components/register_node_macro.hpp"
// Use fully-qualifed name in registration
RCLCPP_COMPONENTS_REGISTER_NODE(composition::Listener);

CMake 注册宏(如果存在)需要更新。 如果不存在,则必须将注册宏添加到项目的 CMake。

add_library(listener src/listener.cpp)
rclcpp_components_register_nodes(listener "composition::Listener")

有关组合的更多信息,请参阅`教程 <../Tutorials/Intermediate/Writing-a-Composable-Node>`

rclpy

创建发布者、订阅和 QoS 配置文件的更改

在 Dashing 之前,您可以选择在创建发布者或订阅时提供 QoSProfile 对象。

为了鼓励用户指定消息队列的历史记录深度,我们现在**要求**在创建发布者或订阅时提供深度值或 QoSProfile 对象。

要创建发布者,以前您需要编写:

node.create_publisher(Empty, 'chatter')
# Or using a keyword argument for QoSProfile
node.create_publisher(Empty, 'chatter', qos_profile=qos_profile_sensor_data)

在 Dashing 中,优先使用以下 API,它提供深度值或“QoSProfile”对象作为第三个位置参数:

# Assume a history setting of KEEP_LAST with depth 10
node.create_publisher(Empty, 'chatter', 10)
# Or pass a QoSProfile object directly
node.create_publisher(Empty, 'chatter', qos_profile_sensor_data)

同样,对于订阅,以前你会这样写:

node.create_subscription(BasicTypes, 'chatter', lambda msg: print(msg))
# Or using a keyword argument for QoSProfile
node.create_subscription(BasicTypes, 'chatter', lambda msg: print(msg), qos_profile=qos_profile_sensor_data)

在 Dashing 中:

# Assume a history setting of KEEP_LAST with depth 10
node.create_subscription(BasicTypes, 'chatter', lambda msg: print(msg), 10)
# Or pass a QoSProfile object directly
node.create_subscription(BasicTypes, 'chatter', lambda msg: print(msg), qos_profile_sensor_data)

为了简化过渡,不使用新 API 的用户将看到弃用警告。

此外,我们还要求在构造“QoSProfile”对象时设置历史策略和/或深度。

如果提供了“KEEP_LAST”的历史策略,则还需要深度参数。 例如,这些调用是有效的:

QoSProfile(history=QoSHistoryPolicy.RMW_QOS_POLICY_HISTORY_KEEP_ALL)
QoSProfile(history=QoSHistoryPolicy.RMW_QOS_POLICY_HISTORY_KEEP_LAST, depth=10)
QoSProfile(depth=10)  # equivalent to the previous line

这些调用将导致弃用警告:

QoSProfile()
QoSProfile(reliability=QoSReliabilityPolicy.RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT)
# KEEP_LAST but no depth
QoSProfile(history=QoSHistoryPolicy.RMW_QOS_POLICY_HISTORY_KEEP_LAST)

有关更多详细信息,请参阅与引入此更改相关的问题和拉取请求:

由于声明参数更改而导致的更改

有关实际行为更改的详细信息,请参阅上面的`声明参数`_。这些更改类似于``rclcpp``中的更改。

这些是``rclpy.node.Node``接口中可用的新API方法:

  • 要声明给定名称、可选默认值(由``rcl_interfaces.msg.ParameterValue``支持)和可选描述符的参数,返回实际设置的值:

    def declare_parameter(
        name: str,
        value: Any = None,
        descriptor: ParameterDescriptor = ParameterDescriptor()
    ) -> Parameter
    
    def declare_parameters(
      namespace: str,
      parameters: List[Union[
          Tuple[str],
          Tuple[str, Any],
          Tuple[str, Any, ParameterDescriptor],
      ]]
    ) -> List[Parameter]
    
  • 取消声明先前声明的参数并检查参数是否已预先声明:

    def undeclare_parameter(name: str) -> None
    
    def has_parameter(name: str) -> bool
    
  • 获取和设置参数描述符:

    def describe_parameter(name: str) -> ParameterDescriptor
    
    def describe_parameters(names: List[str]) -> List[ParameterDescriptor]
    
    def set_descriptor(
        name: str,
        descriptor: ParameterDescriptor,
        alternative_value: Optional[ParameterValue] = None
    ) -> ParameterValue
    
  • 获取可能未声明的参数的便捷方法:

    def get_parameter_or(name: str, alternative_value: Optional[Parameter] = None) -> Parameter
    

其他更改

rclpy.parameter.Parameter 现在可以猜测其类型而无需明确设置它(只要它是 rcl_interfaces.msg.ParameterValue 支持的类型之一)。 例如,此代码:

p = Parameter('myparam', Parameter.Type.DOUBLE, 2.41)

相当于此代码:

p = Parameter('myparam', value=2.41)

此更改不会破坏现有 API。

rosidl

在 Crystal 之前,每个消息生成器包都使用 ament_cmake 扩展点 rosidl_generate_interfaces 注册自身,并传递一组 .msg / .srv / .action 文件。

从 Dashing 开始,消息生成管道基于 .idl 文件。

任何消息生成器包都需要更改并使用新的扩展点 rosidl_generate_idl_interfaces 注册自身,该扩展点仅传递 .idl 文件。 常用的 C、C++ 和 Python 语言的消息生成器以及用于 introspection、Fast RTPS、Connext 和 OpenSplice 的 typesupport 包已经更新(请参阅 ros2/rosidl#334)。 调用 rosidl_generate_interfaces() 的 CMake 代码可以直接传递 .idl 文件,也可以传递 .msg / .srv / .action,然后这些文件将在内部转换为 .idl 文件,然后再传递给每个消息生成器。

.msg / .srv / .action 文件的格式将来不会改进。 .msg / .srv / .action 文件和 .idl 文件之间的映射在 本设计文章 <https://design.ros2.org/articles/legacy_interface_definition.html>`__ 中描述。 ``第二篇设计文章 <https://design.ros2.org/articles/idl_interface_definition.html>`__ 描述了 ``.idl 文件中支持的功能。 为了利用任何新功能,需要转换现有接口(例如使用命令行工具 msg2idl / srv2idl / action2idl)。

为了区分相同类型名称但不同命名空间的情形,内省结构现在包含一个命名空间字段来替换包名称(请参阅 ros2/rosidl#335)。

.msg 文件中 char 的映射

ROS 1 中,char 已弃用很长时间,并被映射到 uint8。 在 ROS 2 中,直到 Crystal,char 被映射到单个字符(C/C++ 中为 char,Python 中长度为 1 的 str),以提供更自然的映射。 从 Dashing 开始,ROS 1 语义已恢复,并且 char 再次映射到 uint8

rosidl_generator_cpp

为消息、服务和操作生成的 C++ 数据结构为每个字段提供设置器方法。 直到 Crystal,每个设置器都返回一个指向数据结构本身的指针,以启用命名参数习语。 从 Dashing 开始,这些 setter 改为“返回引用 <https://github.com/ros2/rosidl/pull/353>” ,因为这似乎是更常见的签名,并且它明确表示返回的值不能是“nullptr”。

rosidl_generator_py

直到 Crystal 出现之前,消息中的数组(固定大小)或序列(动态大小,可选地具有上边界)字段在 Python 中都存储为“列表”。

从 Dashing 开始,数值数组/序列的 Python 类型已更改:

  • 数值数组存储为“numpy.ndarray”(选择“dtype”以匹配数值类型)

  • 数值序列存储为“array.array”(选择“typename”以匹配数值类型)

与以前一样,非数值类型的数组/序列在 Python 中仍然表示为“列表”。

这一变化带来了许多好处:

  • 新的数据结构确保数组/序列中的每个项目都符合数值类型的值范围限制。

  • 数值可以更有效地存储在内存中,从而避免每个项目的 Python 对象开销。

  • 两种数据结构的内存布局允许在单个操作中读取和写入数组/序列的所有项,这使得从 Python 到 Python 的转换速度明显更快/更高效。

启动

launch_testing 包赶上了 Bouncy Bolson 中对 launch 包的重新设计。

旧版 Python API 已移至 launch.legacy 子模块,因此已被弃用并删除。

有关如何使用其新 API 的参考,请参阅 launch examplesdocumentation

有关如何使用新 launch_testing API 的参考,请参阅 demos tests

rmw

Crystal Clemmys 发布以来的变化:

请注意,此参数可以是 NULLnullptr,以保留现有的 Crystal 行为。

  • rmw_publish

  • rmw_take

  • rmw_get_*_names_and_types* 函数返回的类型名称应具有完全限定的命名空间。

例如,返回的类型名称应为“rcl_interface/msg/Parameter”和“rcl_interfaces/srv/GetParameters”,而不是“rcl_interfaces/Parameter”和“rcl_interfaces/GetParameters”。

操作

现在,用户可以使用新的

SendGoalOptions struct. 当操作服务器接受或拒绝目标时,将调用目标响应回调,当收到目标结果时,将调用结果回调。 可选回调也已添加到 rclcpp_action::Client::async_cancel_goalrclcpp_action ::Client::async_get_result.

  • 目标转换名称更改:

    目标状态转换的名称已重构以反映设计文档。 这会影响“rcl_action”、“rclcpp_action”和“rclpy”。 以下是事件名称更改的列表(旧名称 -> 新名称):

    • GOAL_EVENT_CANCEL -> GOAL_EVENT_CANCEL_GOAL

    • GOAL_EVENT_SET_SUCCEEDED -> GOAL_EVENT_SUCCEED

    • GOAL_EVENT_SET_ABORTED -> GOAL_EVENT_ABORT

    • GOAL_EVENT_SET_CANCELED -> GOAL_EVENT_CANCELED

  • 对“CancelGoal.srv”的更改:

在“CancelGoal”服务的响应消息中添加了“return_code”字段。 这是为了更好地传达服务调用失败的原因。 有关详细信息,请参阅“pull 请求 <https://github.com/ros2/rcl_interfaces/pull/76>”和相关问题。

rviz

  • 插件应使用完全限定的类型名称,否则将记录警告。

例如 <https://github.com/ros2/rviz/blob/dfceae319d49546f1e4ad39689853c18fef0001e/rviz_default_plugins/plugins_description.xml#L13>`_,使用类型 sensor_msgs/msg/Image 而不是 sensor_msgs/Image。 有关更多详细信息,请参阅 PR 介绍此更改

已知问题

  • [ros2/rclcpp#715] 独立 ROS 2 节点和组合 ROS 2 节点之间加载参数 YAML 文件的方式不一致。

当前可用的解决方法在 issue comment * [ros2/rclpy#360] 在 Windows 上使用 OpenSplice 时,rclpy 节点会忽略 ctrl-c。 * `[ros2/rosidl_typesupport_opensplice#30] ​​<https://github.com/ros2/rosidl_typesupport_opensplice/issues/30>`_ 使用 OpenSplice 时,存在一个错误,导致无法在同名的服务或操作定义中嵌套消息。 * [ros2/rclcpp#781]on_set_parameter_callback 中调用 get_parameter/list_parameter 会导致 Dashing 死锁。此问题已针对 Eloquent 进行了修复,但属于 ABI 中断,因此尚未移植到 Dashing。 * [ros2/rclcpp#912]std::unique_ptr 发布者和单个 std::unique_ptr 订阅(已发布的 std::unique_ptr 在内部被提升为 std::shared_ptr)之间发生进程内通信时,进程间通信会强制进行消息复制。 * [ros2/rosbag2#125] 不记录 QOS 不可靠的主题。 * [ros2/rclcpp#715] 可组合节点无法通过重新映射接收参数。可以使用 [此评论] 中描述的方法向可组合节点提供参数。 * [ros2/rclcpp#893] rclcpp::Context 由于 rclcpp::GraphListener 的引用循环而被销毁。这会导致内存泄漏。由于存在破坏 ABI 的风险,因此尚未反向移植修复程序。

发布前的时间线

发布前的几个里程碑:

Mon. Apr 8th (alpha)

First releases of core packages available. Testing can happen from now on (some features might not have landed yet).

Thu. May 2nd

API freeze for core packages

Mon. May 6th (beta)

Updated releases of core packages available. Additional testing of the latest features.

Thu. May 16th

Feature freeze. Only bug fix releases should be made after this point. New packages can be released independently.

Mon. May 20th (release candidate)

Updated releases of core packages available.

Wed. May 29th

Freeze rosdistro. No PRs for Dashing on the rosdistro repo will be merged (reopens after the release announcement).