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 optional callbacks to action client for goal response and result #701

Merged
merged 3 commits into from
Apr 26, 2019

Conversation

jacobperron
Copy link
Member

Resolves #635.
This also makes it easier to incorporate action clients in composable nodes since we don't have to rely on waiting on futures.

@jacobperron jacobperron added the in progress Actively being worked on (Kanban column) label Apr 18, 2019
@jacobperron
Copy link
Member Author

jacobperron commented Apr 18, 2019

  • Linux Build Status

Edit: rebuild with ros2/system_tests#346

@jacobperron jacobperron added in review Waiting for review (Kanban column) and removed in progress Actively being worked on (Kanban column) labels Apr 18, 2019
@jacobperron
Copy link
Member Author

Test failures appear unrelated. This is ready for review.

rclcpp_action/include/rclcpp_action/client.hpp Outdated Show resolved Hide resolved
rclcpp_action/include/rclcpp_action/client.hpp Outdated Show resolved Hide resolved
rclcpp_action/include/rclcpp_action/client.hpp Outdated Show resolved Hide resolved
@jacobperron jacobperron added in progress Actively being worked on (Kanban column) and removed in review Waiting for review (Kanban column) labels Apr 23, 2019
Copy link
Member

@wjwwood wjwwood left a comment

Choose a reason for hiding this comment

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

Do you ever need to set the exception in the promise? https://en.cppreference.com/w/cpp/thread/promise/set_exception

@jacobperron
Copy link
Member Author

jacobperron commented Apr 23, 2019

@wjwwood If there is an exception it is set here (just before invoking the callback):

promise->set_exception(std::current_exception());

@jacobperron
Copy link
Member Author

@hidmic @wjwwood In addition to addressing your feedback (thanks!), I've added optional callback parameters to async_get_result and the cancel methods. I plan to squash these into three separate commits before merging. Ready for another round of review.

@jacobperron jacobperron added in review Waiting for review (Kanban column) and removed in progress Actively being worked on (Kanban column) labels Apr 24, 2019
Now supports callbacks for the goal response and result.
This also makes it easier to incorporate action clients in composable nodes since we don't have to rely on waiting on futures.

Signed-off-by: Jacob Perron <jacob@openrobotics.org>
Signed-off-by: Jacob Perron <jacob@openrobotics.org>
Signed-off-by: Jacob Perron <jacob@openrobotics.org>
@jacobperron
Copy link
Member Author

  • Linux Build Status
  • Linux-aarch64 Build Status
  • macOS Build Status
  • Windows Build Status

CI also includes connected PRs:

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.

That's a neat API, LGTM!

EXPECT_EQ(rclcpp_action::GoalStatus::STATUS_ACCEPTED, goal_handle->get_status());
EXPECT_FALSE(goal_handle->is_feedback_aware());
EXPECT_TRUE(goal_handle->is_result_aware());
auto future_result = action_client->async_get_result(goal_handle);
Copy link
Contributor

Choose a reason for hiding this comment

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

@jacobperron nit: since goal_handle->is_result_aware()is true at this point, you can also just do goal_handle->async_result() to get the future.

Copy link
Member Author

Choose a reason for hiding this comment

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

See my comment below proposing we make goal_handle->async_result() private.

if (!ignore_result) {
std::shared_ptr<GoalHandle> goal_handle(
new GoalHandle(goal_info, options.feedback_callback, options.result_callback));
if (options.result_callback) {
Copy link
Contributor

Choose a reason for hiding this comment

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

@jacobperron just for the record, this now means that if you just want the result future, you need to ask for it explicitly later on, always.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, that's true. Though, this is a subtle feature. I bet that most use cases would provide a callback anyways and the case for sending a request early only to get a reference to the result future later is rare. The user can still get the future later with the client method, async_get_result().

This brings me to another point. I think it's odd to have two public facing methods for the getting the result, Client.async_get_result() and ClientGoalHandle.async_result(). Originally, the client method was essentially bypassing the "ignore result" flag. I propose we make the goal handle method private and rely on the client method to return the future. Regarding the "ignore result" flag, in the case where the goal handle is not result aware, we have 2.5 options:

  1. Keep the current behavior and make the goal handle result aware. I.e. Does not fail if the user previously set the "ignore result" flag.
    1. Or we can not even provide the "ignore result" option and make result requests on demand (this PR).
  2. Throw an exception, because the user chose to ignore the result explicitly.

Let me know what you think.

To not drag this PR on any longer, I suggest we make any changes related to this discussion in a follow-up PR.

@jacobperron jacobperron merged commit 02050c3 into master Apr 26, 2019
@jacobperron jacobperron removed the in review Waiting for review (Kanban column) label Apr 26, 2019
@delete-merged-branch delete-merged-branch bot deleted the action_client_callbacks branch April 26, 2019 16:21
Copy link

@mathias-luedtke mathias-luedtke left a comment

Choose a reason for hiding this comment

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

If I am not mistaken, both issues could get solved by swapping the if (options.goal_response_callback) and the if (options.result_callback) block.

try {
this->make_result_aware(goal_handle);
} catch (...) {
promise->set_exception(std::current_exception());
options.goal_response_callback(future);

Choose a reason for hiding this comment

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

this does not check goal_response_callback first

Copy link
Member Author

Choose a reason for hiding this comment

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

Good catch. I've swapped the two if-blocks as suggested in #738.

return;
}
}
std::lock_guard<std::mutex> guard(goal_handles_mutex_);
goal_handles_[goal_handle->get_goal_id()] = goal_handle;
promise->set_value(goal_handle);
if (options.goal_response_callback) {
options.goal_response_callback(future);

Choose a reason for hiding this comment

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

This might get called after result_callback (not 100% sure)

jacobperron added a commit to ros2/examples that referenced this pull request May 24, 2019
Since a result callback is not provided when sending the goal, the goal handle is not "result aware"
and calling the action client method will make it so.

The behaviour was changed in ros2/rclcpp#701.

Signed-off-by: Jacob Perron <jacob@openrobotics.org>
jacobperron added a commit to ros2/examples that referenced this pull request May 24, 2019
Since a result callback is not provided when sending the goal, the goal handle is not "result aware"
and calling the action client method will make it so.

The behaviour was changed in ros2/rclcpp#701.

Signed-off-by: Jacob Perron <jacob@openrobotics.org>
DensoADAS pushed a commit to DensoADAS/rclcpp that referenced this pull request Aug 5, 2022
Signed-off-by: Emerson Knapp <eknapp@amazon.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add more callbacks to rclcpp_action::Client
4 participants