-
Notifications
You must be signed in to change notification settings - Fork 317
Playback pause feature #443
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
Changes from all commits
2aff04b
668a988
8b3f3d7
5767a61
58b24c5
2da411b
c3e211d
ef9a4c2
50594ca
e321f05
cf8a53a
bad9ca1
50a2c07
d995789
f22fe44
a44d5c3
bac141d
335d031
4499ab7
9889f94
7b60a7e
b7bc103
fa155ce
092015d
6fc2981
7cec0a3
47cff25
f514f51
9c92972
fd97872
ca02e1b
3f341ff
4c0b69f
10e62c4
38a1bc7
478f9a1
2ce8c36
2401f22
9603f50
6f56d60
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,6 +22,8 @@ | |
| #include <utility> | ||
| #include <vector> | ||
|
|
||
| #include "lifecycle_msgs/msg/state.hpp" | ||
|
|
||
| #include "rcl/graph.h" | ||
|
|
||
| #include "rclcpp/rclcpp.hpp" | ||
|
|
@@ -75,10 +77,13 @@ namespace rosbag2_transport | |
|
|
||
| const std::chrono::milliseconds | ||
| Player::queue_read_wait_period_ = std::chrono::milliseconds(100); | ||
| const std::chrono::milliseconds | ||
| Player::pause_sleep_period_ = std::chrono::milliseconds(30); | ||
|
|
||
| Player::Player( | ||
| std::shared_ptr<rosbag2_cpp::Reader> reader, std::shared_ptr<Rosbag2Node> rosbag2_transport) | ||
| : reader_(std::move(reader)), rosbag2_transport_(rosbag2_transport) | ||
| : reader_(std::move(reader)), played_all_(false), | ||
| rosbag2_transport_(rosbag2_transport) | ||
| {} | ||
|
|
||
| bool Player::is_storage_completely_loaded() const | ||
|
|
@@ -102,6 +107,14 @@ void Player::play(const PlayOptions & options) | |
|
|
||
| wait_for_filled_queue(options); | ||
|
|
||
| rosbag2_transport_->configure(); | ||
| // If playback should not be paused in the beginning, activate lifecycle node right away. | ||
| // If playback should be paused, move on. | ||
| // Playback will detect when node is activated, either from here or externally. | ||
| if (!options.paused) { | ||
| rosbag2_transport_->activate(); | ||
|
mabelzhang marked this conversation as resolved.
|
||
| } | ||
|
|
||
| play_messages_from_queue(options); | ||
| } | ||
|
|
||
|
|
@@ -158,6 +171,7 @@ void Player::enqueue_up_to_boundary(const TimePoint & time_first_message, uint64 | |
| void Player::play_messages_from_queue(const PlayOptions & options) | ||
| { | ||
| start_time_ = std::chrono::system_clock::now(); | ||
| paused_duration_ = std::chrono::nanoseconds(0); | ||
| do { | ||
| play_messages_until_queue_empty(options); | ||
| if (!is_storage_completely_loaded() && rclcpp::ok()) { | ||
|
|
@@ -166,6 +180,8 @@ void Player::play_messages_from_queue(const PlayOptions & options) | |
| "increasing the --read-ahead-queue-size option."); | ||
| } | ||
| } while (!is_storage_completely_loaded() && rclcpp::ok()); | ||
|
|
||
| played_all_ = true; | ||
| } | ||
|
|
||
| void Player::play_messages_until_queue_empty(const PlayOptions & options) | ||
|
|
@@ -178,12 +194,37 @@ void Player::play_messages_until_queue_empty(const PlayOptions & options) | |
| rate = options.rate; | ||
| } | ||
|
|
||
| static size_t counter = 0; | ||
| while (message_queue_.try_dequeue(message) && rclcpp::ok()) { | ||
| std::this_thread::sleep_until( | ||
| start_time_ + std::chrono::duration_cast<std::chrono::nanoseconds>( | ||
| 1.0 / rate * message.time_since_start)); | ||
| 1.0 / rate * message.time_since_start + paused_duration_)); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why do we sleep longer here?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I understand, it just looks to me for a (yet another) potential place to introduce flakiness. |
||
|
|
||
| if (rosbag2_transport_->get_current_state().id() != | ||
| lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what happened if in state
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With respect to your first comment, the ROS 1 bag implementation had a time_translator class that took care of manipulating the time and keeping track of time pauses and associated math. Do you think this is a better approach?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the question is referring to #443 (comment)
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Sorry, I'm even tardier in responding to this. I'm working through it, but I was thinking about something like this: |
||
| { | ||
| ROSBAG2_TRANSPORT_LOG_INFO("Paused"); | ||
| std::chrono::time_point<std::chrono::system_clock> pause_start = | ||
| std::chrono::system_clock::now(); | ||
|
|
||
| // Sleep until activated externally | ||
| while (rosbag2_transport_->get_current_state().id() != | ||
| lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE && rclcpp::ok()) | ||
| { | ||
| std::this_thread::sleep_for(pause_sleep_period_); | ||
| } | ||
|
|
||
| paused_duration_ += std::chrono::system_clock::now() - pause_start; | ||
|
|
||
| if (rclcpp::ok()) { | ||
| ROSBAG2_TRANSPORT_LOG_INFO("Resumed"); | ||
| } | ||
| } | ||
|
|
||
| if (rclcpp::ok()) { | ||
| publishers_[message.message->topic_name]->publish(message.message->serialized_data); | ||
| // TODO(mabelzhang) TEMPORARY, remove when done debugging. And counter above. | ||
| fprintf(stderr, "publishing message %zu\n", (++counter)); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,6 +23,8 @@ | |
| #include <utility> | ||
| #include <vector> | ||
|
|
||
| #include "lifecycle_msgs/msg/state.hpp" | ||
|
|
||
| #include "rosbag2_cpp/writer.hpp" | ||
|
|
||
| #include "rosbag2_transport/logging.hpp" | ||
|
|
@@ -184,7 +186,9 @@ Recorder::create_subscription( | |
|
|
||
| void Recorder::record_messages() const | ||
| { | ||
| spin(node_); | ||
| rclcpp::executors::MultiThreadedExecutor exe; | ||
| exe.add_node(node_->get_node_base_interface()); | ||
| exe.spin(); | ||
|
Comment on lines
+189
to
+191
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So while this allows me to use the traditional
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are you saying we should add a spin thread to On a related note, as I mentioned here, I actually didn't get anything with |
||
| } | ||
|
|
||
| std::string Recorder::serialized_offered_qos_profiles_for_topic(const std::string & topic_name) | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.