FollowJointTrajectoryActionServer.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  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. #include "FollowJointTrajectoryActionServer.h"
  9. #include <AzCore/std/functional.h>
  10. #include <ROS2/ROS2Bus.h>
  11. namespace ROS2Controllers
  12. {
  13. FollowJointTrajectoryActionServer::FollowJointTrajectoryActionServer(const AZStd::string& actionName, const AZ::EntityId& entityId)
  14. : m_entityId(entityId)
  15. {
  16. m_actionServer = rclcpp_action::create_server<FollowJointTrajectory>(
  17. ROS2::ROS2Interface::Get()->GetNode(),
  18. actionName.c_str(),
  19. AZStd::bind(&FollowJointTrajectoryActionServer::GoalReceivedCallback, this, AZStd::placeholders::_1, AZStd::placeholders::_2),
  20. AZStd::bind(&FollowJointTrajectoryActionServer::GoalCancelledCallback, this, AZStd::placeholders::_1),
  21. AZStd::bind(&FollowJointTrajectoryActionServer::GoalAcceptedCallback, this, AZStd::placeholders::_1));
  22. }
  23. void FollowJointTrajectoryActionServer::CancelGoal(std::shared_ptr<FollowJointTrajectory::Result> result)
  24. {
  25. AZ_Assert(m_goalHandle, "Invalid goal handle!");
  26. if (m_goalHandle && m_goalHandle->is_canceling())
  27. {
  28. AZ_Trace("FollowJointTrajectoryActionServer", "Cancelling goal\n");
  29. m_goalHandle->canceled(result);
  30. }
  31. }
  32. void FollowJointTrajectoryActionServer::GoalSuccess(std::shared_ptr<FollowJointTrajectory::Result> result)
  33. {
  34. AZ_Assert(m_goalHandle, "Invalid goal handle!");
  35. if (m_goalHandle && m_goalHandle->is_executing())
  36. {
  37. AZ_Trace("FollowJointTrajectoryActionServer", "Goal succeeded\n");
  38. m_goalHandle->succeed(result);
  39. }
  40. }
  41. void FollowJointTrajectoryActionServer::PublishFeedback(std::shared_ptr<FollowJointTrajectory::Feedback> feedback)
  42. {
  43. AZ_Assert(m_goalHandle, "Invalid goal handle!");
  44. if (m_goalHandle && m_goalHandle->is_executing())
  45. {
  46. m_goalHandle->publish_feedback(feedback);
  47. }
  48. }
  49. bool FollowJointTrajectoryActionServer::IsGoalActiveState() const
  50. {
  51. return m_goalHandle->is_active() || m_goalHandle->is_executing() || m_goalHandle->is_canceling();
  52. }
  53. bool FollowJointTrajectoryActionServer::IsReadyForExecution() const
  54. {
  55. // Has a goal handle yet - can be accepted.
  56. if (!m_goalHandle)
  57. {
  58. return true;
  59. }
  60. // accept goal if previous is terminal state
  61. return IsGoalActiveState() == false;
  62. }
  63. bool FollowJointTrajectoryActionServer::IsExecuting() const
  64. {
  65. return m_goalHandle && m_goalHandle->is_executing();
  66. }
  67. rclcpp_action::GoalResponse FollowJointTrajectoryActionServer::GoalReceivedCallback(
  68. [[maybe_unused]] const rclcpp_action::GoalUUID& uuid, [[maybe_unused]] std::shared_ptr<const FollowJointTrajectory::Goal> goal)
  69. { // Accept each received goal. It will be aborted if other goal is active (no deferring/queuing).
  70. return rclcpp_action::GoalResponse::ACCEPT_AND_EXECUTE;
  71. }
  72. rclcpp_action::CancelResponse FollowJointTrajectoryActionServer::GoalCancelledCallback(
  73. [[maybe_unused]] const std::shared_ptr<GoalHandle> goalHandle)
  74. { // Accept each cancel attempt
  75. AZ::Outcome<void, AZStd::string> cancelOutcome;
  76. JointsTrajectoryRequestBus::EventResult(cancelOutcome, m_entityId, &JointsTrajectoryRequests::CancelTrajectoryGoal);
  77. if (!cancelOutcome)
  78. { // This will not happen in simulation unless intentionally done for behavior validation
  79. AZ_Trace("FollowJointTrajectoryActionServer", "Cancelling could not be accepted: %s\n", cancelOutcome.GetError().c_str());
  80. return rclcpp_action::CancelResponse::REJECT;
  81. }
  82. return rclcpp_action::CancelResponse::ACCEPT;
  83. }
  84. void FollowJointTrajectoryActionServer::GoalAcceptedCallback(const std::shared_ptr<GoalHandle> goalHandle)
  85. {
  86. AZ_Trace("FollowJointTrajectoryActionServer", "Goal accepted\n");
  87. if (!IsReadyForExecution())
  88. {
  89. AZ_Trace("FollowJointTrajectoryActionServer", "Goal aborted: server is not ready for execution!");
  90. if (m_goalHandle)
  91. {
  92. AZ_Trace(
  93. "FollowJointTrajectoryActionServer",
  94. " is_active: %d, is_executing %d, is_canceling : %d",
  95. m_goalHandle->is_active(),
  96. m_goalHandle->is_executing(),
  97. m_goalHandle->is_canceling());
  98. }
  99. auto result = std::make_shared<FollowJointTrajectory::Result>();
  100. result->error_string = "Goal aborted: server is not ready for execution!";
  101. result->error_code = FollowJointTrajectory::Result::INVALID_GOAL;
  102. goalHandle->abort(result);
  103. return;
  104. }
  105. AZ::Outcome<void, FollowJointTrajectory::Result> executionOrderOutcome;
  106. JointsTrajectoryRequestBus::EventResult(
  107. executionOrderOutcome, m_entityId, &JointsTrajectoryRequests::StartTrajectoryGoal, goalHandle->get_goal());
  108. if (!executionOrderOutcome)
  109. {
  110. AZ_Trace(
  111. "FollowJointTrajectoryActionServer",
  112. "Execution was not accepted: %s",
  113. executionOrderOutcome.GetError().error_string.c_str());
  114. auto result = std::make_shared<FollowJointTrajectory::Result>(executionOrderOutcome.GetError());
  115. goalHandle->abort(result);
  116. return;
  117. }
  118. m_goalHandle = goalHandle;
  119. // m_goalHandle->execute(); // No need to call this, as we are already executing the goal due to ACCEPT_AND_EXECUTE
  120. }
  121. } // namespace ROS2Controllers