@@ -212,16 +212,12 @@ bool Player::is_storage_completely_loaded() const
212212
213213void Player::play ()
214214{
215- is_in_play_ = true ;
216-
217215 float delay;
218216 if (play_options_.delay >= 0.0 ) {
219217 delay = play_options_.delay ;
220218 } else {
221219 RCLCPP_WARN (
222- this ->get_logger (),
223- " Invalid delay value: %f. Delay is disabled." ,
224- play_options_.delay );
220+ this ->get_logger (), " Invalid delay value: %f. Delay is disabled." , play_options_.delay );
225221 delay = 0.0 ;
226222 }
227223
@@ -237,18 +233,28 @@ void Player::play()
237233 reader_->get_metadata ().starting_time .time_since_epoch ()).count ();
238234 clock_->jump (starting_time);
239235
240- storage_loading_future_ = std::async (
241- std::launch::async,
242- [this ]() {load_storage_content ();});
236+ storage_loading_future_ = std::async (std::launch::async, [this ]() {load_storage_content ();});
243237
244238 wait_for_filled_queue ();
239+ { // Notify play_next() that we are ready for playback
240+ std::lock_guard<std::mutex> lk (ready_to_play_from_queue_mutex_);
241+ is_ready_to_play_from_queue_ = true ;
242+ ready_to_play_from_queue_cv_.notify_all ();
243+ }
245244 play_messages_from_queue ();
245+ {
246+ std::lock_guard<std::mutex> lk (ready_to_play_from_queue_mutex_);
247+ is_ready_to_play_from_queue_ = false ;
248+ ready_to_play_from_queue_cv_.notify_all ();
249+ }
246250 reader_->close ();
247251 } while (rclcpp::ok () && play_options_.loop );
248252 } catch (std::runtime_error & e) {
249253 RCLCPP_ERROR (this ->get_logger (), " Failed to play: %s" , e.what ());
250254 }
251- is_in_play_ = false ;
255+ std::lock_guard<std::mutex> lk (ready_to_play_from_queue_mutex_);
256+ is_ready_to_play_from_queue_ = false ;
257+ ready_to_play_from_queue_cv_.notify_all ();
252258}
253259
254260void Player::pause ()
@@ -299,14 +305,19 @@ rosbag2_storage::SerializedBagMessageSharedPtr * Player::peek_next_message_from_
299305
300306bool Player::play_next ()
301307{
302- // Temporary take over playback from play_messages_from_queue()
303- std::lock_guard<std::mutex> lk (skip_message_in_main_play_loop_mutex_);
304-
305- if (!clock_->is_paused () || !is_in_play_) {
308+ if (!clock_->is_paused ()) {
306309 return false ;
307310 }
308311
312+ // Temporary take over playback from play_messages_from_queue()
313+ std::lock_guard<std::mutex> main_play_loop_lk (skip_message_in_main_play_loop_mutex_);
309314 skip_message_in_main_play_loop_ = true ;
315+ // Wait for player to be ready for playback messages from queue i.e. wait for Player:play() to
316+ // be called if not yet and queue to be filled with messages.
317+ {
318+ std::unique_lock<std::mutex> lk (ready_to_play_from_queue_mutex_);
319+ ready_to_play_from_queue_cv_.wait (lk, [this ] {return is_ready_to_play_from_queue_;});
320+ }
310321 rosbag2_storage::SerializedBagMessageSharedPtr * message_ptr = peek_next_message_from_queue ();
311322
312323 bool next_message_published = false ;
@@ -361,7 +372,6 @@ void Player::enqueue_up_to_boundary(uint64_t boundary)
361372
362373void Player::play_messages_from_queue ()
363374{
364- playing_messages_from_queue_ = true ;
365375 // Note: We need to use message_queue_.peek() instead of message_queue_.try_dequeue(message)
366376 // to support play_next() API logic.
367377 rosbag2_storage::SerializedBagMessageSharedPtr * message_ptr = peek_next_message_from_queue ();
@@ -386,7 +396,6 @@ void Player::play_messages_from_queue()
386396 message_ptr = peek_next_message_from_queue ();
387397 }
388398 }
389- playing_messages_from_queue_ = false ;
390399}
391400
392401void Player::prepare_publishers ()
0 commit comments