JointsManipulationEditorComponent.cpp 6.2 KB

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