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

Add play-until functionality #962

Closed
wants to merge 3 commits into from
Closed

Conversation

gbiggs
Copy link
Member

@gbiggs gbiggs commented Feb 16, 2022

This PR adds the ability to play until a given timestamp.

This work was co-authored by @agalbachicar.

This PR requires #960 to be merged first (at which point it will probably need to be rebased).

Signed-off-by: Geoffrey Biggs <[email protected]>
Signed-off-by: Geoffrey Biggs <[email protected]>
Signed-off-by: Geoffrey Biggs <[email protected]>
@gbiggs gbiggs added the enhancement New feature or request label Feb 16, 2022
@gbiggs gbiggs requested a review from a team as a code owner February 16, 2022 06:31
@gbiggs gbiggs self-assigned this Feb 16, 2022
@gbiggs gbiggs requested review from MichaelOrlov and hidmic and removed request for a team February 16, 2022 06:31
@MichaelOrlov
Copy link
Contributor

@gbiggs Let's finish review for #960 first.

Copy link
Contributor

@hidmic hidmic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First pass!

"play", &rosbag2_py::Player::play, py::arg("storage_options"), py::arg(
"play_options"), py::arg("duration") = std::nullopt)
.def(
"play_until", &rosbag2_py::Player::play, py::arg("storage_options"), py::arg(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gbiggs should be rosbag2_py::Player::play_until instead?

"play_options"), py::arg("duration") = std::nullopt)
.def(
"play_until", &rosbag2_py::Player::play, py::arg("storage_options"), py::arg(
"play_options"), py::arg("timestamp") = std::nullopt)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gbiggs hmm, shouldn't timestamp be mandatory for play_until()?

Comment on lines +700 to +703
const rcutils_duration_value_t duration =
static_cast<rcutils_duration_value_t>(request->duration.sec) *
static_cast<rcutils_duration_value_t>(1000000000) +
static_cast<rcutils_duration_value_t>(request->duration.nanosec);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gbiggs nit: consider

Suggested change
const rcutils_duration_value_t duration =
static_cast<rcutils_duration_value_t>(request->duration.sec) *
static_cast<rcutils_duration_value_t>(1000000000) +
static_cast<rcutils_duration_value_t>(request->duration.nanosec);
const rcutils_duration_value_t duration =
rclcpp::Duration(request->duration).nanoseconds();

Comment on lines +714 to +717
const rcutils_time_point_value_t timestamp =
static_cast<rcutils_time_point_value_t>(request->time.sec) *
static_cast<rcutils_time_point_value_t>(1000000000) +
static_cast<rcutils_time_point_value_t>(request->time.nanosec);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gbiggs nit: consider

Suggested change
const rcutils_time_point_value_t timestamp =
static_cast<rcutils_time_point_value_t>(request->time.sec) *
static_cast<rcutils_time_point_value_t>(1000000000) +
static_cast<rcutils_time_point_value_t>(request->time.nanosec);
const rcutils_time_point_value_t timestamp =
rclcpp::Time(request->time).nanoseconds();

Comment on lines 469 to 470
// Do not move on until sleep_until returns true
// It will always sleep, so this is not a tight busy loop on pause
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gbiggs this should probably be relocated after the next if clause and before the while loop.

Comment on lines +131 to +132
std::move(
reader), storage_options_, play_options_);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gbiggs nit: can we collapse this two lines into one?

