1
$\begingroup$

I'd like to modify this example of recording a bag file from a ROS node written in Python to be able to effectively start and stop recording using a service call. My thought is I could create self.writer = rosbag2_py.SequentialWriter() in my service callback, and add some logic in the callbacks for the topic subscriptions to ensure that it will only try to write the data if self.writer exists and is ready to be written to.

I think what I describe should work for starting recording, my question is how will I handle safely stopping the recording, such that I can subsequently start recording a new bag file again with a subsequent service call. Since there is an open function on SequentialWriter, I was expecting to see a close or flush function, but I don't see such functionality in the exposed Python API. My guess then is that maybe this isn't working like how I normally think of files being "open" in Python.

So, what I would like to know: what is the correct way to "stop" recording when using the Python API? Is it sufficient to simply call self.writer.open() with different StorageOptions that assign a new uri to save to? If I do that, am I somehow leaving "open" resources dangling?

UPDATE (1/2): It seems there is in fact a close function on SequentialWriter, but only in the C++ API and it's not offered yet in the Python bindings. There is an issue on GitHub that gives some awareness to this.

UPDATE (2/2): I wrote what I described in C++, and me calling the close function on SequentialWriter just caused my program to crash without any error. I ended up finding the package system_data_recorder that implements the functionality I needed of being able to programmatically start/stop bag recording. They use node lifecycles to manage start/pause/resume/stop recording and have the added benefit that they can copy incremental chunks of the bags to a copy location so that you can incrementally save your data to a backup. Very nice!

$\endgroup$

1 Answer 1

1
$\begingroup$

One possible approach (that was often done in ROS1 since there wasn't a stable rosbag API) would be to instead use Python subprocess to call the ros2 bag record command as you would from the command line - it is then very easy to send a ctrl-C to the subprocess.

$\endgroup$
1
  • $\begingroup$ I do recall doing this sort of thing in ROS1, following guidance similar to what's suggested here: answers.ros.org/question/10714/…. However, I recall that causing me many headaches because there were many child processes that got spawned by rosbag, and killing it cleanly without creating orphans was a challenge. The system_data_recorder I think has the best approach, leveraging the lifecycle node capabilities in ROS2. $\endgroup$
    – adamconkey
    Commented Mar 17, 2023 at 23:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.