Dashing Diademata (dashing
)
Dashing Diademata is the fourth release of ROS 2.
支持的平台
Dashing Diademata 主要支持以下平台:
一级平台:
Ubuntu 18.04 (Bionic):
amd64
andarm64
Mac macOS 10.12 (Sierra)
Windows 10 (Visual Studio 2019)
二级平台:
Ubuntu 18.04 (Bionic):
arm32
三级平台:
Debian Stretch (9):
amd64
,arm64
andarm32
OpenEmbedded Thud (2.6) / webOS OSE:
arm32
andx86
有关 RMW 实现、编译器/解释器版本和系统依赖项版本的更多信息,请参阅 REP 2000。
安装
此 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>`__)。
* 与 actions
和 components
相关的命令行工具。
* 支持 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_parameters
选项来恢复旧行为(大多数情况下,请参阅下一段中的注释)。
您可能希望这样做以避免暂时更改代码,或者为了满足一些不常见的用例。
例如,“全局参数服务器”或“参数黑板”可能希望允许外部节点在不先声明新参数的情况下自行设置新参数,因此它可以使用 allow_undeclared_parameters
选项来实现这一点。
但是,在大多数情况下,不建议使用此选项,因为它会使其余参数 API 不太安全,容易出现参数名称拼写错误和“设置前使用”逻辑错误等错误。
请注意,使用 allow_undeclared_parameters
将使您获得大多数旧行为,特别是针对“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”消息的链接:
使用 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::PublisherOptions
和rclcpp::SubscriptionOptions
。
所有变更都向后兼容(无需更改代码),但已弃用几种现有的调用样式。
鼓励用户更新到新签名。
过去,在创建发布者或订阅时,您可以不指定任何 QoS 设置(例如,只提供发布者的主题名称),也可以指定“qos 配置文件”数据结构(类型为 rmw_qos_profile_t
),其中已设置所有设置。
现在,您必须使用新的 rclcpp::QoS
对象来指定您的 QoS 以及至少 QoS 的历史记录设置。
这鼓励用户在使用 KEEP_LAST
时指定历史记录深度,而不是将其默认为可能合适也可能不合适的值。
在 ROS 1 中,这被称为 queue_size
,它在 C++ 和 Python 中都是必需的。
我们正在更改 ROS 2 API 以恢复此要求。
此外,以前在创建发布者或订阅时可以传递的任何选项现在分别封装在 rclcpp::PublisherOptions
和 rclcpp::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
examples 和 documentation。
有关如何使用新 launch_testing
API 的参考,请参阅 demos tests。
rmw
自 Crystal Clemmys 发布以来的变化:
rmw
中的新 API,rmw_context_t
的 fini 函数:修改
rmw
,现在将rmw_context_t
传递给rmw_create_wait_set
:rmw
中用于预分配已发布和订阅消息空间的新 API:修改
rmw
,现在将rmw_publisher_allocation_t
或rmw_subscription_allocation_t
分别传递给rmw_publish
和rmw_take
。
请注意,此参数可以是 NULL
或 nullptr
,以保留现有的 Crystal 行为。
rmw_get_*_names_and_types*
函数返回的类型名称应具有完全限定的命名空间。
例如,返回的类型名称应为“rcl_interface/msg/Parameter”和“rcl_interfaces/srv/GetParameters”,而不是“rcl_interfaces/Parameter”和“rcl_interfaces/GetParameters”。
操作
对“rclcpp_action::Client”签名的更改: rclcpp_action::Client::async_send_goal 的签名 已改变。
现在,用户可以使用新的
SendGoalOptions struct. 当操作服务器接受或拒绝目标时,将调用目标响应回调,当收到目标结果时,将调用结果回调。 可选回调也已添加到 rclcpp_action::Client::async_cancel_goal 和 rclcpp_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).