A rosbag2 recorder node that backs up split files to an external location during recording

System Data Recorder (SDR)

A lifecycle node and executable for recording topic data to a rosbag2 bag, while simultaneously copying the split bag files to another location as each bag file is completed. This is useful, for example, to copy bag data files to an external disc during recording as each data file is completed, rather than waiting until all data is recorded before copying the entire bag at once (an operation that can take a significant time if the bag is large).

The copying function requires that a maximum file size for bag files be enabled. Otherwise no splitting will be performed and the files will not be copied until recording is terminated.

Compilation

The SDR requires two features not yet available in the rosbag2 main branch or binary releases. You will need to compile rosbag2 from source, applying the following two pull requests to the source prior to compiling it.

  1. Expose the QoS object wrapper
  2. Notification of significant events during bag recording and playback

Create a colcon workspace with the SDR source code in it, and compile the workspace.

Use

Lifecycle management

Run the executable to start the node.

ros2 run system_data_recorder system_data_recorder

In a separate terminal, use the lifecycle manager to configure and activate the node.

ros2 lifecycle set sdr configure
ros2 lifecycle set sdr activate

This will enable recording of data to the bag. To pause recording, deactivate the node.

ros2 lifecycle set sdr deactivate

From here, recording can be resumed by re-activating the node, or recording can be terminated by cleaning up the node.

ros2 lifecycle set sdr cleanup

Once cleaned up, the node will copy the final files of the bag, as well as any metadata, to the backup destination.

Configuring

The SDR is configured by the arguments passed to the node's constructor. These are not currently exposed as command line arguments or ROS parameters, so they must be changed in the source code. See the constructor's documentation block for the possible parameters.

By default, the SDR will:

  • Record from the /chatter topic, expecting std_msgs/msg/String data.
  • Record to a bag named test_bag.
  • Copy bag files to the directory copied_bag/test_bag.
  • Split bag files every 100,000 bytes.

A simple test

In one terminal, start publishing data on the /chatter topic.

ros2 run demo_nodes_cpp talker

In another terminal, start the SDR node.

ros2 run system_data_recorder system_data_recorder

In a third terminal, configure and activate the SDR.

ros2 lifecycle set sdr configure
ros2 lifecycle set sdr activate

Wait a minute or two for 100,000 bytes of data to be recorded. Navigate to the directory copied_bag and observe that there is a test_bag directory containing the first data file of the bag.

Deactivate and cleanup the SDR.

ros2 lifecycle set sdr deactivate
ros2 lifecycle set sdr cleanup

Again navigate to the copied_bag directory, and observe that the test_bag directory now contains all the data files of the bag, and a metadata.yaml file.

This is a complete, usable bag. This can be demonstrated by stopping the talker node, then starting the listener node and playing the bag file.

ros2 run demo_nodes_cpp listener
ros2 bag play copied_bag/test_bag

The recorded data will be echoed by the listener node.

Lifecycle transition behaviours

on_configure

In the on_configure state, the node sets up the rosbag2 infrastructure for recording by creating a writer and opening the storage. It also sets up the worker thread that will copy files in parallel to the recording of data. A callback is registered with the writer so that the node will get informed each time a new file is created in the bag.

on_activate

In the on_activate transition, the node simply notifies the worker thread that it is recording. Data will be written to the bag automatically because the state changes to Active.

on_deactivate

In the on_deactivate transition, the node simply notifies the worker thread that it is paused. Data will not be written to the bag because the state changes to Inactive.

on_cleanup

When cleaning up, the node needs to stop recording, stop receiving data (i.e. unsubscribe from topics), and ensure that the final files of the bag (the last data file and the metadata file, which gets written when the writer object destructs) are copied to the destination directory.

on_shutdown

If not already performed, the shutdown transition performs the same functions as the cleanup transition.

Similar Resources

Monitor based on perf_event: split-lock, irq-off, profile, task-state, watchdog, kmemleak, kvm-exit, mpdelay

基于perf的监控框架 基于libperf和libtraceevent库实现简单的监控框架,提供比perf更灵活的特性。 数据不落盘。 数据过滤,基于tracepoint的过滤机制,减少数据量。 数据实时处理并输出。不需要存盘后再处理。 基于perf_event_open系统调用。 虽然比perf更