{
auto await_received_messages = sub_->spin_subscriptions();

player_->play(std::chrono::nanoseconds(std::chrono::milliseconds(1000)).count());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gbiggs fyi: you could also do

Suggested change
player_->play(std::chrono::nanoseconds(std::chrono::milliseconds(1000)).count());
player_->play(RCUTILS_MS_TO_NS(1000));

or equivalently

Suggested change
player_->play(std::chrono::nanoseconds(std::chrono::milliseconds(1000)).count());
player_->play(RCUTILS_S_TO_NS(1));

Same everywhere else.

Comment on lines +147 to +148
auto replayed_test_primitives = sub_->get_received_messages<test_msgs::msg::BasicTypes>(
kTopic1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gbiggs nit:

Suggested change
auto replayed_test_primitives = sub_->get_received_messages<test_msgs::msg::BasicTypes>(
kTopic1);
auto replayed_test_primitives =
sub_->get_received_messages<test_msgs::msg::BasicTypes>(kTopic1);

Same elsewhere.

std::future<void> await_received_messages_;
};

TEST_F(RosBag2PlayForTestFixture, play_for_all_are_played_due_to_duration)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gbiggs nit^N: test case names read a bit awkward. For instance, how about play_for_a_long_duration_publishes_some here?

EXPECT_THAT(replayed_test_primitives, SizeIs(0u));

auto replayed_test_arrays = sub_->get_received_messages<test_msgs::msg::Arrays>("/topic2");
// All messages should have arrived.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gbiggs leftover?

@agalbachicar
Copy link
Contributor

Before proceeding to fix this PR, I'd like to know your preference on the implementation @MichaelOrlov and @hidmic . We proposed and discussed this in the meeting group on 2021-05-21. The feature request changed a bit to be: "play until timepoint" rather than "play until next message of topic T" since then.

Also, we needed to have this functionality in another rosbag2 fork first that should be compliant with foxy. As a consequence, this patch looks so odd at first (likewise to #960 at first). We aimed for API compatibility or minimal changes across ros2 releases. That said, we are eager to push to get these changes in before the code freeze (as everyone else contributing :)) and hoping you could make some time to guide us to get these changes in.

Looking forward to hearing your thoughts.

@MichaelOrlov
Copy link
Contributor

@agalbachicar @gbiggs I think you will need to rebase first and rework this PR since we already have play_messages_from_queue(play_until_time); API implemented in #960.
Implementation for this PR is going to be sort of a light-way.
I assume will need to add new parameter for command line and in playback options data structure. Further in Player::Play() use two parameters play_for and play_until to determine which time is latter, to use it as parameter for existing play_messages_from_queue(play_until_time); call.
Please take in to consideration the way how we workout unit tests in #960 and use similar approach.

@gbiggs
Copy link
Member Author

gbiggs commented May 10, 2022

Closing in favour of #1005

MichaelOrlov pushed a commit that referenced this pull request Jun 21, 2022
* Implements play until on top of play for.

Signed-off-by: Agustin Alba Chicar <[email protected]>

* Adds python bindings

Signed-off-by: Agustin Alba Chicar <[email protected]>

* Adds test for play until.

Signed-off-by: Agustin Alba Chicar <[email protected]>

* Fixes variable name.

Signed-off-by: Agustin Alba Chicar <[email protected]>

* Adds the same docstring for play_until and play_duration options than in PlayOptions to clarify usage.

Signed-off-by: Agustin Alba Chicar <[email protected]>

* Updates the CLI to combine the seconds and nanoseconds part of the playback_until stamp

Signed-off-by: Agustin Alba Chicar <[email protected]>

* Changes to play verb parameters:

- Unifies the use of '-' instead of '_' to split words in arguments.
- Uses mutually exclusive arguments: --playback-until-sec and --playback-until-nsec
  to pass the timestamp.

Signed-off-by: Agustin Alba Chicar <[email protected]>

* Solves review comments.

- Adds test cases to the player.
- Renames play_until and similar occurrences to contain timestamp.
- Renames play_for and similar occurrences to not contain for and include duration.

Signed-off-by: Agustin Alba Chicar <[email protected]>

* Solves review comments to tests.

Signed-off-by: Agustin Alba Chicar <[email protected]>

* Modifies play_until_is_equal_to_the_total_duration

The test body now evaluates a bag whose duration is exactly the same
as given timestamp in PlayOptions.

Signed-off-by: Agustin Alba Chicar <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants