转换插件开发
转换插件用于在不同的存储序列化格式之间进行转换。 ROS 2 中 rosbag 的录制数据以某种序列化格式获取并存储。 默认情况下,bag 以录制时所用中间件的序列化格式存储(不同中间件可能共享同一种序列化格式)。 如果消息需要由使用不同序列化格式的中间件读取,就必须先转换为对应格式。 为了简化所有格式之间的转换,每个插件只需实现自定义格式与通用 ROS 2 消息表示之间的双向转换即可。
Rosbag2 自带一个默认的转换插件,用于在 ROS 2 消息和 CDR 格式的序列化消息之间转换(CDR 是 DDS 定义的通用序列化格式)。
编写同时支持序列化和反序列化的转换插件
Section titled “编写同时支持序列化和反序列化的转换插件”大多数转换插件需要在自定义序列化格式与 ROS 2 消息之间进行双向转换,即序列化和反序列化。
要编写一个支持与自定义序列化格式双向转换的插件 MyConverter,需实现接口 rosbag2_cpp::converter_interfaces::SerializationFormatConverter。
插件接口提供两个函数:
serialize函数接收一个已初始化的 SerializedBagMessage 和一个 ROS 2 消息,以及话题和类型信息,然后用 ROS 2 消息内容填充 SerializedBagMessage。deserialize函数执行相反的操作,接收一个完整的 SerializedBagMessage,用提供的 typesupport(必须与 SerializedBagMessage 的实际类型匹配)填充一个预分配的 ROS 2 消息。
要在运行时被发现,插件需要导出到 pluginlib。
在 my_converter.cpp 中添加以下行:
#include "pluginlib/class_list_macros.hpp"PLUGINLIB_EXPORT_CLASS(MyConverter, rosbag2_cpp::converter_interfaces::SerializationFormatConverter)此外,还需要一个 plugin_description.xml 文件来提供元信息。
对于 MyConverter,该文件内容如下:
<library path="my_converter_library"> <class name="my_storage_format_converter" type="MyConverter" base_class_type="rosbag2_cpp::converter_interfaces::SerializationFormatConverter" > <description>This is a converter plugin for my storage format.</description> </class></library>其中 my_converter_library 是库的名称,my_storage_format_converter 是 pluginlib 加载它时使用的标识符。
它必须采用 <rmw storage format>_converter 的格式,如”如何在运行时选择转换”一节所述。
此外,在 CMakeLists.txt 中,需要将 plugin_description.xml 添加到 ament index,以便运行时能发现该插件:
pluginlib_export_plugin_description_file(rosbag2_cpp plugin_description.xml)第一个参数 rosbag2_cpp 表示向哪个 ament index 键添加插件(对转换插件来说,它永远是 rosbag2_cpp),第二个参数是插件描述文件的路径。
编写仅支持序列化或仅支持反序列化的转换插件
Section titled “编写仅支持序列化或仅支持反序列化的转换插件”可以编写只支持转换到自定义序列化格式、或只支持从自定义序列化格式转换的插件。 例如,用于旧版 ROS 1 rosbag 的默认插件只支持从 ROS 1 消息格式反序列化为 ROS 2 消息格式,因为 rosbag2 并不打算以旧格式写入 rosbag。 在类似的使用场景中,可以提供只支持单方向(序列化或反序列化)的插件。
要编写一个支持从自定义序列化格式转换的插件 MyDeserializer,需实现接口 rosbag2_cpp::converter_interfaces::SerializationFormatDeserializer。
该接口只提供上面提到的 deserialize 方法。
类似地,序列化插件对应接口 rosbag2_cpp::converter_interfaces::SerializationFormatSerializer。
如何在运行时选择转换
Section titled “如何在运行时选择转换”转换会根据 bag 文件中指定的存储格式或用户指定的格式自动选择。
为了实现这一点,rosbag2 会搜索名为 <storage format>_converter 的转换插件。
例如,用于 CDR 消息间转换的默认插件在其 pluginlib.txt 文件中命名为 cdr_converter。
同一存储格式不需要不同的转换器,因此不支持这种情况。