Dec 20, 2022

A split-screen menu page

A split-screen menu page

split_screen_menu A split-screen menu page Getting Started ###isMobileLayout retun bool SplitScreenMenu menu Widget initialRoute String? initPage Widg

Feb 19, 2022

GlueGD is a mod loader for Geometry Dash that does not require a modification to any existing Geometry Dash files or an external injector or launcher.

GlueGD is a mod loader for Geometry Dash that does not require a modification to any existing Geometry Dash files or an external injector or la

Apr 10, 2022

recording OSC messages with ofxPubSubOsc

ofxRecordOsc recording OSC with ofxPubSubOsc. Dependencies ofxOsc ofxPubSubOsc 0.3.2- Notice if you got error on ofx::RecordOsc::Player::play, please

Nov 21, 2021

ebpf syscall recording demo project

ebpf syscall recording demo project

Jun 7, 2022

A GPS bicycle speedometer that supports offline maps and track recording

A GPS bicycle speedometer that supports offline maps and track recording

X-TRACK 开源GPS自行车码表。 拥有可显示实时位置的离线地图。 支持记录和显示实时轨迹以及导出标准GPX格式的轨迹文件。 全新设计的"页面生命周期管理"和"消息订阅发布框架"。 演示视频:https://www.bilibili.com/video/BV1GB4y1K7VV GUI LVGL

Jan 3, 2023

Bank Management System is based on a concept of recording customer’s account details

Bank Management System is based on a concept of recording customer’s account details. Here the user can perform all the tasks like creating an account, deposit amount, withdraw amount, check balance, view all account holders detail, close an account and modify an account. There’s no login system for this project. All the main features for banking system are set in this project.

Feb 12, 2022

A refactored Proof-of-concept originally developed in 2017 to print all function calls with their arguments data types and values using Ptrace during program execution.

print-function-args-debugger A refactored Proof-of-concept originally developed in 2017 to print all function calls with their arguments data types an

Jun 17, 2022

An App created during the hackaTum 2021

An App created during the hackaTum 2021

FlowingBlue A project created in 36 hours for the HackaTUM Hackathon. Created By Mohamed Dhia Nouri: @theKooker Dylan Alyandi: @WoodRawr Alexander Hof

