diff --git a/rosbag2_examples/rosbag2_examples_cpp/CMakeLists.txt b/rosbag2_examples/rosbag2_examples_cpp/CMakeLists.txt index 3e68057661..bbc9b484d6 100644 --- a/rosbag2_examples/rosbag2_examples_cpp/CMakeLists.txt +++ b/rosbag2_examples/rosbag2_examples_cpp/CMakeLists.txt @@ -20,6 +20,7 @@ endif() find_package(ament_cmake REQUIRED) find_package(rclcpp REQUIRED) find_package(rosbag2_cpp REQUIRED) +find_package(rosbag2_transport REQUIRED) find_package(example_interfaces REQUIRED) add_executable(simple_bag_recorder src/simple_bag_recorder.cpp) @@ -34,6 +35,19 @@ install(TARGETS DESTINATION lib/${PROJECT_NAME} ) +add_executable(simple_bag_reader src/simple_bag_reader.cpp) +target_link_libraries(simple_bag_reader + rclcpp::rclcpp + rosbag2_cpp::rosbag2_cpp + rosbag2_transport::rosbag2_transport + ${example_interfaces_TARGETS} +) + +install(TARGETS + simple_bag_reader + DESTINATION lib/${PROJECT_NAME} +) + add_executable(data_generator_node src/data_generator_node.cpp) target_link_libraries(data_generator_node rclcpp::rclcpp diff --git a/rosbag2_examples/rosbag2_examples_cpp/package.xml b/rosbag2_examples/rosbag2_examples_cpp/package.xml index 5b18096ea0..8ade5e5162 100644 --- a/rosbag2_examples/rosbag2_examples_cpp/package.xml +++ b/rosbag2_examples/rosbag2_examples_cpp/package.xml @@ -13,6 +13,7 @@ rclcpp rosbag2_cpp + rosbag2_transport example_interfaces ament_lint_auto diff --git a/rosbag2_examples/rosbag2_examples_cpp/src/simple_bag_reader.cpp b/rosbag2_examples/rosbag2_examples_cpp/src/simple_bag_reader.cpp new file mode 100644 index 0000000000..bf44e229a1 --- /dev/null +++ b/rosbag2_examples/rosbag2_examples_cpp/src/simple_bag_reader.cpp @@ -0,0 +1,80 @@ +// Copyright 2024 Sony Group Corporation. +// +// 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 +#include +#include +#include +#include + +#include "example_interfaces/msg/string.hpp" + +#include "rclcpp/rclcpp.hpp" +#include "rclcpp/serialization.hpp" +#include "rosbag2_transport/reader_writer_factory.hpp" + +using namespace std::chrono_literals; + +class SimpleBagReader : public rclcpp::Node +{ +public: + explicit SimpleBagReader(const std::string & bag_filename) + : Node("simple_bag_reader") + { + publisher_ = this->create_generic_publisher( + "chatter", "example_interfaces/msg/String", 10); + + timer_ = this->create_wall_timer( + 100ms, + [this]() {return this->timer_callback();} + ); + + rosbag2_storage::StorageOptions storage_options; + storage_options.uri = bag_filename; + reader_ = rosbag2_transport::ReaderWriterFactory::make_reader(storage_options); + reader_->open(storage_options); + } + +private: + void timer_callback() + { + while (reader_->has_next()) { + rosbag2_storage::SerializedBagMessageSharedPtr msg = reader_->read_next(); + + if (msg->topic_name != "chatter") { + continue; + } + rclcpp::SerializedMessage serialized_msg(*msg->serialized_data); + std::cout << "Publish serialized data to " << msg->topic_name << ".\n"; + publisher_->publish(serialized_msg); + break; + } + } + rclcpp::TimerBase::SharedPtr timer_; + std::shared_ptr publisher_; + + std::unique_ptr reader_; +}; + +int main(int argc, char ** argv) +{ + if (argc != 2) { + std::cerr << "Usage: " << argv[0] << " " << std::endl; + return 1; + } + rclcpp::init(argc, argv); + rclcpp::spin(std::make_shared(argv[1])); + rclcpp::shutdown(); + return 0; +} diff --git a/rosbag2_examples/rosbag2_examples_py/rosbag2_examples_py/simple_bag_reader.py b/rosbag2_examples/rosbag2_examples_py/rosbag2_examples_py/simple_bag_reader.py new file mode 100644 index 0000000000..e4f7d0a629 --- /dev/null +++ b/rosbag2_examples/rosbag2_examples_py/rosbag2_examples_py/simple_bag_reader.py @@ -0,0 +1,58 @@ +# Copyright 2024 Sony Group Corporation. +# +# 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. +import sys + +import rclpy +from rclpy.executors import ExternalShutdownException +from rclpy.node import Node +import rosbag2_py +from std_msgs.msg import String + + +class SimpleBagReader(Node): + + def __init__(self, bag_filename): + super().__init__('simple_bag_reader') + self.reader = rosbag2_py.SequentialReader() + storage_options = rosbag2_py._storage.StorageOptions( + uri=bag_filename, + storage_id='sqlite3') + converter_options = rosbag2_py._storage.ConverterOptions('', '') + self.reader.open(storage_options, converter_options) + + self.publisher = self.create_publisher(String, 'chatter', 10) + self.timer = self.create_timer(0.1, self.timer_callback) + + def timer_callback(self): + while self.reader.has_next(): + msg = self.reader.read_next() + if msg[0] != 'chatter': + continue + self.publisher.publish(msg[1]) + self.get_logger().info('Publish serialized data to ' + msg[0]) + + +def main(args=None): + rclpy.init(args=args) + try: + sbr = SimpleBagReader(sys.argv[1]) + rclpy.spin(sbr) + except KeyboardInterrupt: + pass + except ExternalShutdownException: + rclpy.shutdown() + + +if __name__ == '__main__': + main() diff --git a/rosbag2_examples/rosbag2_examples_py/rosbag2_examples_py/simple_bag_recorder.py b/rosbag2_examples/rosbag2_examples_py/rosbag2_examples_py/simple_bag_recorder.py index 7890d69887..7187f1c09d 100644 --- a/rosbag2_examples/rosbag2_examples_py/rosbag2_examples_py/simple_bag_recorder.py +++ b/rosbag2_examples/rosbag2_examples_py/rosbag2_examples_py/simple_bag_recorder.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. import rclpy +from rclpy.executors import ExternalShutdownException from rclpy.node import Node from rclpy.serialization import serialize_message import rosbag2_py @@ -53,9 +54,13 @@ def topic_callback(self, msg): def main(args=None): rclpy.init(args=args) - sbr = SimpleBagRecorder() - rclpy.spin(sbr) - rclpy.shutdown() + try: + sbr = SimpleBagRecorder() + rclpy.spin(sbr) + except KeyboardInterrupt: + pass + except ExternalShutdownException: + rclpy.shutdown() if __name__ == '__main__': diff --git a/rosbag2_examples/rosbag2_examples_py/setup.py b/rosbag2_examples/rosbag2_examples_py/setup.py index 10ef1119cb..5379a11b42 100644 --- a/rosbag2_examples/rosbag2_examples_py/setup.py +++ b/rosbag2_examples/rosbag2_examples_py/setup.py @@ -21,6 +21,7 @@ entry_points={ 'console_scripts': [ 'simple_bag_recorder = rosbag2_examples_py.simple_bag_recorder:main', + 'simple_bag_reader = rosbag2_examples_py.simple_bag_reader:main', 'data_generator_node = rosbag2_examples_py.data_generator_node:main', 'data_generator_executable = rosbag2_examples_py.data_generator_executable:main', ],