ros2/rosbag2

play service call doesn't return until play finished

KenYN opened this issue · 2 comments

Description

When using the service interface to pull request #1419 (I'm not sure how to set up the same situation for ros2 bag play) with the command:

$ rosservice call /bag_player/play rosbag2_interfaces/srv/Play "{start_offset: {sec: 0, nanosec: 0}, playback_duration: {sec: 0, nanosec: 0}, playback_until_timestamp: {sec: 0, nanosec: 0}}" requester: making request: rosbag2_interfaces.srv.Play_Request(start_offset=builtin_interfaces.msg.Time(sec=0, nanosec=0), playback_duration=builtin_interfaces.msg.Duration(sec=0, nanosec=0), playback_until_timestamp=builtin_interfaces.msg.Time(sec=0, nanosec=0))

Expected Behavior

According to this page I would expect it to return quickly after starting the playback:

Services

  • Should be used for remote procedure calls that terminate quickly, e.g. for querying the state of a node or doing a quick calculation such as IK. They should never be used for longer running processes

Actual Behavior

The service call does not return until play completes, and if looping is on, then it never returns until CTRL+C.

System (please complete the following information)

Ubuntu 22.04 + Rolling

Very stupid question: does this happens only with my branch? I'm looking at the service callback code:

srv_play_ = owner_->create_service<rosbag2_interfaces::srv::Play>(
"~/play",
[this](
rosbag2_interfaces::srv::Play::Request::ConstSharedPtr request,
rosbag2_interfaces::srv::Play::Response::SharedPtr response)
{
play_options_.start_offset = rclcpp::Time(request->start_offset).nanoseconds();
play_options_.playback_duration = rclcpp::Duration(request->playback_duration);
play_options_.playback_until_timestamp =
rclcpp::Time(request->playback_until_timestamp).nanoseconds();
configure_play_until_timestamp();
response->success = owner_->play();
});

and it seems to me also upstream rosbag2 waits for the end of .play() method.

@KenYN @roncapat Yeah, the Player::play() method is a blocking call and probably is not suitable for the direct call from the service callback.
We may need to consider spawning a new thread for playback from service callback if we are not in the playback already.