Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Specify recording time for a ros2 bag #1857

Open
paoloelle opened this issue Nov 15, 2024 · 8 comments · May be fixed by #1896
Open

Specify recording time for a ros2 bag #1857

paoloelle opened this issue Nov 15, 2024 · 8 comments · May be fixed by #1896
Labels
backlog Not assigned and not immediately planned enhancement New feature or request help wanted Extra attention is needed

Comments

@paoloelle
Copy link

Description

I would like to have a flag that allows to specify the time length of a record of a ros2 bag.

Related Issues

I cannot specify the time length when I want to record a bag file. I need it since I will run the record from a bash file and the command timeout 10 ros2 bag record /topic_name doesn't work. If I run the same command directly from the terminal works.

Completion Criteria

  • have a flag that allow to specify the recording lenght
@paoloelle paoloelle added the enhancement New feature or request label Nov 15, 2024
@paoloelle
Copy link
Author

paoloelle commented Nov 15, 2024

An alternative solution that I found is by storing the PID:

ros2 bag record /topic_name
BAG_PID=$!
sleep time_length
kill $BAG_PID

@MichaelOrlov MichaelOrlov added help wanted Extra attention is needed backlog Not assigned and not immediately planned labels Nov 17, 2024
@nicolaloi nicolaloi linked a pull request Jan 13, 2025 that will close this issue
@MichaelOrlov
Copy link
Contributor

@paoloelle, @nicolaloi Could you please provide a real-world use cases/examples when this functionality with requested new --max-recording-duration, --max-recording-size and --max-recording-messages CLI options would be usefull?

@MichaelOrlov
Copy link
Contributor

Why one would need to record for some time and then automatically stop at the first hand?

Why not send SIG_INT or use a service call to stop recording when needed as
ros2 service call /rosbag2_recorder/stop rosbag2_interfaces/Stop ?

@paoloelle
Copy link
Author

paoloelle commented Jan 30, 2025

@MichaelOrlov I'm running an evolutionary algorithm using ROS 2 and Gazebo. In my setup, I need to run a huge amount of simulations (each of them lasts 1 minute) and be able to stop/resume a simulation, change some parameters, and record the data for each single run (using ros2 bag). I do that in an automated way by using a bash file. I thought that having an option that allows me to specify the duration of my recording instead of having to explicitly kill the process would be a more practical way to stop the recording. Also, my idea is to run these simulations on a computing cluster, and I’m not sure I will have the privileges to kill processes at will.

Why one would need to record for some time and then automatically stop at the first hand?

Why not send SIG_INT or use a service call to stop recording when needed as ros2 service call /rosbag2_recorder/stop rosbag2_interfaces/Stop ?

Does this service already exist? Sorry, but I didn't know about that.

@nicolaloi
Copy link
Contributor

@MichaelOrlov I’d say that having options (in the CLI, as class parameters, node parameters) to specify a known bag duration, size, etc., is more convenient and user-friendly than having to setup a ros service call at a specific moment to stop the recording (especially when the stopping condition is not based on the simple duration).

Why would someone need to record for a set duration and have it stop automatically from the start?

Apart from integration testing (eg #1574), other use cases are data collection scenarios (eg for ML training) where you can already know in advance how many messages you need to collect (eg images). More generally, there are cases where you simply want to record for a predefined specific duration or a set number of messages.

Currently, once the recording starts it can only be stopped through "external" signals like SIGINT or a ros service. Integrating a built-in stopping based on predefined conditions (providing at least a standard/common condition like max recording duration as in ros1) would simplify its usage.

@MichaelOrlov
Copy link
Contributor

@paoloelle @nicolaloi Thank you for the clarification. Make sense.

As regards /rosbag2_recorder/stop rosbag2_interfaces/Stop it is not available yet. However, we have a plan to add it. Please refer to the #1634 and #1840

@emersonknapp
Copy link
Collaborator

I think something is missing from this discussion, which is that you can always script your own arbitrarry use cases by using the API!

If you look at record.py you'll see that the actual code to record is pretty small - https://github.com/ros2/rosbag2/blob/rolling/ros2bag/ros2bag/verb/record.py#L291

You can easily accomplish your use case with a small Python script like:

# record_duration.py

from argparse import ArgumentParser
from threading import Thread
import time
from rosbag2_py import Recorder, RecordOptions, StorageOptions

def record(recorder, storage_opts, record_opts):
    try:
        recorder.record(storage_opts, record_opts)
    except KeyboardInterrupt:
        pass


def main():
    parser = ArgumentParser()
    parser.add_argument('outdir')
    parser.add_argument('duration', type=int, help='In seconds')
    args = parser.parse_args()
    print(f"Recording to {args.outdir} for {args.duration} seconds...")

    storage_opts = StorageOptions(uri=args.outdir)
    record_opts = RecordOptions()
    record_opts.all_topics = True
    recorder = Recorder()

    print("Start recording")
    record_thread = Thread(target=record, args=(recorder, storage_opts, record_opts))
    record_thread.start()
    time.sleep(args.duration)
    print("Stopping recording")
    recorder.cancel()
    record_thread.join()
    print("Done!")

if __name__ == "__main__":
    main()

Which I just testing on Rolling and it worked great!

$ python3 src/ros2/rosbag2/record_duration.py data/durationbag 5
Recording to data/durationbag for 5 seconds...
Start recording
[INFO] [1740188176.851256077] [rosbag2_recorder]: Press SPACE for pausing/resuming
[INFO] [1740188176.854224888] [rosbag2_recorder]: Listening for topics...
[INFO] [1740188176.854231528] [rosbag2_recorder]: Event publisher thread: Starting
[INFO] [1740188176.857596575] [rosbag2_recorder]: Subscribed to topic '/rosout'
[INFO] [1740188176.858837590] [rosbag2_recorder]: Subscribed to topic '/events/write_split'
[INFO] [1740188176.858892016] [rosbag2_recorder]: Recording...
[INFO] [1740188176.975242376] [rosbag2_recorder]: Subscribed to topic '/chatter'
[INFO] [1740188176.981359735] [rosbag2_recorder]: Subscribed to topic '/parameter_events'
Stopping recording
[INFO] [1740188181.911224733] [rosbag2_recorder]: Pausing recording.
[INFO] [1740188181.917537441] [rosbag2_recorder]: Event publisher thread: Exiting
[INFO] [1740188181.917705170] [rosbag2_recorder]: Recording stopped
Done!

I think encouraging this flexibility is probably far more useful on average than complicating the existing commandline - when it comes to somewhat specialized cases.

I would agree that the rosbag2_py API could use some ergonomics improvements, but at least it's possible with relatively little code!

If you agree that this is a good solution, perhaps I can add this to the README "Tips and Tricks" section, or rosbag2_examples and close this issue as wontfix.

@paoloelle
Copy link
Author

@emersonknapp thanks for the suggestion and the example, it will help me a lot. Anyway, I think that for a command whose purpose is to register data, allowing the user to specify the recording duration based on certain criteria via a command-line flag seems like a reasonable feature to me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backlog Not assigned and not immediately planned enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants