Skip to content

Commit 66a898e

Browse files
committed
Add new interfaces to configure feedback subscription content filter for action client
Signed-off-by: Barry Xu <barry.xu@sony.com>
1 parent 7f783cb commit 66a898e

5 files changed

Lines changed: 272 additions & 2 deletions

File tree

rclcpp_action/include/rclcpp_action/client.hpp

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,24 +111,31 @@ class Client : public ClientBase
111111
* This constructs an action client, but it will not work until it has been added to a node.
112112
* Use `rclcpp_action::create_client()` to both construct and add to a node.
113113
*
114+
* If enable_feedback_msg_optimization is set to true, an action client can handle up to 6 goals
115+
* simultaneously.
116+
*
114117
* \param[in] node_base A pointer to the base interface of a node.
115118
* \param[in] node_graph A pointer to an interface that allows getting graph information about
116119
* a node.
117120
* \param[in] node_logging A pointer to an interface that allows getting a node's logger.
118121
* \param[in] action_name The action name.
122+
* \param[in] enable_feedback_msg_optimization Enable feedback subscription content filter to
123+
* reduce network load.
119124
* \param[in] client_options Options to pass to the underlying `rcl_action::rcl_action_client_t`.
120125
*/
121126
Client(
122127
rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_base,
123128
rclcpp::node_interfaces::NodeGraphInterface::SharedPtr node_graph,
124129
rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr node_logging,
125130
const std::string & action_name,
131+
bool enable_feedback_msg_optimization = false,
126132
const rcl_action_client_options_t & client_options = rcl_action_client_get_default_options()
127133
)
128134
: ClientBase(
129135
node_base, node_graph, node_logging, action_name,
130136
rosidl_typesupport_cpp::get_action_type_support_handle<ActionT>(),
131-
client_options)
137+
client_options),
138+
enable_feedback_msg_optimization_(enable_feedback_msg_optimization)
132139
{
133140
}
134141

