0
$\begingroup$

I am writing a user interface for various ROS2 related functionalities. One of these functionalities is that users should be able to play or stream a ROS2 bag file.
For this, I have two different threads. One thread is for handling any UI based code, while the other thread (called PlayBagThread) which is based on QT's QThread class, handles the ROSBag playing instance.
In PlayBagThread, I have a run function which runs the thread's main code. The code roughly looks like this:

void
PlayBagThread::run()
{
    rosbag2_storage::StorageOptions storageOptions;
    rosbag2_transport::PlayOptions playOptions;

    auto player = std::make_shared<rosbag2_transport::Player>(storageOptions, playOptions);
    player->play();
}

If the run function is finished, the thread will finish and be deleted later. However, the play function will open another asychronous thread handling the bag playing in the background. Also, the rosbag2_transport::Player class has no stopping function, at least not for ROS2 Humble which I am currently working on (it is available for Jazzy and Rolling, though). Because of this, I found no way to interrupt or cancel the play function.
So I tried an alternative design which looks like this:

void
PlayBagThread::run()
{
    rosbag2_storage::StorageOptions storageOptions;
    rosbag2_transport::PlayOptions playOptions;

    auto player = std::make_shared<rosbag2_transport::Player>(storageOptions, playOptions);
    auto playerFuture = std::async(std::launch::async, [&player]() -> void {player->play();});

    player->pause();

    while (player->play_next()) {
        if (breakingCondition) {
            return;
        }
    }
}

In this design, the thread will run until a certain breaking condition is met. From outside PlayBagThread, I can then set the breaking condition to true, which normally should finish the thread.
However, even after the function is returned, the thread is still running. My main guess for this is that the playerFuture instance is still active and running in the background so that the thread can't terminate. But there is no way to terminate an instance of std::future (which makes sense considering its design).

Is there a way to terminate a running rosbag2_transport::Player instance while it is playing something? Does it even make sense to rely on this class or the C++ code in general?
Thanks in advance!

$\endgroup$

0

Your Answer

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

Browse other questions tagged or ask your own question.