forked from ros2/rclcpp
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
initial version of plugin based storage api (ros2#7)
* initial version of plugin based storage api * Add readable and writable storage interfaces * Fix build and uncrustify * Delete first storage interface proposal and adapt storage factory to new one * Modify test to work with new storage interfaces * Adapt sqlite3 plugin to new interface and extract rosbag2 part to own project * Adapt read() and write() methods signature * Prevent pluginlib from using boost * Add plugin development documentation * Remove Sqlite dependencies from rosbag2 tests * Add tests to rosbag2_storage_default_plugins * Add visibility control for Windows in rosbag_storage * Rename visibility_control.h to visibility_control.hpp * Cleanup CMakeLists in rosbag2_storage * Use void * instead of char * in rosbag_storage * Update plugin_description.xml and write() method * Introduce better logging using rcutils in rosbag_storage * Adapt interface and introduce better logging * Fix package.xml in rosbag2_storage * Add storage facade for plugins which are both readable and writable * Extract bag_info struct to own file * Change storage interface to have read/write access * Adapt copyright and use copyright linter * rosbag2 serialized message * remove colcon ignores * Add visibility to template specializations * Remove no longer necessary File install from CMakeLists.txt * Refactor storage_factory_impl.hpp * Minor refactoring * Add COLCON_IGNORE files to irrelevant projects * Fix Windows warning * Simpler class hierarchy without WritableStorage * Use exceptions instead of bool returns everywhere in interface * Change rosbag2_storage interface * storage interfaces * linters * a bit of refactoring * expose opening and closing * take messages as shared ptr * linters * rename to open, unique_ptr for pimpl * remove obsolete api * comply with new interfaces * change templated open to explicit open_ro and open_rw * Delete superfluous classes + polishing * Adapt SerializedBagMessage format * Let sqlite3 storage use new interface * Fix tests in rosbag2 * Write and read only data * Replace creation of shared instance by unmanaged instance * Add pragma for windows * Add visibility control for Windows * Expose template definitions * Move const to better location * Replace strcpy * Delete superfluous methods * Use visibility control in rosbag2 * Minor cleanup * test for nullptr when opening storage
- Loading branch information
1 parent
2d3bcdb
commit 05d24c8
Showing
61 changed files
with
2,121 additions
and
976 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# Writing storage plugins | ||
|
||
There are different interfaces for storage plugins depending on your need: The general `ReadWriteStorage` and the more specific `ReadableStorage`. | ||
|
||
## Writing a general plugin | ||
|
||
Assume you write a plugin `MyStorage` which can both save messages and read messages. | ||
Its header file could be `my_storage.hpp` and it would derive from `rosbag2_storage::ReadWriteStorage`. | ||
While implementing the interface provided by `rosbag2_storage::ReadWriteStorage`, make sure that all resources such as file handles or database connections are closed or destroyed in the destructor, no additional `close` call should be necessary. | ||
|
||
In order to find the plugin at runtime, it needs to be exported to the pluginlib. | ||
Add the following lines to `my_storage.cpp`: | ||
|
||
``` | ||
#include "pluginlib/class_list_macros.hpp" | ||
PLUGINLIB_EXPORT_CLASS(MyStorage, rosbag2_storage::ReadWriteStorage) | ||
``` | ||
|
||
Furthermore, we need some meta-information in the form of a `plugin_description.xml` file. | ||
Here, it contains | ||
|
||
``` | ||
<library path="my_storage_lib"> | ||
<class name="my_storage" type="MyStorage" base_class_type="rosbag2_storage::ReadWriteStorage"> | ||
</class> | ||
</library> | ||
``` | ||
Here, `my_storage_lib` is the name of the library while `my_storage` is an identifier used by the pluginlib to load it. | ||
|
||
In addition, in the `CMakeLists.txt` plugins and `plugin_description` file need to be added to the index to be found at runtime: | ||
|
||
`pluginlib_export_plugin_description_file(rosbag2_storage plugin_description.xml)` | ||
|
||
The first argument `rosbag2_storage` denotes the library we add our plugin to, while the second argument is the path to the plugin description file. | ||
|
||
## Writing a plugin for reading only | ||
|
||
When writing plugins to only provide functionality for reading, derive from `rosbag2_storage::ReadableStorage`. | ||
|
||
If the read-only plugin is called `my_readonly_storage` in a library `my_storage_lib`, it will be registered using | ||
|
||
``` | ||
#include "pluginlib/class_list_macros.hpp" | ||
PLUGINLIB_EXPORT_CLASS(MyReadonlyStorage, rosbag2_storage::ReadableStorage) | ||
``` | ||
with the plugin description | ||
``` | ||
<library path="my_storage_lib"> | ||
<class name="my_readonly_storage" type="MyReadonlyStorage" base_class_type="rosbag2_storage::ReadableStorage"> | ||
</class> | ||
</library> | ||
``` | ||
and the usual pluginlib export in the CMakeLists: | ||
|
||
`pluginlib_export_plugin_description_file(rosbag2_storage plugin_description.xml)` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// Copyright 2018, Bosch Software Innovations GmbH. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
#ifndef ROSBAG2__ROSBAG2_HPP_ | ||
#define ROSBAG2__ROSBAG2_HPP_ | ||
|
||
#include <functional> | ||
#include <string> | ||
|
||
#include "rosbag2/visibility_control.hpp" | ||
|
||
namespace rosbag2 | ||
{ | ||
|
||
class Rosbag2 | ||
{ | ||
public: | ||
ROSBAG2_PUBLIC | ||
void record( | ||
const std::string & file_name, | ||
const std::string & topic_name, | ||
std::function<void(void)> after_write_action = nullptr); | ||
|
||
ROSBAG2_PUBLIC | ||
void play(const std::string & file_name, const std::string & topic_name); | ||
}; | ||
|
||
} // namespace rosbag2 | ||
|
||
#endif // ROSBAG2__ROSBAG2_HPP_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// Copyright 2018, Bosch Software Innovations GmbH. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
#include "rclcpp/rclcpp.hpp" | ||
|
||
#include "rosbag2/rosbag2.hpp" | ||
|
||
int main(int argc, const char ** argv) | ||
{ | ||
rclcpp::init(argc, argv); | ||
|
||
rosbag2::Rosbag2 rosbag2; | ||
rosbag2.play("test.bag", "string_topic"); | ||
|
||
rclcpp::shutdown(); | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// Copyright 2018, Bosch Software Innovations GmbH. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
#include <cstdio> | ||
#include <string> | ||
|
||
#include "rclcpp/rclcpp.hpp" | ||
|
||
#include "rosbag2/rosbag2.hpp" | ||
|
||
int main(int argc, const char ** argv) | ||
{ | ||
// TODO(anhosi): allow output file to be specified by cli argument and do proper checking if | ||
// file already exists | ||
std::string filename("test.bag"); | ||
std::remove(filename.c_str()); | ||
|
||
rclcpp::init(argc, argv); | ||
|
||
rosbag2::Rosbag2 rosbag2; | ||
rosbag2.record(filename, "string_topic"); | ||
|
||
rclcpp::shutdown(); | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
// Copyright 2018, Bosch Software Innovations GmbH. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
#include "rosbag2/rosbag2.hpp" | ||
|
||
#include <memory> | ||
#include <string> | ||
|
||
#include "rclcpp/rclcpp.hpp" | ||
|
||
#include "rcutils/logging_macros.h" | ||
|
||
#include "std_msgs/msg/string.hpp" | ||
|
||
#include "rosbag2_storage/serialized_bag_message.hpp" | ||
#include "rosbag2_storage/storage_interfaces/read_only_interface.hpp" | ||
#include "rosbag2_storage/storage_interfaces/read_write_interface.hpp" | ||
#include "rosbag2_storage/storage_factory.hpp" | ||
|
||
namespace rosbag2 | ||
{ | ||
|
||
const char * ROS_PACKAGE_NAME = "rosbag2"; | ||
|
||
void Rosbag2::record( | ||
const std::string & file_name, | ||
const std::string & topic_name, | ||
std::function<void(void)> after_write_action) | ||
{ | ||
rosbag2_storage::StorageFactory factory; | ||
auto storage = | ||
factory.open_read_write(file_name, "sqlite3"); | ||
storage->create_topic(); | ||
|
||
if (storage) { | ||
auto node = std::make_shared<rclcpp::Node>("rosbag_node"); | ||
auto subscription = node->create_subscription<std_msgs::msg::String>( | ||
topic_name, | ||
[&storage, after_write_action](std::shared_ptr<rmw_serialized_message_t> msg) { | ||
auto bag_msg = std::make_shared<rosbag2_storage::SerializedBagMessage>(); | ||
bag_msg->serialized_data = msg; | ||
storage->write(bag_msg); | ||
if (after_write_action) { | ||
after_write_action(); | ||
} | ||
}); | ||
|
||
RCUTILS_LOG_INFO_NAMED(ROS_PACKAGE_NAME, "Waiting for messages..."); | ||
rclcpp::spin(node); | ||
} | ||
} | ||
|
||
void Rosbag2::play(const std::string & file_name, const std::string & topic_name) | ||
{ | ||
rosbag2_storage::StorageFactory factory; | ||
auto storage = | ||
factory.open_read_only(file_name, "sqlite3"); | ||
|
||
if (storage) { | ||
auto node = std::make_shared<rclcpp::Node>("rosbag_publisher_node"); | ||
auto publisher = node->create_publisher<std_msgs::msg::String>(topic_name); | ||
while (storage->has_next()) { | ||
auto message = storage->read_next(); | ||
|
||
std_msgs::msg::String string_message; | ||
// TODO(Martin-Idel-SI): We don't write a correct serialized_data in sqlite3_storage for now | ||
// Change once available | ||
string_message.data = std::string(message->serialized_data->buffer); | ||
// without the sleep_for() many messages are lost. | ||
std::this_thread::sleep_for(std::chrono::milliseconds(500)); | ||
publisher->publish(string_message); | ||
} | ||
} | ||
} | ||
|
||
} // namespace rosbag2 |
Oops, something went wrong.