@@ -180,6 +187,18 @@ class Client : public ClientBase
180187
}
181188
return;
182189
}
190+
191+
// If feedback message optimization is enabled, add goal id to feedback subscription
192+
// content filter
193+
if (enable_feedback_msg_optimization_) {
194+
std::lock_guard<std::mutex> lock(configure_feedback_sub_content_filter_mutex_);
195+
if (!configure_feedback_subscription_filter_add_goal_id(goal_request->goal_id.uuid)) {
196+
RCLCPP_ERROR(
197+
this->get_logger(),
198+
"Failed to add goal id to feedback subscription content filter for action client.");
199+
}
200+
}
201+
183202
GoalInfo goal_info;
184203
goal_info.goal_id.uuid = goal_request->goal_id.uuid;
185204
goal_info.stamp = goal_response->stamp;
@@ -519,6 +538,21 @@ class Client : public ClientBase
519538
wrapped_result.goal_id = goal_handle->get_goal_id();
520539
wrapped_result.code = static_cast<ResultCode>(result_response->status);
521540
goal_handle->set_result(wrapped_result);
541+
542+
// If feedback message optimization is enabled, remove goal id from feedback subscription
543+
// content filter
544+
if (this->enable_feedback_msg_optimization_) {
545+
std::lock_guard<std::mutex> lock(
546+
this->configure_feedback_sub_content_filter_mutex_);
547+
if (!this->configure_feedback_subscription_filter_remove_goal_id(
548+
goal_handle->get_goal_id()))
549+
{
550+
RCLCPP_ERROR(
551+
this->get_logger(),
552+
"Failed to remove goal id from feedback subscription content filter for action "
553+
"client.");
554+
}
555+
}
522556
std::lock_guard<std::recursive_mutex> lock(goal_handles_mutex_);
523557
goal_handles_.erase(goal_handle->get_goal_id());
524558
});
@@ -539,9 +573,26 @@ class Client : public ClientBase
539573
std::shared_future<typename CancelResponse::SharedPtr> future(promise->get_future());
540574
this->send_cancel_request(
541575
std::static_pointer_cast<void>(cancel_request),
542-
[cancel_callback, promise](std::shared_ptr<void> response) mutable
576+
[this, cancel_callback, promise](std::shared_ptr<void> response) mutable
543577
{
544578
auto cancel_response = std::static_pointer_cast<CancelResponse>(response);
579+
580+
// If feedback message optimization is enabled, remove goal id from feedback subscription
581+
// content filter
582+
if (this->enable_feedback_msg_optimization_) {
583+
for (const auto & goal_info : cancel_response->goals_canceling) {
584+
std::lock_guard<std::mutex> lock(this->configure_feedback_sub_content_filter_mutex_);
585+
if (!this->configure_feedback_subscription_filter_remove_goal_id(
586+
goal_info.goal_id.uuid))
587+
{
588+
RCLCPP_ERROR(
589+
this->get_logger(),
590+
"Failed to remove goal id from feedback subscription content filter for action "
591+
"client.");
592+
}
593+
}
594+
}
595+
545596
promise->set_value(cancel_response);
546597
if (cancel_callback) {
547598
cancel_callback(cancel_response);
@@ -552,6 +603,10 @@ class Client : public ClientBase
552603

553604
std::map<GoalUUID, typename GoalHandle::WeakPtr> goal_handles_;
554605
std::recursive_mutex goal_handles_mutex_;
606+
607+
// Enable feedback subscription content filter
608+
const bool enable_feedback_msg_optimization_;
609+
std::mutex configure_feedback_sub_content_filter_mutex_;
555610
};
556611
} // namespace rclcpp_action
557612

rclcpp_action/include/rclcpp_action/client_base.hpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,22 @@ class ClientBase : public rclcpp::Waitable
295295
void
296296
handle_feedback_message(std::shared_ptr<void> message) = 0;
297297

298+
/// \internal
299+
/// \return true if goal id was added to feedback subscription content filter successfully
300+
/// \return false if an error occurred during calling rcl function or
301+
/// if the used rmw middleware doesn't support Content Filtering feature.
302+
bool
303+
configure_feedback_subscription_filter_add_goal_id(const GoalUUID & goal_id);
304+
305+
306+
/// \internal
307+
/// \return true if goal id was removed from feedback subscription content filter successfully or
308+
/// goal id was not found in feedback subscription content filter or
309+
/// if the used rmw middleware doesn't support Content Filtering feature.
310+
/// \return false if an error occurred during calling rcl function.
311+
bool
312+
configure_feedback_subscription_filter_remove_goal_id(const GoalUUID & goal_id);
313+
298314
/// \internal
299315
virtual
300316
std::shared_ptr<void>

rclcpp_action/include/rclcpp_action/create_client.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,16 @@ namespace rclcpp_action
3030
* This function is equivalent to \sa create_client()` however is using the individual
3131
* node interfaces to create the client.
3232
*
33+
* If enable_feedback_msg_optimization is set to true, an action client can handle up to 6 goals
34+
* simultaneously. If the number of goals exceeds the limit, optimization is automatically disabled.
35+
*
3336
* \param[in] node_base_interface The node base interface of the corresponding node.
3437
* \param[in] node_graph_interface The node graph interface of the corresponding node.
3538
* \param[in] node_logging_interface The node logging interface of the corresponding node.
3639
* \param[in] node_waitables_interface The node waitables interface of the corresponding node.
3740
* \param[in] name The action name.
41+
* \param[in] enable_feedback_msg_optimization Enable feedback subscription content filter to
42+
* reduce network load.
3843
* \param[in] group The action client will be added to this callback group.
3944
* If `nullptr`, then the action client is added to the default callback group.
4045
* \param[in] options Options to pass to the underlying `rcl_action_client_t`.
@@ -47,6 +52,7 @@ create_client(
4752
rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr node_logging_interface,
4853
rclcpp::node_interfaces::NodeWaitablesInterface::SharedPtr node_waitables_interface,
4954
const std::string & name,
55+
bool enable_feedback_msg_optimization = false,
5056
rclcpp::CallbackGroup::SharedPtr group = nullptr,
5157
const rcl_action_client_options_t & options = rcl_action_client_get_default_options())
5258
{
@@ -85,6 +91,7 @@ create_client(
8591
node_graph_interface,
8692
node_logging_interface,
8793
name,
94+
enable_feedback_msg_optimization,
8895
options),
8996
deleter);
9097

@@ -105,6 +112,7 @@ typename Client<ActionT>::SharedPtr
105112
create_client(
106113
NodeT node,
107114
const std::string & name,
115+
bool enable_feedback_msg_optimization = false,
108116
rclcpp::CallbackGroup::SharedPtr group = nullptr,
109117
const rcl_action_client_options_t & options = rcl_action_client_get_default_options())
110118
{
@@ -114,6 +122,7 @@ create_client(
114122
node->get_node_logging_interface(),
115123
node->get_node_waitables_interface(),
116124
name,
125+
enable_feedback_msg_optimization,
117126
group,
118127
options);
119128
}

rclcpp_action/src/client_base.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -830,4 +830,23 @@ ClientBase::configure_introspection(
830830
}
831831
}
832832

833+
bool
834+
ClientBase::configure_feedback_subscription_filter_add_goal_id(
835+
const GoalUUID & goal_id)
836+
{
837+
const rcl_ret_t ret = rcl_action_client_configure_feedback_subscription_filter_add_goal_id(
838+
pimpl_->client_handle.get(), goal_id.data(), goal_id.size());
839+
840+
return ret == RCL_RET_OK;
841+
}
842+
843+
bool
844+
ClientBase::configure_feedback_subscription_filter_remove_goal_id(
845+
const GoalUUID & goal_id)
846+
{
847+
const rcl_ret_t ret = rcl_action_client_configure_feedback_subscription_filter_remove_goal_id(
848+
pimpl_->client_handle.get(), goal_id.data(), goal_id.size());
849+
850+
return ret == RCL_RET_OK;
851+
}
833852
} // namespace rclcpp_action

0 commit comments

Comments
 (0)