KrakenManipulatorController.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  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 "KrakenManipulatorController.h"
  9. #include <ROS2/Manipulation/MotorizedJoints/PidMotorControllerBus.h>
  10. #include <AzCore/Serialization/EditContext.h>
  11. #include <AzFramework/Components/TransformComponent.h>
  12. namespace AppleKraken
  13. {
  14. void ManipulatorController::Activate()
  15. {
  16. ManipulatorRequestBus::Handler::BusConnect(GetEntityId());
  17. AZ::TickBus::Handler::BusConnect();
  18. ImGui::ImGuiUpdateListenerBus::Handler::BusConnect();
  19. initialized = false;
  20. }
  21. void ManipulatorController::Deactivate()
  22. {
  23. ManipulatorRequestBus::Handler::BusDisconnect(GetEntityId());
  24. AZ::TickBus::Handler::BusDisconnect();
  25. ImGui::ImGuiUpdateListenerBus::Handler::BusDisconnect();
  26. }
  27. void ManipulatorController::Reflect(AZ::ReflectContext* context)
  28. {
  29. if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context))
  30. {
  31. serialize->Class<ManipulatorController, AZ::Component>()
  32. ->Version(2)
  33. ->Field("ManipulatorEntityX", &ManipulatorController::m_entityX)
  34. ->Field("ManipulatorEntityY", &ManipulatorController::m_entityY)
  35. ->Field("ManipulatorEntityZ", &ManipulatorController::m_entityZ)
  36. ->Field("ManipulatorVecX", &ManipulatorController::m_vectorX)
  37. ->Field("ManipulatorVecY", &ManipulatorController::m_vectorY)
  38. ->Field("ManipulatorVecZ", &ManipulatorController::m_vectorZ)
  39. ->Field("RestEntity", &ManipulatorController::m_restEntity)
  40. ->Field("m_effector", &ManipulatorController::m_effector)
  41. ->Field("max_errorXZ", &ManipulatorController::max_errorXZ)
  42. ->Field("max_errorY", &ManipulatorController::max_errorY);
  43. if (AZ::EditContext* ec = serialize->GetEditContext())
  44. {
  45. ec->Class<ManipulatorController>("ManipulatorController", "ManipulatorController")
  46. ->ClassElement(AZ::Edit::ClassElements::EditorData, "ManipulatorController")
  47. ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game"))
  48. ->Attribute(AZ::Edit::Attributes::Category, "AppleKraken")
  49. ->DataElement(AZ::Edit::UIHandlers::EntityId, &ManipulatorController::m_entityX, "m_entityX", "m_entityX")
  50. ->DataElement(AZ::Edit::UIHandlers::EntityId, &ManipulatorController::m_entityY, "m_entityY", "m_entityY")
  51. ->DataElement(AZ::Edit::UIHandlers::EntityId, &ManipulatorController::m_entityZ, "m_entity_z1", "m_entityZ")
  52. ->DataElement(AZ::Edit::UIHandlers::EntityId, &ManipulatorController::m_vectorX, "vx", "vx")
  53. ->DataElement(AZ::Edit::UIHandlers::EntityId, &ManipulatorController::m_vectorY, "vy", "vy")
  54. ->DataElement(AZ::Edit::UIHandlers::EntityId, &ManipulatorController::m_vectorZ, "vz", "vz")
  55. ->DataElement(AZ::Edit::UIHandlers::EntityId, &ManipulatorController::m_effector, "Effector", "Effector")
  56. ->DataElement(AZ::Edit::UIHandlers::EntityId, &ManipulatorController::m_restEntity, "Rest entity", "Rest Entity")
  57. ->DataElement(AZ::Edit::UIHandlers::EntityId, &ManipulatorController::max_errorXZ, "max_errorXZ", "max error XZ to retract nose")
  58. ->DataElement(AZ::Edit::UIHandlers::EntityId, &ManipulatorController::max_errorY, "max_errorY", "max error Y to retract nose");
  59. }
  60. }
  61. }
  62. void ManipulatorController::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time)
  63. {
  64. if (!initialized)
  65. {
  66. // get offset to effector
  67. AZ::Transform transformBaseLink;
  68. AZ::TransformBus::EventResult(transformBaseLink, GetEntityId(), &AZ::TransformBus::Events::GetWorldTM);
  69. AZ::Transform transformEffector;
  70. AZ::TransformBus::EventResult(transformEffector, m_effector, &AZ::TransformBus::Events::GetWorldTM);
  71. m_transform_base_link_to_effector = transformBaseLink.GetInverse() * transformEffector;
  72. initialized = true;
  73. return;
  74. }
  75. if (m_desiredApple)
  76. {
  77. m_desiredPosition = *m_desiredApple;
  78. }
  79. else
  80. {
  81. AZ::TransformBus::EventResult(m_desiredPosition, m_restEntity, &AZ::TransformBus::Events::GetWorldTranslation);
  82. }
  83. // apple is given in the World's coordinate system
  84. AZ::Transform current_base_link;
  85. AZ::TransformBus::EventResult(current_base_link, GetEntityId(), &AZ::TransformBus::Events::GetWorldTM);
  86. AZ::Vector3 position_in_baselink_tf = current_base_link.GetInverse().TransformPoint(m_desiredPosition);
  87. AZ::Vector3 position_in_effector_tf = m_transform_base_link_to_effector.GetInverse().TransformPoint(position_in_baselink_tf);
  88. m_setPointX = position_in_effector_tf.Dot(m_vectorX);
  89. m_setPointZ = position_in_effector_tf.Dot(m_vectorZ);
  90. float error_x = std::numeric_limits<float>::max();
  91. float error_z = std::numeric_limits<float>::max();
  92. ROS2::PidMotorControllerRequestBus::Event(m_entityX, &ROS2::PidMotorControllerRequests::SetSetpoint, m_setPointX);
  93. ROS2::PidMotorControllerRequestBus::EventResult(error_x, m_entityX, &ROS2::PidMotorControllerRequests::GetError);
  94. ROS2::PidMotorControllerRequestBus::Event(m_entityZ, &ROS2::PidMotorControllerRequests::SetSetpoint, m_setPointZ);
  95. ROS2::PidMotorControllerRequestBus::EventResult(error_z, m_entityZ, &ROS2::PidMotorControllerRequests::GetError);
  96. // auto - disable nose retrieve only if we reached small error.
  97. if (m_noseRetrieveRequest == true)
  98. {
  99. m_time_XZ_ok += deltaTime;
  100. if (m_time_XZ_ok > m_timeSetpointReach)
  101. {
  102. if (error_x < max_errorXZ && error_x > -max_errorXZ && error_z < max_errorXZ && error_z > -max_errorXZ)
  103. {
  104. AZ_Printf("ManipulatorController", "Nose is sliding out \n");
  105. m_noseRetrieveRequest = false;
  106. m_time_XZ_ok = 0;
  107. }
  108. }
  109. }
  110. m_setPointY = position_in_effector_tf.Dot(m_vectorY);
  111. if (m_entityY.IsValid())
  112. {
  113. if (m_noseRetrieveRequest)
  114. {
  115. m_setPointY = 0;
  116. m_time_Y_ok += deltaTime;
  117. if (m_time_Y_ok > m_timeSetpointReach)
  118. {
  119. float error_y = std::numeric_limits<float>::max();
  120. ROS2::PidMotorControllerRequestBus::EventResult(error_y, m_entityY, &ROS2::PidMotorControllerRequests::GetError);
  121. if (error_y < max_errorY && error_y > -max_errorY)
  122. {
  123. m_noseRetrievingSuccess = true;
  124. m_time_Y_ok = 0.0;
  125. }
  126. }
  127. }
  128. else
  129. {
  130. m_noseRetrievingSuccess = false;
  131. }
  132. ROS2::PidMotorControllerRequestBus::Event(m_entityY, &ROS2::PidMotorControllerRequests::SetSetpoint, m_setPointY);
  133. }
  134. }
  135. void ManipulatorController::PickApple(const AZ::Vector3 position)
  136. {
  137. m_noseRetrieveRequest = true;
  138. m_time_XZ_ok = 0;
  139. AZ_Printf("ManipulatorController", "PickApple\n");
  140. ResetTimer();
  141. m_desiredApple = position;
  142. };
  143. AZ::Vector3 ManipulatorController::GetPosition()
  144. {
  145. float x{0};
  146. float y{0};
  147. float z{0};
  148. ROS2::PidMotorControllerRequestBus::EventResult(x, m_entityX, &ROS2::PidMotorControllerRequests::GetCurrentMeasurement);
  149. ROS2::PidMotorControllerRequestBus::EventResult(y, m_entityY, &ROS2::PidMotorControllerRequests::GetCurrentMeasurement);
  150. ROS2::PidMotorControllerRequestBus::EventResult(z, m_entityZ, &ROS2::PidMotorControllerRequests::GetCurrentMeasurement);
  151. return AZ::Vector3{x,y,z};
  152. };
  153. void ManipulatorController::Retrieve()
  154. {
  155. AZ_Printf("ManipulatorController", "Retrieve\n");
  156. m_time_XZ_ok = std::numeric_limits<float>::lowest();
  157. m_noseRetrieveRequest = true;
  158. ResetApple();
  159. };
  160. void ManipulatorController::ResetApple()
  161. {
  162. m_desiredApple.reset();
  163. };
  164. void ManipulatorController::RetrieveNose()
  165. {
  166. AZ_Printf("ManipulatorController", "RetrieveNose\n");
  167. m_time_XZ_ok = std::numeric_limits<float>::lowest();
  168. m_noseRetrieveRequest = true;
  169. }
  170. int ManipulatorController::GetStatus()
  171. {
  172. return 0;
  173. };
  174. void ManipulatorController::ResetTimer()
  175. {
  176. m_time_XZ_ok = 0;
  177. }
  178. bool ManipulatorController::IsNoseRetreived()
  179. {
  180. return m_noseRetrievingSuccess;
  181. }
  182. AZ::EntityId ManipulatorController::GetEffectorEntity()
  183. {
  184. return m_effector;
  185. }
  186. AZ::EntityId ManipulatorController::GetRestEntity()
  187. {
  188. return m_restEntity;
  189. }
  190. void ManipulatorController::OnImGuiUpdate()
  191. {
  192. AZStd::string window_name = AZStd::string::format("ManipulatorController%s", GetEntityId().ToString().c_str());
  193. ImGui::Begin(window_name.c_str());
  194. auto pos = GetPosition();
  195. if (m_desiredApple){
  196. ImGui::Text("Desired Apple : %.1f %.1f %.1f", m_desiredApple->GetX(),m_desiredApple->GetY(),m_desiredApple->GetZ());
  197. }else{
  198. ImGui::Text("No Desired Apple");
  199. }
  200. if (ImGui::CollapsingHeader("Gantry"))
  201. {
  202. ImGui::Text("Positions : %.1f %.1f", pos.GetX(), pos.GetZ() );
  203. ImGui::Text("SetPoint : %.1f %.1f", m_setPointX, m_setPointZ );
  204. }
  205. if (ImGui::CollapsingHeader("Nose"))
  206. {
  207. ImGui::Text("Positions : %.1f", pos.GetY());
  208. ImGui::Text("SetPoint : %.1f", m_setPointY);
  209. ImGui::Checkbox("noseRetrieveRequest", &m_noseRetrieveRequest);
  210. ImGui::Checkbox("noseRetrievingSuccess", &m_noseRetrievingSuccess);
  211. }
  212. ImGui::End();
  213. }
  214. } // namespace AppleKraken