2
0

JointsManipulationEditorComponent.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  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 "JointsManipulationEditorComponent.h"
  9. #include "JointUtils.h"
  10. #include "JointsManipulationComponent.h"
  11. #include <AzCore/Component/ComponentApplicationBus.h>
  12. #include <AzCore/Component/TransformBus.h>
  13. #include <AzCore/Serialization/EditContext.h>
  14. #include <AzCore/std/functional.h>
  15. #include <AzToolsFramework/API/ToolsApplicationAPI.h>
  16. #include <ROS2/Frame/ROS2FrameEditorComponent.h>
  17. #include <ROS2Controllers/Manipulation/Controllers/JointsPositionControllerRequests.h>
  18. #include <ROS2Controllers/Manipulation/JointInfo.h>
  19. #include <Source/ArticulationLinkComponent.h>
  20. #include <Source/HingeJointComponent.h>
  21. namespace ROS2Controllers
  22. {
  23. JointsManipulationEditorComponent::JointsManipulationEditorComponent()
  24. {
  25. m_jointStatePublisherConfiguration.m_topicConfiguration.m_type = "sensor_msgs::msg::JointState";
  26. m_jointStatePublisherConfiguration.m_topicConfiguration.m_topic = "joint_states";
  27. m_jointStatePublisherConfiguration.m_frequency = 25.0f;
  28. }
  29. JointsManipulationEditorComponent::JointsManipulationEditorComponent(const ROS2::PublisherConfiguration& publisherConfiguration)
  30. {
  31. m_jointStatePublisherConfiguration = publisherConfiguration;
  32. }
  33. void JointsManipulationEditorComponent::BuildGameEntity(AZ::Entity* gameEntity)
  34. {
  35. gameEntity->CreateComponent<JointsManipulationComponent>(m_jointStatePublisherConfiguration, m_initialPositions);
  36. }
  37. void JointsManipulationEditorComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
  38. {
  39. required.push_back(AZ_CRC_CE("ROS2Frame"));
  40. required.push_back(AZ_CRC_CE("JointsControllerService"));
  41. }
  42. void JointsManipulationEditorComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
  43. {
  44. provided.push_back(AZ_CRC_CE("JointsManipulationService"));
  45. }
  46. void JointsManipulationEditorComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
  47. {
  48. incompatible.push_back(AZ_CRC_CE("JointsManipulationService"));
  49. }
  50. void JointsManipulationEditorComponent::Reflect(AZ::ReflectContext* context)
  51. {
  52. if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context))
  53. {
  54. serialize->Class<JointsManipulationEditorComponent, AZ::Component>()
  55. ->Version(1)
  56. ->Field("JointStatePublisherConfiguration", &JointsManipulationEditorComponent::m_jointStatePublisherConfiguration)
  57. ->Field("Initial positions", &JointsManipulationEditorComponent::m_initialPositions);
  58. if (AZ::EditContext* ec = serialize->GetEditContext())
  59. {
  60. ec->Class<JointsManipulationEditorComponent>("JointsManipulationEditorComponent", "Component for manipulation of joints")
  61. ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
  62. ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game"))
  63. ->Attribute(AZ::Edit::Attributes::Category, "ROS2")
  64. ->Attribute(AZ::Edit::Attributes::Icon, "Editor/Icons/Components/JointsManipulationEditorComponent.svg")
  65. ->Attribute(
  66. AZ::Edit::Attributes::ViewportIcon, "Editor/Icons/Components/Viewport/JointsManipulationEditorComponent.svg")
  67. ->DataElement(
  68. AZ::Edit::UIHandlers::Default,
  69. &JointsManipulationEditorComponent::m_jointStatePublisherConfiguration,
  70. "Joint State Publisher",
  71. "Configuration of Joint State Publisher")
  72. ->UIElement(AZ::Edit::UIHandlers::Button, "Reload joints", "Reload joints")
  73. ->Attribute(AZ::Edit::Attributes::ButtonText, "Reload joints")
  74. ->Attribute(AZ::Edit::Attributes::ChangeNotify, &JointsManipulationEditorComponent::ReloadJoints)
  75. ->Attribute(AZ::Edit::Attributes::NameLabelOverride, "")
  76. ->DataElement(
  77. AZ::Edit::UIHandlers::Default,
  78. &JointsManipulationEditorComponent::m_initialPositions,
  79. "Initial positions",
  80. "Initial positions of all the joints (in order)");
  81. }
  82. }
  83. }
  84. AZ::Crc32 JointsManipulationEditorComponent::ReloadJoints()
  85. {
  86. AzToolsFramework::ScopedUndoBatch undo("ReloadJoints");
  87. // create backup of the configuration
  88. AZStd::unordered_map<AZStd::string, float> configBackup;
  89. for (const auto& [jointName, jointValue] : m_initialPositions)
  90. {
  91. configBackup[jointName] = jointValue;
  92. }
  93. m_initialPositions.clear();
  94. AZStd::function<void(const AZ::Entity* entity)> getAllJointsHierarchy = [&](const AZ::Entity* entity)
  95. {
  96. auto* frameEditorComponent = entity->FindComponent<ROS2::ROS2FrameEditorComponent>();
  97. AZ_Assert(frameEditorComponent, "ROS2FrameEditorComponent does not exist!");
  98. const bool hasNonFixedJoints = JointUtils::HasNonFixedJoints(entity);
  99. const AZStd::string jointName(frameEditorComponent->GetConfiguration().m_jointName);
  100. if (!jointName.empty() && hasNonFixedJoints)
  101. {
  102. m_initialPositions.emplace_back(AZStd::make_pair(jointName, configBackup[jointName]));
  103. }
  104. const auto& childrenEntityIds = frameEditorComponent->GetFrameChildren();
  105. if (!childrenEntityIds.empty())
  106. {
  107. for (const auto& entityId : childrenEntityIds)
  108. {
  109. AZ::Entity* childEntity = nullptr;
  110. AZ::ComponentApplicationBus::BroadcastResult(childEntity, &AZ::ComponentApplicationBus::Events::FindEntity, entityId);
  111. AZ_Assert(childEntity, "Entity not found!");
  112. getAllJointsHierarchy(childEntity);
  113. }
  114. }
  115. };
  116. getAllJointsHierarchy(GetEntity());
  117. undo.MarkEntityDirty(GetEntity()->GetId());
  118. return AZ::Edit::PropertyRefreshLevels::EntireTree;
  119. }
  120. } // namespace ROS2Controllers