Nov 21, 2021
Comments
  • Making SDR compatible with latest rolling branch rosbag2 api

    Making SDR compatible with latest rolling branch rosbag2 api

    SDR currently references a WriteSplitInfo struct in the rosbag2 library, which has since been renamed to BagSplitInfo on the rolling and main branch of rosbag2.

    I was able to get SDR building recording successfully with this change

    [email protected] ~ $ ros2 run system_data_recorder system_data_recorder
    [INFO] [1659029476.584931608] [sdr]: Preparing to begin recording
    [INFO] [1659029476.585102157] [sdr]: Copying bag files to copied_bag/test_bag
    [INFO] [1659029476.585198133] [sdr]: Creating destination directory copied_bag/test_bag
    [INFO] [1659029476.585496439] [sdr]: Copy thread: Starting
    [INFO] [1659029476.611364364] [rosbag2_storage]: Opened database 'test_bag/test_bag_0.db3' for READ_WRITE.
    [INFO] [1659029476.616457519] [sdr]: Subscribed to topic '/chatter'
    [INFO] [1659029487.841847194] [sdr]: Starting recording
    [INFO] [1659029688.142586287] [sdr]: Pausing recording
    [INFO] [1659029695.752533597] [sdr]: Stopping and finalising recording
    [INFO] [1659029695.753182777] [rosbag2_cpp]: Writing remaining messages from cache to the bag. It may take a while
    [INFO] [1659029695.754422044] [sdr]: Copying test_bag/test_bag_0.db3 to copied_bag/test_bag
    [INFO] [1659029695.754532109] [sdr]: Copying test_bag/metadata.yaml to copied_bag/test_bag
    [INFO] [1659029695.754580171] [sdr]: Copy thread: Exiting
    [INFO] [1659029695.754626078] [sdr]: Cleanup complete
    
  • Building with ros2 humble and gbiggs backport branch of rosbag2 fails

    Building with ros2 humble and gbiggs backport branch of rosbag2 fails

    Pulling in the rosbag2 events from this PR https://github.com/ros2/rosbag2/pull/1037 and attempting to build with ROS2 Humble fails with the following output:

    colcon build --symlink-install --packages-select system_data_recorder
    Starting >>> system_data_recorder
    --- stderr: system_data_recorder                             
    /home/veesai/ros2_humble/src/system_data_recorder/src/sdr_component.cpp: In member function ‘virtual rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn sdr::SystemDataRecorder::on_configure(const rclcpp_lifecycle::State&)’:
    /home/veesai/ros2_humble/src/system_data_recorder/src/sdr_component.cpp:101:6: error: ‘rosbag2_cpp::bag_events::WriteSplitInfo’ has not been declared
      101 |     (rosbag2_cpp::bag_events::WriteSplitInfo & info) {
          |      ^~~~~~~~~~~
    /home/veesai/ros2_humble/src/system_data_recorder/src/sdr_component.cpp: In lambda function:
    /home/veesai/ros2_humble/src/system_data_recorder/src/sdr_component.cpp:104:29: error: request for member ‘opened_file’ in ‘info’, which is of non-class type ‘int’
      104 |       last_bag_file_ = info.opened_file;
          |                             ^~~~~~~~~~~
    /home/veesai/ros2_humble/src/system_data_recorder/src/sdr_component.cpp:106:36: error: request for member ‘closed_file’ in ‘info’, which is of non-class type ‘int’
      106 |       notify_new_file_to_copy(info.closed_file);
          |                                    ^~~~~~~~~~~
    /home/veesai/ros2_humble/src/system_data_recorder/src/sdr_component.cpp: In member function ‘virtual rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn sdr::SystemDataRecorder::on_configure(const rclcpp_lifecycle::State&)’:
    /home/veesai/ros2_humble/src/system_data_recorder/src/sdr_component.cpp:107:5: error: no match for ‘operator=’ (operand types are ‘rosbag2_cpp::bag_events::BagSplitCallbackType’ {aka ‘std::function<void(rosbag2_cpp::bag_events::BagSplitInfo&)>’} and ‘sdr::SystemDataRecorder::on_configure(const rclcpp_lifecycle::State&)::<lambda(int&)>’)
      107 |     };
          |     ^
    In file included from /usr/include/c++/9/future:48,
                     from /home/veesai/ros2_humble/install/rclcpp/include/rclcpp/rclcpp/executors.hpp:18,
                     from /home/veesai/ros2_humble/install/rclcpp/include/rclcpp/rclcpp/rclcpp.hpp:155,
                     from /home/veesai/ros2_humble/src/system_data_recorder/include/sdr/sdr_component.hpp:25,
                     from /home/veesai/ros2_humble/src/system_data_recorder/src/sdr_component.cpp:15:
    /usr/include/c++/9/bits/std_function.h:462:7: note: candidate: ‘std::function<_Res(_ArgTypes ...)>& std::function<_Res(_ArgTypes ...)>::operator=(const std::function<_Res(_ArgTypes ...)>&) [with _Res = void; _ArgTypes = {rosbag2_cpp::bag_events::BagSplitInfo&}]’
      462 |       operator=(const function& __x)
          |       ^~~~~~~~
    /usr/include/c++/9/bits/std_function.h:462:33: note:   no known conversion for argument 1 from ‘sdr::SystemDataRecorder::on_configure(const rclcpp_lifecycle::State&)::<lambda(int&)>’ to ‘const std::function<void(rosbag2_cpp::bag_events::BagSplitInfo&)>&’
      462 |       operator=(const function& __x)
          |                 ~~~~~~~~~~~~~~~~^~~
    /usr/include/c++/9/bits/std_function.h:480:7: note: candidate: ‘std::function<_Res(_ArgTypes ...)>& std::function<_Res(_ArgTypes ...)>::operator=(std::function<_Res(_ArgTypes ...)>&&) [with _Res = void; _ArgTypes = {rosbag2_cpp::bag_events::BagSplitInfo&}]’
      480 |       operator=(function&& __x) noexcept
          |       ^~~~~~~~
    /usr/include/c++/9/bits/std_function.h:480:28: note:   no known conversion for argument 1 from ‘sdr::SystemDataRecorder::on_configure(const rclcpp_lifecycle::State&)::<lambda(int&)>’ to ‘std::function<void(rosbag2_cpp::bag_events::BagSplitInfo&)>&&’
      480 |       operator=(function&& __x) noexcept
          |                 ~~~~~~~~~~~^~~
    /usr/include/c++/9/bits/std_function.h:494:7: note: candidate: ‘std::function<_Res(_ArgTypes ...)>& std::function<_Res(_ArgTypes ...)>::operator=(std::nullptr_t) [with _Res = void; _ArgTypes = {rosbag2_cpp::bag_events::BagSplitInfo&}; std::nullptr_t = std::nullptr_t]’
      494 |       operator=(nullptr_t) noexcept
          |       ^~~~~~~~
    /usr/include/c++/9/bits/std_function.h:494:17: note:   no known conversion for argument 1 from ‘sdr::SystemDataRecorder::on_configure(const rclcpp_lifecycle::State&)::<lambda(int&)>’ to ‘std::nullptr_t’
      494 |       operator=(nullptr_t) noexcept
          |                 ^~~~~~~~~
    /usr/include/c++/9/bits/std_function.h:523:2: note: candidate: ‘template<class _Functor> std::function<_Res(_ArgTypes ...)>::_Requires<std::function<_Res(_ArgTypes ...)>::_Callable<typename std::decay<_Functor>::type>, std::function<_Res(_ArgTypes ...)>&> std::function<_Res(_ArgTypes ...)>::operator=(_Functor&&) [with _Functor = _Functor; _Res = void; _ArgTypes = {rosbag2_cpp::bag_events::BagSplitInfo&}]’
      523 |  operator=(_Functor&& __f)
          |  ^~~~~~~~
    /usr/include/c++/9/bits/std_function.h:523:2: note:   template argument deduction/substitution failed:
    /usr/include/c++/9/bits/std_function.h: In substitution of ‘template<class _Res, class ... _ArgTypes> template<class _Cond, class _Tp> using _Requires = typename std::enable_if<_Cond::value, _Tp>::type [with _Cond = std::function<void(rosbag2_cpp::bag_events::BagSplitInfo&)>::_Callable<sdr::SystemDataRecorder::on_configure(const rclcpp_lifecycle::State&)::<lambda(int&)>, std::__invoke_result<sdr::SystemDataRecorder::on_configure(const rclcpp_lifecycle::State&)::<lambda(int&)>&, rosbag2_cpp::bag_events::BagSplitInfo&> >; _Tp = std::function<void(rosbag2_cpp::bag_events::BagSplitInfo&)>&; _Res = void; _ArgTypes = {rosbag2_cpp::bag_events::BagSplitInfo&}]’:
    /usr/include/c++/9/bits/std_function.h:523:2:   required by substitution of ‘template<class _Functor> std::function<void(rosbag2_cpp::bag_events::BagSplitInfo&)>::_Requires<std::function<void(rosbag2_cpp::bag_events::BagSplitInfo&)>::_Callable<typename std::decay<_Tp>::type, std::__invoke_result<typename std::decay<_Tp>::type&, rosbag2_cpp::bag_events::BagSplitInfo&> >, std::function<void(rosbag2_cpp::bag_events::BagSplitInfo&)>&> std::function<void(rosbag2_cpp::bag_events::BagSplitInfo&)>::operator=<_Functor>(_Functor&&) [with _Functor = sdr::SystemDataRecorder::on_configure(const rclcpp_lifecycle::State&)::<lambda(int&)>]’
    /home/veesai/ros2_humble/src/system_data_recorder/src/sdr_component.cpp:107:5:   required from here
    /usr/include/c++/9/bits/std_function.h:385:8: error: no type named ‘type’ in ‘struct std::enable_if<false, std::function<void(rosbag2_cpp::bag_events::BagSplitInfo&)>&>’
      385 |  using _Requires = typename enable_if<_Cond::value, _Tp>::type;
          |        ^~~~~~~~~
    /usr/include/c++/9/bits/std_function.h:532:2: note: candidate: ‘template<class _Functor> std::function<_Res(_ArgTypes ...)>& std::function<_Res(_ArgTypes ...)>::operator=(std::reference_wrapper<_Functor>) [with _Functor = _Functor; _Res = void; _ArgTypes = {rosbag2_cpp::bag_events::BagSplitInfo&}]’
      532 |  operator=(reference_wrapper<_Functor> __f) noexcept
          |  ^~~~~~~~
    /usr/include/c++/9/bits/std_function.h:532:2: note:   template argument deduction/substitution failed:
    /home/veesai/ros2_humble/src/system_data_recorder/src/sdr_component.cpp:107:5: note:   ‘sdr::SystemDataRecorder::on_configure(const rclcpp_lifecycle::State&)::<lambda(int&)>’ is not derived from ‘std::reference_wrapper<_Tp>’
      107 |     };
          |     ^
    make[2]: *** [CMakeFiles/sdr_component.dir/build.make:63: CMakeFiles/sdr_component.dir/src/sdr_component.cpp.o] Error 1
    make[1]: *** [CMakeFiles/Makefile2:107: CMakeFiles/sdr_component.dir/all] Error 2
    make: *** [Makefile:141: all] Error 2
    ---
    Failed   <<< system_data_recorder [2.82s, exited with code 2]
    
    Summary: 0 packages finished [3.28s]
      1 package failed: system_data_recorder
      1 package had stderr output: system_data_recorder
    
    
