KrakenEffectorComponent.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  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 "KrakenEffectorComponent.h"
  9. #include "ApplePickingNotifications.h"
  10. #include "Manipulator/ManipulatorRequestBus.h"
  11. #include "PickingStructs.h"
  12. #include "ROS2/VehicleDynamics/VehicleInputControlBus.h"
  13. #include <AzCore/Component/Entity.h>
  14. #include <AzCore/Component/ComponentApplicationBus.h>
  15. #include <AzCore/Component/TransformBus.h>
  16. #include <AzCore/Serialization/EditContext.h>
  17. #include <AzCore/Serialization/EditContextConstants.inl>
  18. #include <AzCore/Serialization/SerializeContext.h>
  19. #include <AzFramework/Physics/Common/PhysicsSimulatedBody.h>
  20. #include <AzFramework/Physics/RigidBodyBus.h>
  21. #include <LmbrCentral/Shape/BoxShapeComponentBus.h>
  22. namespace AppleKraken
  23. {
  24. namespace DebugStateTransit
  25. {
  26. static const AZStd::unordered_map<EffectorState, const char*> kMapToString{ { EffectorState::INVALID, "INVALID" },
  27. { EffectorState::IDLE, "IDLE" },
  28. { EffectorState::PREPARED, "PREPARED" },
  29. { EffectorState::PICKING, "PICKING" },
  30. { EffectorState::PICKING_STABILIZE, "PICKING_STABILIZE" },
  31. { EffectorState::RETRIEVING_NOSE, "RETRIEVING_NOSE" },
  32. { EffectorState::RETRIEVING, "RETRIEVING" },
  33. { EffectorState::RETRIEVING_STABILIZE,
  34. "RETRIEVING_STABILIZE" },
  35. { EffectorState::RETRIEVING_FAILED,
  36. "RETRIEVING_FAILED" } };
  37. // TODO - this is a debug space for a stub implementation. Proper: a state transition machine with lambdas.
  38. AZStd::string StateTransitionString(EffectorState current, EffectorState next)
  39. {
  40. return AZStd::string::format("state transition %s -> %s\n", kMapToString.at(current), kMapToString.at(next));
  41. }
  42. } // namespace DebugStateTransit
  43. KrakenEffectorComponent::KrakenEffectorComponent()
  44. {
  45. InitializeStateProperties();
  46. }
  47. void KrakenEffectorComponent::Activate()
  48. {
  49. ApplePickingRequestBus::Handler::BusConnect(GetEntityId());
  50. AZ::TickBus::Handler::BusConnect();
  51. ImGui::ImGuiUpdateListenerBus::Handler::BusConnect();
  52. EBUS_EVENT_ID_RESULT(m_appleProbe, m_manipulatorEntity, ManipulatorRequestBus, GetEffectorEntity);
  53. EBUS_EVENT_ID_RESULT(m_restEntityId, m_manipulatorEntity, ManipulatorRequestBus, GetRestEntity);
  54. m_onTriggerHandleBeginHandler = AzPhysics::SimulatedBodyEvents::OnTriggerEnter::Handler(
  55. [&]([[maybe_unused]] AzPhysics::SimulatedBodyHandle bodyHandle, [[maybe_unused]] const AzPhysics::TriggerEvent& event)
  56. {
  57. const AZ::EntityId& e1 = event.m_otherBody->GetEntityId();
  58. const AZ::EntityId& e2 = event.m_triggerBody->GetEntityId();
  59. [[maybe_unused]] const AZ::EntityId& collideToEntityId = m_appleProbe == e1 ? e2 : e1;
  60. // AZStd::string entity_name;
  61. // AZ::ComponentApplicationBus::BroadcastResult(entity_name,
  62. // &AZ::ComponentApplicationRequests::GetEntityName, collideToEntityId);
  63. // AZ_Printf("m_onTriggerHandleBeginHandler", "Collission %s\n", entity_name.c_str());
  64. // AzPhysics::SimulatedBody* collideToEntityId = this->GetEntityId() == e1 ? event.m_triggerBody : event.m_otherBody;}
  65. if (m_currentTask.m_appleEntityId == collideToEntityId)
  66. {
  67. AZ_TracePrintf("m_onTriggerHandleBeginHandler", " %s : m_onTriggerHandle to Apple!====================",
  68. GetEntity()->GetName().c_str());
  69. ApplePickingNotificationBus::Event(this->GetEntityId(),&ApplePickingNotifications::ApplePicked);
  70. if (m_effectorState == EffectorState::PICKING)
  71. {
  72. // start picking the apple
  73. BeginTransitionIfAcceptable(EffectorState::PICKING_STABILIZE);
  74. }
  75. }
  76. if (m_restEntityId == collideToEntityId)
  77. {
  78. AZ_TracePrintf("m_onTriggerHandleBeginHandler", "%s : m_onTriggerHandle to Rest!====================",
  79. GetEntity()->GetName().c_str());
  80. if (m_effectorState == EffectorState::RETRIEVING || m_effectorState == EffectorState::RETRIEVING_NOSE )
  81. {
  82. // start picking the apple
  83. BeginTransitionIfAcceptable(EffectorState::RETRIEVING_STABILIZE);
  84. }
  85. }
  86. });
  87. }
  88. void KrakenEffectorComponent::Deactivate()
  89. {
  90. AZ::TickBus::Handler::BusDisconnect();
  91. ApplePickingRequestBus::Handler::BusDisconnect();
  92. ImGui::ImGuiUpdateListenerBus::Handler::BusDisconnect();
  93. }
  94. void KrakenEffectorComponent::Reflect(AZ::ReflectContext* context)
  95. {
  96. if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context))
  97. {
  98. serialize->Class<KrakenEffectorComponent, AZ::Component>()
  99. ->Version(4)
  100. ->Field("ReachEntity", &KrakenEffectorComponent::m_reachEntity)
  101. ->Field("ManipulatorEntity", &KrakenEffectorComponent::m_manipulatorEntity)
  102. ->Field("RootManipulatorFreeze", &KrakenEffectorComponent::m_rootEntityToFreeze)
  103. ->Field("BaseLinkToKinematic", &KrakenEffectorComponent::m_baseLinkToKinematic)
  104. ->Field("PickStabilizeTime", &KrakenEffectorComponent::m_stabilize_time)
  105. ->Field("MaxPickingTime", &KrakenEffectorComponent::m_maxPickingTime);
  106. if (AZ::EditContext* ec = serialize->GetEditContext())
  107. {
  108. ec->Class<KrakenEffectorComponent>("Kraken Effector", "Manipulator component for picking apples")
  109. ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
  110. ->Attribute(AZ::Edit::Attributes::Category, "AppleKraken")
  111. ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game"))
  112. ->DataElement(
  113. AZ::Edit::UIHandlers::EntityId,
  114. &KrakenEffectorComponent::m_reachEntity,
  115. "Kraken Reach entity",
  116. "Kraken entity with box shape to set reach area")
  117. ->DataElement(
  118. AZ::Edit::UIHandlers::EntityId,
  119. &KrakenEffectorComponent::m_manipulatorEntity,
  120. "Entity with manipulator",
  121. "The entity that has a component handling events from ManipulatorRequestBus")
  122. ->DataElement(
  123. AZ::Edit::UIHandlers::EntityId,
  124. &KrakenEffectorComponent::m_rootEntityToFreeze,
  125. "RootManipulatorFreeze",
  126. "RootManipulatorFreeze to freeze during robot movement")
  127. ->DataElement(
  128. AZ::Edit::UIHandlers::EntityId,
  129. &KrakenEffectorComponent::m_baseLinkToKinematic,
  130. "BaseLinkToKinematic",
  131. "BaseLinkToKinematic during manipulator movement")
  132. ->DataElement(
  133. AZ::Edit::UIHandlers::EntityId,
  134. &KrakenEffectorComponent::m_stabilize_time,
  135. "PickStabilizeTime",
  136. "PickStabilizeTime")
  137. ->DataElement(
  138. AZ::Edit::UIHandlers::EntityId, &KrakenEffectorComponent::m_maxPickingTime, "MaxPickingTime", "MaxPickingTime")
  139. ->Attribute(AZ::Edit::Attributes::AutoExpand, true);
  140. }
  141. }
  142. }
  143. void KrakenEffectorComponent::PrepareForPicking()
  144. {
  145. AZ_TracePrintf("KrakenEffectorComponent", "%s: PrepareForPicking\n", GetEntity()->GetName().c_str());
  146. BeginTransitionIfAcceptable(EffectorState::PREPARED);
  147. }
  148. void KrakenEffectorComponent::PickApple(const PickAppleTask& appleTask)
  149. {
  150. AZ_TracePrintf("KrakenEffectorComponent", "%s: PickApple\n", GetEntity()->GetName().c_str());
  151. // TODO - handle appleTask
  152. m_currentTask = appleTask;
  153. ManipulatorRequestBus::Event(m_manipulatorEntity, &ManipulatorRequest::PickApple, appleTask.m_middle);
  154. BeginTransitionIfAcceptable(EffectorState::PICKING);
  155. }
  156. void KrakenEffectorComponent::FinishPicking()
  157. {
  158. AZ_TracePrintf("KrakenEffectorComponent", "%s : FinishPicking\n", GetEntity()->GetName().c_str());
  159. BeginTransitionIfAcceptable(EffectorState::IDLE);
  160. }
  161. PickingState KrakenEffectorComponent::GetEffectorState()
  162. {
  163. PickingState state;
  164. state.m_effectorState = m_effectorState;
  165. state.m_taskProgress = 0.0f; // TODO
  166. state.m_description = DebugStateTransit::kMapToString.at(m_effectorState);
  167. if (m_currentTask.IsValid())
  168. {
  169. state.m_currentTask = m_currentTask;
  170. }
  171. return state;
  172. }
  173. AZ::Obb KrakenEffectorComponent::GetEffectorReachArea()
  174. {
  175. AZ::Obb reachArea;
  176. if (m_reachEntity.IsValid())
  177. {
  178. AZ::Transform targetTM = AZ::Transform::CreateIdentity();
  179. AZ::TransformBus::EventResult(targetTM, m_reachEntity, &AZ::TransformBus::Events::GetWorldTM);
  180. AZ::Vector3 dimensions = AZ::Vector3{ 0.f };
  181. LmbrCentral::BoxShapeComponentRequestsBus::EventResult(
  182. dimensions, m_reachEntity, &LmbrCentral::BoxShapeComponentRequests::GetBoxDimensions);
  183. if (!dimensions.IsZero())
  184. {
  185. reachArea.SetHalfLengths(dimensions / 2);
  186. reachArea.SetPosition(targetTM.GetTranslation());
  187. reachArea.SetRotation(targetTM.GetRotation());
  188. return reachArea;
  189. }
  190. AZ_Warning(
  191. "KrakenEffectorComponent", true, "Reach entity %s does not have BoxShapeComponent!", m_reachEntity.ToString().c_str());
  192. }
  193. AZ_Warning("KrakenEffectorComponent", true, "GetEffectorReachArea - returning invalid reach");
  194. reachArea.SetHalfLengths(AZ::Vector3{ 0, 0, 0 });
  195. reachArea.SetPosition(AZ::Vector3{ 0, 0, 0 }); /// TODO - get it from entity With box
  196. return reachArea;
  197. }
  198. void KrakenEffectorComponent::OnTick(float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time)
  199. {
  200. m_currentStateTransitionTime += deltaTime;
  201. GetCurrentStateAction()();
  202. if (m_effectorState == m_effectorTargetState)
  203. { // //TODO - nothing to do in stub version
  204. return;
  205. }
  206. // State transition
  207. AZ_TracePrintf(
  208. "KrakenEffectorComponent", "%s : %s", GetEntity()->GetName().c_str(), DebugStateTransit::StateTransitionString(m_effectorState, m_effectorTargetState).c_str());
  209. m_currentStateTransitionTime = 0.0f;
  210. // Update state
  211. auto transitionAction = GetCurrentTransitionAction();
  212. m_effectorState = m_effectorTargetState;
  213. transitionAction();
  214. if (!m_registeredCallback)
  215. {
  216. auto* physicsSystem = AZ::Interface<AzPhysics::SystemInterface>::Get();
  217. auto* sceneInterface = AZ::Interface<AzPhysics::SceneInterface>::Get();
  218. auto [physicScene, physicBody] = physicsSystem->FindAttachedBodyHandleFromEntityId(m_appleProbe);
  219. if (physicBody != AzPhysics::InvalidSimulatedBodyHandle && physicScene != AzPhysics::InvalidSceneHandle)
  220. {
  221. AzPhysics::SimulatedBody* simulated_body = sceneInterface->GetSimulatedBodyFromHandle(physicScene, physicBody);
  222. simulated_body->RegisterOnTriggerEnterHandler(m_onTriggerHandleBeginHandler);
  223. m_registeredCallback = true;
  224. }
  225. }
  226. }
  227. void KrakenEffectorComponent::LockManipulator(bool locked)
  228. {
  229. AZStd::vector<AZ::EntityId> descendants;
  230. AZ::TransformBus::EventResult(descendants, m_rootEntityToFreeze, &AZ::TransformBus::Events::GetAllDescendants);
  231. descendants.push_back(m_rootEntityToFreeze);
  232. if (is_manipulator_locked != locked)
  233. {
  234. if (locked) {
  235. AZ_Printf("KrakenEffectorComponent", "Locking : %s\n", GetEntity()->GetName().c_str());
  236. }
  237. else{
  238. AZ_Printf("KrakenEffectorComponent", "Unlocking : %s\n", GetEntity()->GetName().c_str());
  239. }
  240. for (auto& descadant : descendants)
  241. {
  242. using VehicleBus = ROS2::VehicleDynamics::VehicleInputControlRequestBus;
  243. if (locked)
  244. {
  245. // Lock manipulator, make base_link not kinematic anymore
  246. Physics::RigidBodyRequestBus::Event(descadant, &Physics::RigidBodyRequestBus::Events::DisablePhysics);
  247. Physics::RigidBodyRequestBus::Event(m_baseLinkToKinematic, &Physics::RigidBodyRequestBus::Events::SetKinematic, false);
  248. VehicleBus::Event(m_baseLinkToKinematic, &VehicleBus::Events::SetDisableVehicleDynamics, false);
  249. }
  250. else
  251. {
  252. // loose manipulator, make base_link kinematic
  253. Physics::RigidBodyRequestBus::Event(descadant, &Physics::RigidBodyRequestBus::Events::EnablePhysics);
  254. Physics::RigidBodyRequestBus::Event(m_baseLinkToKinematic, &Physics::RigidBodyRequestBus::Events::SetKinematic, true);
  255. VehicleBus::Event(m_baseLinkToKinematic, &VehicleBus::Events::SetDisableVehicleDynamics, true);
  256. }
  257. }
  258. is_manipulator_locked = locked;
  259. }
  260. }
  261. bool KrakenEffectorComponent::IsTransitionValid(EffectorState targetState) const
  262. {
  263. AZ_Assert(m_effectorState != EffectorState::INVALID, "Effector is in an invalid state! Unable to access transition properties.");
  264. return m_stateProperties.m_allowedTransitions.contains(AZStd::make_pair(m_effectorState, targetState));
  265. }
  266. bool KrakenEffectorComponent::IsTransitionAcceptable(EffectorState targetState) const
  267. {
  268. if (m_effectorState == EffectorState::PICKING && m_effectorState == EffectorState::PICKING)
  269. {
  270. // allow this non-existing state transition without error
  271. return true;
  272. }
  273. if (m_effectorState != m_effectorTargetState)
  274. {
  275. AZ_Error(
  276. "KrakenEffectorComponent",
  277. false,
  278. "%s: Unable to accept request: currently realizing %s", GetEntity()->GetName().c_str(),
  279. DebugStateTransit::StateTransitionString(m_effectorState, m_effectorTargetState).c_str());
  280. return false;
  281. }
  282. if (!IsTransitionValid(targetState))
  283. {
  284. AZ_Error(
  285. "KrakenEffectorComponent",
  286. false,
  287. "%s: Invalid state transition %s",GetEntity()->GetName().c_str(),
  288. DebugStateTransit::StateTransitionString(m_effectorState, m_effectorTargetState).c_str());
  289. return false;
  290. }
  291. return true;
  292. }
  293. void KrakenEffectorComponent::BeginTransitionIfAcceptable(EffectorState targetState)
  294. {
  295. if (IsTransitionAcceptable(targetState))
  296. {
  297. m_currentStateTransitionTime = 0.0f;
  298. m_effectorTargetState = targetState;
  299. }
  300. }
  301. void KrakenEffectorComponent::InitializeStateProperties()
  302. {
  303. m_stateProperties.m_stateActions = {
  304. { EffectorState::IDLE,
  305. [this]()
  306. {
  307. LockManipulator(true);
  308. } },
  309. { EffectorState::PREPARED,
  310. []()
  311. {
  312. } },
  313. { EffectorState::PICKING,
  314. [this]()
  315. {
  316. if (m_currentStateTransitionTime > m_maxPickingTime)
  317. {
  318. AZ_Printf("m_onTriggerHandleBeginHandler", "%s : Failed to retrieve apple--------------------\n", GetEntity()->GetName().c_str());
  319. BeginTransitionIfAcceptable(EffectorState::RETRIEVING_FAILED);
  320. }
  321. } },
  322. { EffectorState::PICKING_STABILIZE,
  323. [this]()
  324. {
  325. if (m_currentStateTransitionTime > m_stabilize_time)
  326. {
  327. BeginTransitionIfAcceptable(EffectorState::RETRIEVING_NOSE);
  328. }
  329. } },
  330. { EffectorState::RETRIEVING_NOSE,
  331. [this]()
  332. {
  333. bool result;
  334. EBUS_EVENT_ID_RESULT(result, m_manipulatorEntity, ManipulatorRequestBus, IsNoseRetreived);
  335. if (result)
  336. {
  337. BeginTransitionIfAcceptable(EffectorState::RETRIEVING);
  338. }
  339. } },
  340. { EffectorState::RETRIEVING_FAILED,
  341. [this]()
  342. {
  343. bool result;
  344. EBUS_EVENT_ID_RESULT(result, m_manipulatorEntity, ManipulatorRequestBus, IsNoseRetreived);
  345. if (result)
  346. {
  347. BeginTransitionIfAcceptable(EffectorState::PREPARED);
  348. }
  349. } },
  350. {EffectorState::RETRIEVING,
  351. [this]() {
  352. // Continue if manipulator retraction was blocked
  353. if (m_currentStateTransitionTime > m_maxRetrieveTime) {
  354. BeginTransitionIfAcceptable(EffectorState::RETRIEVING_STABILIZE);
  355. }
  356. } },
  357. { EffectorState::RETRIEVING_STABILIZE,
  358. [this]()
  359. {
  360. if (m_currentStateTransitionTime > m_stabilize_time)
  361. {
  362. BeginTransitionIfAcceptable(EffectorState::PREPARED);
  363. }
  364. } }
  365. };
  366. m_stateProperties.m_allowedTransitions = {
  367. {
  368. { EffectorState::IDLE, EffectorState::PREPARED },
  369. [this]()
  370. {
  371. LockManipulator(false);
  372. ApplePickingNotificationBus::Event(GetEntityId(),&ApplePickingNotifications::EffectorReadyForPicking);
  373. },
  374. },
  375. {
  376. { EffectorState::PREPARED, EffectorState::PICKING },
  377. []()
  378. {
  379. },
  380. },
  381. {
  382. { EffectorState::PICKING, EffectorState::PICKING_STABILIZE },
  383. []()
  384. {
  385. },
  386. },
  387. {
  388. { EffectorState::PICKING_STABILIZE, EffectorState::RETRIEVING_NOSE },
  389. [this]()
  390. {
  391. if (!m_currentTask.IsValid())
  392. {
  393. AZ_Error("KrakenEffectorComponent", true, "%s : No valid task for current picking!",GetEntity()->GetName().c_str());
  394. return;
  395. }
  396. ManipulatorRequestBus::Event(m_manipulatorEntity, &ManipulatorRequest::RetrieveNose);
  397. },
  398. },
  399. {
  400. { EffectorState::RETRIEVING_NOSE, EffectorState::RETRIEVING },
  401. [this]()
  402. {
  403. ManipulatorRequestBus::Event(m_manipulatorEntity, &ManipulatorRequest::Retrieve);
  404. },
  405. },
  406. { // on skip
  407. { EffectorState::RETRIEVING_NOSE, EffectorState::RETRIEVING_STABILIZE },
  408. [this]()
  409. {
  410. ManipulatorRequestBus::Event(m_manipulatorEntity, &ManipulatorRequest::Retrieve);
  411. },
  412. },
  413. {
  414. { EffectorState::RETRIEVING, EffectorState::RETRIEVING_STABILIZE },
  415. []()
  416. {
  417. },
  418. },
  419. {
  420. { EffectorState::RETRIEVING_FAILED, EffectorState::PREPARED },
  421. [this]()
  422. {
  423. ApplePickingNotificationBus::Event(this->GetEntityId(),&ApplePickingNotifications::PickingFailed, "Timeout");
  424. },
  425. },
  426. {
  427. { EffectorState::RETRIEVING_STABILIZE, EffectorState::PREPARED },
  428. [this]()
  429. {
  430. ApplePickingNotificationBus::Event(GetEntityId(),&ApplePickingNotifications::AppleRetrieved);
  431. },
  432. },
  433. {
  434. { EffectorState::PREPARED, EffectorState::IDLE },
  435. []()
  436. {
  437. },
  438. },
  439. {
  440. { EffectorState::PICKING, EffectorState::IDLE },
  441. [this]()
  442. {
  443. // apple picking was finished with timeout
  444. ManipulatorRequestBus::Event(m_manipulatorEntity, &ManipulatorRequest::Retrieve);
  445. },
  446. },
  447. {
  448. { EffectorState::PICKING, EffectorState::RETRIEVING_FAILED },
  449. [this]()
  450. {
  451. ManipulatorRequestBus::Event(m_manipulatorEntity, &ManipulatorRequest::RetrieveNose);
  452. ManipulatorRequestBus::Event(m_manipulatorEntity, &ManipulatorRequest::ResetApple);
  453. },
  454. },
  455. };
  456. }
  457. const AZStd::function<void()>& KrakenEffectorComponent::GetCurrentStateAction() const
  458. {
  459. AZ_Assert(m_effectorState != EffectorState::INVALID, "%s : Effector is in an invalid state! Unable to access state properties.",GetEntity()->GetName().c_str());
  460. return m_stateProperties.m_stateActions.at(m_effectorState);
  461. }
  462. const AZStd::function<void()>& KrakenEffectorComponent::GetCurrentTransitionAction() const
  463. {
  464. return m_stateProperties.m_allowedTransitions.at(AZStd::make_pair(m_effectorState, m_effectorTargetState));
  465. }
  466. void KrakenEffectorComponent::OnImGuiUpdate(){
  467. AZStd::string window_name = AZStd::string::format("ManipulatorController%s", GetEntityId().ToString().c_str());
  468. ImGui::Begin(window_name.c_str());
  469. const auto & state_name = DebugStateTransit::kMapToString.at(m_effectorState);
  470. ImGui::Text("m_effectorState : %s",state_name);
  471. ImGui::BeginGroup();
  472. ImGui::Text("m_currentTask:");
  473. ImGui::Text("m_appleEntityId : %s",m_currentTask.m_appleEntityId.ToString().c_str());
  474. ImGui::Text("m_middle : %.1f %.1f %.1f",m_currentTask.m_middle.GetX(),m_currentTask.m_middle.GetY(),m_currentTask.m_middle.GetZ());
  475. ImGui::EndGroup();
  476. if (ImGui::CollapsingHeader("KrakenTestApplePicking") && m_reachEntity.IsValid()) {
  477. AZ::Obb r = KrakenEffectorComponent::GetEffectorReachArea();
  478. ImGui::SliderFloat("Horizontal", &m_debugApple[0], -r.GetHalfLengthX(), r.GetHalfLengthX());
  479. ImGui::SliderFloat("Vertical", &m_debugApple[2], -r.GetHalfLengthZ(), r.GetHalfLengthZ());
  480. ImGui::SliderFloat("Nose", &m_debugApple[1], -r.GetHalfLengthY(), r.GetHalfLengthY());
  481. if (ImGui::Button("Send 'PickApple'")) {
  482. AZ::Transform targetTM = AZ::Transform::CreateIdentity();
  483. AZ::TransformBus::EventResult(targetTM, m_reachEntity, &AZ::TransformBus::Events::GetWorldTM);
  484. PickAppleTask appleTask;
  485. appleTask.m_middle = targetTM.TransformPoint(AZ::Vector3::CreateFromFloat3(m_debugApple.data()));
  486. PickApple(appleTask);
  487. }
  488. ImGui::SameLine();
  489. if (ImGui::Button("Send 'PrepareForPicking'")) {
  490. PrepareForPicking();
  491. }
  492. ImGui::SameLine();
  493. if (ImGui::Button("Send 'FinishPicking'")) {
  494. FinishPicking();
  495. }
  496. }
  497. ImGui::End();
  498. };
  499. } // namespace AppleKraken