@@ -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
0 commit comments