This repository uses a ROS node to subscribe to camera (hikvision) and lidar (livox) data. After the node merges the data, it publishes the colored point cloud and displays it in rviz.
This repository uses a ROS node to subscribe to camera (hikvision) and lidar (livox) data. After the node merges the data, it publishes the colored point cloud and displays it in rviz.

fusion-lidar-camera-ROS 一、介绍 本仓库是一个ROS工作空间,其中ws_fusion_camera/src有一个工具包color_pc ws_fusion_camera │ README.md │ └───src │ └───package: c

Dec 7, 2022
The Pizza Compass will determine your location and direct you to the nearest pizza place. It’s like a regular compass, but better!

Pizza_Compass A Particle project named Pizza_Compass Welcome to your project! Every new Particle project is composed of 3 important elements that you'

Aug 16, 2022
The command line app automatically determines your location using GeoIP and adjusts the color temperature depending on time

go-sct A color temperature setting library and CLI that operates in a similar way to f.lux and Redshift. The command line app automatically determines

Jan 25, 2022
Wgeo, or "wi-fi geolocator", is a cross-platform C/C++ library for wifi-based device geolocation, utilising public wireless access point location databases

wgeo Wgeo, or "wi-fi geolocator", is a cross-platform C/C++ library for wifi-based device geolocation, utilising public wireless access point location

