123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- /*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
- #include "KrakenManipulatorController.h"
- #include <AzCore/Serialization/EditContext.h>
- #include <AzFramework/Components/TransformComponent.h>
- #include <AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI.h>
- namespace AppleKraken
- {
- ROS2::MotorizedJoint* ManipulatorController::getMotorizedJoint(const AZ::EntityId& entityWithMotJoint)
- {
- AZ_Assert(entityWithMotJoint.IsValid(), "Entity Invalid");
- AZ::Entity* e_ptr{ nullptr };
- AZ::ComponentApplicationBus::BroadcastResult(e_ptr, &AZ::ComponentApplicationRequests::FindEntity, entityWithMotJoint);
- AZ_Assert(e_ptr, "No such entity");
- ROS2::MotorizedJoint* component = e_ptr->FindComponent<ROS2::MotorizedJoint>();
- // AZ_Assert(component, "No ROS2::MotorizedJoint in %s", e_ptr->GetName().c_str());
- return component;
- }
- void ManipulatorController::Activate()
- {
- ManipulatorRequestBus::Handler::BusConnect(GetEntityId());
- AZ::TickBus::Handler::BusConnect();
- initialized = false;
- }
- void ManipulatorController::Deactivate()
- {
- ManipulatorRequestBus::Handler::BusDisconnect(GetEntityId());
- AZ::TickBus::Handler::BusDisconnect();
- }
- void ManipulatorController::Reflect(AZ::ReflectContext* context)
- {
- if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context))
- {
- serialize->Class<ManipulatorController, AZ::Component>()
- ->Version(2)
- ->Field("ManipulatorEntityX", &ManipulatorController::m_entityX)
- ->Field("ManipulatorEntityY", &ManipulatorController::m_entityY)
- ->Field("ManipulatorEntityZ", &ManipulatorController::m_entityZ)
- ->Field("ManipulatorVecX", &ManipulatorController::m_vectorX)
- ->Field("ManipulatorVecY", &ManipulatorController::m_vectorY)
- ->Field("ManipulatorVecZ", &ManipulatorController::m_vectorZ)
- ->Field("RestEntity", &ManipulatorController::m_restEntity)
- ->Field("m_effector", &ManipulatorController::m_effector)
- ->Field("max_errorXZ", &ManipulatorController::max_errorXZ)
- ->Field("max_errorY", &ManipulatorController::max_errorY);
- if (AZ::EditContext* ec = serialize->GetEditContext())
- {
- ec->Class<ManipulatorController>("ManipulatorController", "ManipulatorController")
- ->ClassElement(AZ::Edit::ClassElements::EditorData, "ManipulatorController")
- ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game"))
- ->Attribute(AZ::Edit::Attributes::Category, "AppleKraken")
- ->DataElement(AZ::Edit::UIHandlers::EntityId, &ManipulatorController::m_entityX, "m_entityX", "m_entityX")
- ->DataElement(AZ::Edit::UIHandlers::EntityId, &ManipulatorController::m_entityY, "m_entityY", "m_entityY")
- ->DataElement(AZ::Edit::UIHandlers::EntityId, &ManipulatorController::m_entityZ, "m_entity_z1", "m_entityZ")
- ->DataElement(AZ::Edit::UIHandlers::EntityId, &ManipulatorController::m_vectorX, "vx", "vx")
- ->DataElement(AZ::Edit::UIHandlers::EntityId, &ManipulatorController::m_vectorY, "vy", "vy")
- ->DataElement(AZ::Edit::UIHandlers::EntityId, &ManipulatorController::m_vectorZ, "vz", "vz")
- ->DataElement(AZ::Edit::UIHandlers::EntityId, &ManipulatorController::m_effector, "Effector", "Effector")
- ->DataElement(AZ::Edit::UIHandlers::EntityId, &ManipulatorController::m_restEntity, "Rest entity", "Rest Entity")
- ->DataElement(AZ::Edit::UIHandlers::EntityId, &ManipulatorController::max_errorXZ, "max_errorXZ", "max error XZ to retract nose")
- ->DataElement(AZ::Edit::UIHandlers::EntityId, &ManipulatorController::max_errorY, "max_errorY", "max error Y to retract nose");
- }
- }
- }
- void ManipulatorController::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time)
- {
- if (!initialized)
- {
- // get offset to effector
- AZ::Transform transformBaseLink;
- AZ::TransformBus::EventResult(transformBaseLink, GetEntityId(), &AZ::TransformBus::Events::GetWorldTM);
- AZ::Transform transformEffector;
- AZ::TransformBus::EventResult(transformEffector, m_effector, &AZ::TransformBus::Events::GetWorldTM);
- m_transform_base_link_to_effector = transformBaseLink.GetInverse() * transformEffector;
- initialized = true;
- return;
- }
- if (m_desiredApple)
- {
- m_desiredPosition = *m_desiredApple;
- }
- else
- {
- AZ::TransformBus::EventResult(m_desiredPosition, m_restEntity, &AZ::TransformBus::Events::GetWorldTranslation);
- }
- // apple is given in the World's coordinate system
- AZ::Transform current_base_link;
- AZ::TransformBus::EventResult(current_base_link, GetEntityId(), &AZ::TransformBus::Events::GetWorldTM);
- AZ::Vector3 position_in_baselink_tf = current_base_link.GetInverse().TransformPoint(m_desiredPosition);
- AZ::Vector3 position_in_effector_tf = m_transform_base_link_to_effector.GetInverse().TransformPoint(position_in_baselink_tf);
- float setpoint_x = position_in_effector_tf.Dot(m_vectorX);
- float setpoint_z = position_in_effector_tf.Dot(m_vectorZ);
- float error_x = std::numeric_limits<float>::max();
- float error_z = std::numeric_limits<float>::max();
- if (m_entityX.IsValid())
- {
- auto component_x = getMotorizedJoint(m_entityX);
- if (component_x)
- {
- component_x->SetSetpoint(setpoint_x);
- error_x = component_x->GetError();
- }
- }
- if (m_entityZ.IsValid())
- {
- auto component_z = getMotorizedJoint(m_entityZ);
- if (component_z)
- {
- component_z->SetSetpoint(setpoint_z);
- error_z = component_z->GetError();
- }
- }
- // auto - disable nose retrieve only if we reached small error.
- if (m_noseRetrieved == true)
- {
- m_time_XZ_ok += deltaTime;
- if (m_time_XZ_ok > m_timeSetpointReach)
- {
- if (error_x < max_errorXZ && error_x > -max_errorXZ && error_z < max_errorXZ && error_z > -max_errorXZ)
- {
- AZ_Printf("ManipulatorController", "Nose is sliding out \n");
- m_noseRetrieved = false;
- m_time_XZ_ok = 0;
- }
- }
- }
- float setpoint_y = position_in_effector_tf.Dot(m_vectorY);
- if (m_entityY.IsValid())
- {
- auto component_y = getMotorizedJoint(m_entityY);
- if (component_y)
- {
- if (m_noseRetrieved)
- {
- setpoint_y = 0;
- m_time_Y_ok += deltaTime;
- if (m_time_Y_ok > m_timeSetpointReach)
- {
- auto error_y = getMotorizedJoint(m_entityY)->GetError();
- if (error_y < max_errorY && error_y > -max_errorY)
- {
- m_noseRetrievingSuccess = true;
- m_time_Y_ok = 0.0;
- }
- }
- }
- else
- {
- m_noseRetrievingSuccess = false;
- }
- component_y->SetSetpoint(setpoint_y);
- }
- }
- //auto currentPosition = GetPosition();
- AZ_Printf("ManipulatorController", "#### [%f, %f, %f] [%f, %f, %f]\n",setpoint_x, setpoint_y, setpoint_z,
- getMotorizedJoint(m_entityX)->GetCurrentPosition(),
- getMotorizedJoint(m_entityY)->GetCurrentPosition(),
- getMotorizedJoint(m_entityZ)->GetCurrentPosition());
- }
- void ManipulatorController::PickApple(const AZ::Vector3 position)
- {
- m_noseRetrieved = true;
- m_time_XZ_ok = 0;
- AZ_Printf("ManipulatorController", "PickApple\n");
- ResetTimer();
- m_desiredApple = position;
- };
- AZ::Vector3 ManipulatorController::GetPosition()
- {
- auto currentPosition = AZ::Vector3(
- getMotorizedJoint(m_entityX)->GetCurrentPosition(),
- getMotorizedJoint(m_entityY)->GetCurrentPosition(),
- getMotorizedJoint(m_entityZ)->GetCurrentPosition()
- );
- return currentPosition;
- };
- void ManipulatorController::Retrieve()
- {
- AZ_Printf("ManipulatorController", "Retrieve\n");
- m_time_XZ_ok = std::numeric_limits<float>::lowest();
- m_noseRetrieved = true;
- m_desiredApple.reset();
- };
- void ManipulatorController::RetrieveNose()
- {
- AZ_Printf("ManipulatorController", "RetrieveNose\n");
- m_time_XZ_ok = std::numeric_limits<float>::lowest();
- m_noseRetrieved = true;
- }
- int ManipulatorController::GetStatus()
- {
- return 0;
- };
- void ManipulatorController::ResetTimer()
- {
- AZ_Printf("ManipulatorController", "Timer is RESET!\n");
- m_time_XZ_ok = 0;
- }
- bool ManipulatorController::IsNoseRetreived()
- {
- return m_noseRetrievingSuccess;
- }
- AZ::EntityId ManipulatorController::GetEffectorEntity()
- {
- return m_effector;
- }
- AZ::EntityId ManipulatorController::GetRestEntity()
- {
- return m_restEntity;
- }
- } // namespace AppleKraken
|