ROS2ActionBase.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #pragma once
  9. #include <AzCore/std/functional.h>
  10. #include <Interfaces/IROS2HandlerBase.h>
  11. #include <Utils/RegistryUtils.h>
  12. #include <rclcpp_action/rclcpp_action.hpp>
  13. #include <simulation_interfaces/msg/simulator_features.hpp>
  14. namespace ROS2SimulationInterfaces
  15. {
  16. //! Base for each ROS 2 action server handler, forces declaration of features provided by the server
  17. //! combined information along all ROS 2 handlers gives information about simulation features
  18. //! @see https://github.com/ros-simulation/simulation_interfaces/blob/main/msg/SimulatorFeatures.msg
  19. using SimulationFeatures = simulation_interfaces::msg::SimulatorFeatures;
  20. template<typename RosActionType>
  21. class ROS2ActionBase : public virtual IROS2HandlerBase
  22. {
  23. public:
  24. using Result = typename RosActionType::Result;
  25. using Feedback = typename RosActionType::Feedback;
  26. using Goal = typename RosActionType::Goal;
  27. using ActionHandle = typename rclcpp_action::Server<RosActionType>::SharedPtr;
  28. using GoalHandle = rclcpp_action::ServerGoalHandle<RosActionType>;
  29. virtual ~ROS2ActionBase() = default;
  30. void Initialize(rclcpp::Node::SharedPtr& node) override
  31. {
  32. CreateAction(node);
  33. }
  34. protected:
  35. //! This function is called when the action is cancelled
  36. virtual void CancelGoal(std::shared_ptr<Result> result)
  37. {
  38. AZ_Assert(m_goalHandle, "Invalid goal handle!");
  39. if (m_goalHandle && m_goalHandle->is_canceling())
  40. {
  41. m_goalHandle->canceled(result);
  42. m_goalHandle.reset();
  43. }
  44. }
  45. //! This function is called when the action successfully finished
  46. virtual void GoalSuccess(std::shared_ptr<Result> result)
  47. {
  48. AZ_Assert(m_goalHandle, "Invalid goal handle!");
  49. if (m_goalHandle && (m_goalHandle->is_executing() || m_goalHandle->is_canceling()))
  50. {
  51. m_goalHandle->succeed(result);
  52. m_goalHandle.reset();
  53. }
  54. }
  55. //! This function is called on demand, based on the action server implementation, to share the action progress
  56. virtual void PublishFeedback(std::shared_ptr<Feedback> feedback)
  57. {
  58. AZ_Assert(m_goalHandle, "Invalid goal handle!");
  59. if (m_goalHandle && m_goalHandle->is_executing())
  60. {
  61. m_goalHandle->publish_feedback(feedback);
  62. }
  63. }
  64. //! This function check if the server is ready to handle new goal
  65. virtual bool IsReadyForExecution() const
  66. {
  67. // Has no goal handle yet - can be accepted.
  68. if (!m_goalHandle)
  69. {
  70. return true;
  71. }
  72. // Accept if the previous one is in a terminal state.
  73. return !(m_goalHandle->is_active() || m_goalHandle->is_executing() || m_goalHandle->is_canceling());
  74. }
  75. //! This function is called when the new goal receives
  76. virtual rclcpp_action::GoalResponse GoalReceivedCallback(const rclcpp_action::GoalUUID& uuid, std::shared_ptr<const Goal> goal) = 0;
  77. //! This function is called when the currently executed goal is cancelled
  78. virtual rclcpp_action::CancelResponse GoalCancelledCallback(const std::shared_ptr<GoalHandle> goal_handle) = 0;
  79. //! This function is called when the newly received goal is accepted
  80. virtual void GoalAcceptedCallback(const std::shared_ptr<GoalHandle> goal_handle) = 0;
  81. //! return features id defined by the handler, ids must follow the definition inside standard:
  82. //! @see https://github.com/ros-simulation/simulation_interfaces/blob/main/msg/SimulatorFeatures.msg
  83. AZStd::unordered_set<AZ::u8> GetProvidedFeatures() override
  84. {
  85. return {};
  86. };
  87. std::shared_ptr<GoalHandle> m_goalHandle;
  88. private:
  89. void CreateAction(rclcpp::Node::SharedPtr& node)
  90. {
  91. // Get the action name from the type name
  92. AZStd::string actionName = RegistryUtilities::GetName(GetTypeName());
  93. if (actionName.empty())
  94. {
  95. // if the action name is empty, use the default name
  96. actionName = GetDefaultName();
  97. }
  98. const std::string actionNameStr{ actionName.c_str(), actionName.size() };
  99. m_actionHandle = rclcpp_action::create_server<RosActionType>(
  100. node,
  101. actionNameStr,
  102. AZStd::bind(&ROS2ActionBase::GoalReceivedCallback, this, AZStd::placeholders::_1, AZStd::placeholders::_2),
  103. AZStd::bind(&ROS2ActionBase::GoalCancelledCallback, this, AZStd::placeholders::_1),
  104. AZStd::bind(&ROS2ActionBase::GoalAcceptedCallback, this, AZStd::placeholders::_1));
  105. }
  106. ActionHandle m_actionHandle;
  107. };
  108. } // namespace ROS2SimulationInterfaces