Dec 23, 2022
Split flap display Arduino library

SplitFlapDisplay Split flap display Arduino library Introduction This is a simple high level library to drive split flap display letters with Arduino.

Jul 14, 2022
split89 keyboard - a 3d printed 89 key split TKL keyboard base powered by ATmega32U4 Pro Micro controllers with QMK Configurator support.
 split89 keyboard - a 3d printed 89 key split TKL keyboard base powered by ATmega32U4 Pro Micro controllers with QMK Configurator support.

split89 keyboard - a 3d printed 89 key split TKL keyboard base powered by ATmega32U4 Pro Micro controllers with QMK Configurator support. This keyboar

Jan 7, 2023
keyball is split keyboard has 100% track ball

keyball Keyball is split keyboard has 100% track ball Firmware build guide Keyball46 have separate firmwares for each of PCBs w/ trackball and w/o tra

Dec 26, 2022
code for split-flap display

split-flap 3D-files here: https://www.prusaprinters.org/prints/69464-split-flap-display General The display's electronics use one esp01 as the master

Dec 31, 2022
VinyGo is an open hardawe, meca, and source project to make a vinyl recorder.
VinyGo is an open hardawe, meca, and source project to make a vinyl recorder.

The goal of this project is to refresh the gramophone concept to build a vinyl recorder, easier, more accessible, and affordable. Is made for artists, vinyl stores, recording studios, or music lovers.

Dec 16, 2022
Autonomous recorder for vex robots using the PROS API

VEX Robot Recorder Description This is a demo project for the "Recorder" class that allows the user to record and play back past recorded autonomouses

Jun 14, 2022