124 virtual bool onCancelRequest(std::shared_ptr<const Goal> goal_ptr, std::shared_ptr<Result> result_ptr);
137 virtual Status
cancelGoal(std::shared_ptr<const Goal> goal_ptr, std::shared_ptr<Result> result_ptr);
150 std::shared_ptr<const Goal> goal_ptr, std::shared_ptr<Feedback> feedback_ptr,
151 std::shared_ptr<Result> result_ptr) = 0;
157 rclcpp_action::GoalResponse handle_goal_(
const rclcpp_action::GoalUUID & uuid, std::shared_ptr<const Goal> goal_ptr);
158 rclcpp_action::CancelResponse handle_cancel_(std::shared_ptr<GoalHandle> goal_handle_ptr);
159 void handle_accepted_(std::shared_ptr<GoalHandle> goal_handle_ptr);
161 void execution_timer_callback_(std::shared_ptr<const Goal> goal_ptr);
164 rclcpp::node_interfaces::NodeBaseInterface::SharedPtr get_node_base_interface()
const;
167 rclcpp::Node::SharedPtr node_ptr_;
168 std::shared_ptr<ActionContextType> action_context_ptr_;
169 const ParamListener param_listener_;
172 typename rclcpp_action::Server<ActionT>::SharedPtr action_server_ptr_;
173 rclcpp::TimerBase::SharedPtr execution_timer_ptr_;
174 rclcpp::Time last_feedback_ts_;
177template <
class ActionT>
179 const std::string & action_name, rclcpp::Node::SharedPtr node_ptr,
180 std::shared_ptr<ActionContextType> action_context_ptr)
181: node_ptr_(node_ptr), action_context_ptr_(action_context_ptr), param_listener_(node_ptr)
185 using namespace std::placeholders;
186 action_server_ptr_ = rclcpp_action::create_server<ActionT>(
187 node_ptr_, action_name, std::bind(&ActionWrapper<ActionT>::handle_goal_,
this, _1, _2),
188 std::bind(&ActionWrapper<ActionT>::handle_cancel_,
this, _1),
189 std::bind(&ActionWrapper<ActionT>::handle_accepted_,
this, _1));
192template <
class ActionT>
194:
ActionWrapper(action_name, node_ptr, std::make_shared<ActionContextType>(node_ptr->get_logger()))
198template <
class ActionT>
200:
ActionWrapper(action_name, std::make_shared<rclcpp::Node>(action_name +
"_node", options))
204template <
class ActionT>
205rclcpp::node_interfaces::NodeBaseInterface::SharedPtr ActionWrapper<ActionT>::get_node_base_interface()
const
207 return node_ptr_->get_node_base_interface();
210template <
class ActionT>
217template <
class ActionT>
219 std::shared_ptr<const Goal> , std::shared_ptr<Result> )
224template <
class ActionT>
226 std::shared_ptr<const Goal> , std::shared_ptr<Result> )
232template <
class ActionT>
234 std::shared_ptr<const Goal> , std::shared_ptr<Result> )
237 return ActionStatus::SUCCESS;
240template <
class ActionT>
241rclcpp_action::GoalResponse ActionWrapper<ActionT>::handle_goal_(
242 const rclcpp_action::GoalUUID & uuid, std::shared_ptr<const Goal> goal_ptr)
244 if (action_context_ptr_->isValid() && action_context_ptr_->getGoalHandlePtr()->is_active()) {
246 node_ptr_->get_logger(),
"Goal %s was REJECTED: Goal %s is still executing.",
247 rclcpp_action::to_string(uuid).c_str(),
248 rclcpp_action::to_string(action_context_ptr_->getGoalHandlePtr()->get_goal_id()).c_str());
249 return rclcpp_action::GoalResponse::REJECT;
252 if (!onGoalRequest(goal_ptr)) {
254 node_ptr_->get_logger(),
"Goal %s was REJECTED because onGoalRequest() returned false",
255 rclcpp_action::to_string(uuid).c_str());
256 return rclcpp_action::GoalResponse::REJECT;
259 return rclcpp_action::GoalResponse::ACCEPT_AND_EXECUTE;
262template <
class ActionT>
263rclcpp_action::CancelResponse ActionWrapper<ActionT>::handle_cancel_(std::shared_ptr<GoalHandle> )
265 return onCancelRequest(action_context_ptr_->getGoalHandlePtr()->get_goal(), action_context_ptr_->getResultPtr())
266 ? rclcpp_action::CancelResponse::ACCEPT
267 : rclcpp_action::CancelResponse::REJECT;
270template <
class ActionT>
271void ActionWrapper<ActionT>::handle_accepted_(std::shared_ptr<GoalHandle> goal_handle_ptr)
273 action_context_ptr_->setUp(goal_handle_ptr);
274 std::shared_ptr<const Goal> goal_ptr = action_context_ptr_->getGoalHandlePtr()->get_goal();
275 setInitialResult(goal_ptr, action_context_ptr_->getResultPtr());
276 (void)goal_handle_ptr;
278 const Params & params = param_listener_.get_params();
281 last_feedback_ts_ = node_ptr_->now() - rclcpp::Duration::from_seconds(params.feedback_rate);
284 execution_timer_ptr_ = node_ptr_->create_wall_timer(
285 std::chrono::duration<double>(params.loop_rate), [
this, goal_ptr]() { this->execution_timer_callback_(goal_ptr); });
288template <
class ActionT>
289void ActionWrapper<ActionT>::execution_timer_callback_(std::shared_ptr<const Goal> goal_ptr)
292 if (!action_context_ptr_->getGoalHandlePtr()->is_active()) {
293 execution_timer_ptr_->cancel();
298 if (action_context_ptr_->getGoalHandlePtr()->is_canceling()) {
299 switch (cancelGoal(goal_ptr, action_context_ptr_->getResultPtr())) {
300 case ActionStatus::RUNNING:
302 case ActionStatus::SUCCESS:
303 action_context_ptr_->cancel();
305 case ActionStatus::FAILURE:
306 action_context_ptr_->abort();
310 const auto ret = executeGoal(goal_ptr, action_context_ptr_->getFeedbackPtr(), action_context_ptr_->getResultPtr());
313 const auto feedback_rate = rclcpp::Duration::from_seconds(param_listener_.get_params().feedback_rate);
314 if (node_ptr_->now() - last_feedback_ts_ > feedback_rate) {
315 action_context_ptr_->publishFeedback();
316 last_feedback_ts_ = node_ptr_->now();
320 case ActionStatus::RUNNING:
322 case ActionStatus::SUCCESS:
323 action_context_ptr_->succeed();
325 case ActionStatus::FAILURE:
326 action_context_ptr_->abort();