@@ -111,24 +111,30 @@ 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,
126- const rcl_action_client_options_t & client_options = rcl_action_client_get_default_options()
131+ const rcl_action_client_options_t & client_options = rcl_action_client_get_default_options(),
132+ bool enable_feedback_msg_optimization = false
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, enable_feedback_msg_optimization )
132138 {
133139 }
134140
@@ -180,6 +186,19 @@ class Client : public ClientBase
180186 }
181187 return ;
182188 }
189+
190+ // If feedback message optimization is enabled, add goal id to feedback subscription
191+ // content filter
192+ if (enable_feedback_msg_optimization_) {
193+ std::lock_guard<std::mutex> lock (configure_feedback_sub_content_filter_mutex_);
194+ if (!configure_feedback_subscription_filter_add_goal_id (goal_request->goal_id .uuid )) {
195+ RCLCPP_ERROR (
196+ this ->get_logger (),
197+ " Failed to add goal id to feedback subscription content filter for action client." );
198+ enable_feedback_msg_optimization_ = false ;
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,22 @@ 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_ .load ()) {
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+ this ->enable_feedback_msg_optimization_ .store (false );
555+ }
556+ }
522557 std::lock_guard<std::recursive_mutex> lock (goal_handles_mutex_);
523558 goal_handles_.erase (goal_handle->get_goal_id ());
524559 });
@@ -539,9 +574,27 @@ class Client : public ClientBase
539574 std::shared_future<typename CancelResponse::SharedPtr> future (promise->get_future ());
540575 this ->send_cancel_request (
541576 std::static_pointer_cast<void >(cancel_request),
542- [cancel_callback, promise](std::shared_ptr<void > response) mutable
577+ [this , cancel_callback, promise](std::shared_ptr<void > response) mutable
543578 {
544579 auto cancel_response = std::static_pointer_cast<CancelResponse>(response);
580+
581+ // If feedback message optimization is enabled, remove goal id from feedback subscription
582+ // content filter
583+ if (this ->enable_feedback_msg_optimization_ .load ()) {
584+ for (const auto & goal_info : cancel_response->goals_canceling ) {
585+ std::lock_guard<std::mutex> lock (this ->configure_feedback_sub_content_filter_mutex_ );
586+ if (!this ->configure_feedback_subscription_filter_remove_goal_id (
587+ goal_info.goal_id .uuid ))
588+ {
589+ RCLCPP_ERROR (
590+ this ->get_logger (),
591+ " Failed to remove goal id from feedback subscription content filter for action "
592+ " client." );
593+ }
594+ this ->enable_feedback_msg_optimization_ .store (false );
595+ }
596+ }
597+
545598 promise->set_value (cancel_response);
546599 if (cancel_callback) {
547600 cancel_callback (cancel_response);
0 commit comments