ROS2SDFormatHooksUtils.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  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. #pragma once
  9. #include <AzCore/Component/Component.h>
  10. #include <AzCore/Component/Entity.h>
  11. #include <AzCore/Memory/SystemAllocator.h>
  12. #include <AzCore/RTTI/RTTI.h>
  13. #include <AzCore/std/string/string.h>
  14. #include <AzToolsFramework/ToolsComponents/EditorComponentBase.h>
  15. #include <AzToolsFramework/ToolsComponents/GenericComponentWrapper.h>
  16. #include <ROS2/Frame/ROS2FrameEditorComponent.h>
  17. #include <ROS2/RobotImporter/SDFormatModelPluginImporterHook.h>
  18. // temporarily disable import hooks for sensors and models for https://github.com/o3de/sig-simulation/pull/96
  19. // #include <ROS2/Sensor/SensorConfiguration.h>
  20. #include <Source/EditorArticulationLinkComponent.h>
  21. #include <Source/EditorHingeJointComponent.h>
  22. #include <sdf/Model.hh>
  23. #include <sdf/Sensor.hh>
  24. namespace ROS2::SDFormat
  25. {
  26. namespace HooksUtils
  27. {
  28. //! Add a ROS 2 topic configuration to sensor parameters.
  29. //! @param sensorConfig sensor's configuration which hosts multiple topic configurations
  30. //! @param topic ROS 2 topic name
  31. //! @param messageType ROS 2 message type
  32. //! @param configName name under which topic configuration is stored in sensor's configuration
  33. // temporarily disable import hooks for sensors and models for https://github.com/o3de/sig-simulation/pull/96
  34. // void AddTopicConfiguration(
  35. // SensorConfiguration& sensorConfig,
  36. // const AZStd::string& topic,
  37. // const AZStd::string& messageType,
  38. // const AZStd::string& configName);
  39. //! Find O3DE entity id of the SDFormat joint based on its name and a map of all created entities.
  40. //! @param jointName name of the joint in query
  41. //! @param sdfModel reference to SDFormat model
  42. //! @param createdEntities list of all created entities passed as entity creation results
  43. //! @return entity id (invalid id if not found)
  44. AZ::EntityId GetJointEntityId(const std::string& jointName, const sdf::Model& sdfModel, const CreatedEntitiesMap& createdEntities);
  45. //! Enable motor in EditorHingeJointComponent if possible
  46. //! @param entityId entity id of the modified entity
  47. void EnableMotor(const AZ::EntityId& entityId);
  48. //! Set transform to entity containing sensor based on <pose> tag in sdformat data (if available).
  49. //! @param entity entity to which the transform is set
  50. //! @param sdfSensor reference to SDFormat sensor possibly containing <pose> tag
  51. void SetSensorEntityTransform(AZ::Entity& entity, const sdf::Sensor& sdfSensor);
  52. //! Create a component and attach the component to the entity.
  53. //! This method ensures that game components are wrapped into GenericComponentWrapper.
  54. //! @param entity entity to which the new component is added
  55. //! @param args constructor arguments used to create the new component
  56. //! @return A pointer to the component. Returns a null pointer if the component could not be created.
  57. template<class ComponentType, typename... Args>
  58. AZ::Component* CreateComponent(AZ::Entity& entity, Args&&... args)
  59. {
  60. // Do not create a component if the same type is already added.
  61. if (entity.FindComponent<ComponentType>())
  62. {
  63. return nullptr;
  64. }
  65. // Create component.
  66. // If it's not an "editor component" then wrap it in a GenericComponentWrapper.
  67. AZ::Component* component = nullptr;
  68. if (AZ::GetRttiHelper<ComponentType>() &&
  69. AZ::GetRttiHelper<ComponentType>()->IsTypeOf(AzToolsFramework::Components::EditorComponentBase::RTTI_Type()))
  70. {
  71. component = aznew ComponentType(AZStd::forward<Args>(args)...);
  72. }
  73. else
  74. {
  75. AZ::Component* gameComponent = aznew ComponentType(AZStd::forward<Args>(args)...);
  76. component = aznew AzToolsFramework::Components::GenericComponentWrapper(gameComponent);
  77. }
  78. AZ_Assert(component, "Failed to create component: %s", AZ::AzTypeInfo<ComponentType>::Name());
  79. if (component)
  80. {
  81. if (!entity.IsComponentReadyToAdd(component) || !entity.AddComponent(component))
  82. {
  83. delete component;
  84. component = nullptr;
  85. }
  86. }
  87. return component;
  88. }
  89. //! Create a component and attach the component to the entity.
  90. //! This method ensures that game components are wrapped into GenericComponentWrapper.
  91. //! @param entityId entity id to which the new component is added
  92. //! @param args constructor arguments used to create the new component
  93. //! @return A pointer to the component. Returns a null pointer if the component could not be created.
  94. template<class ComponentType, typename... Args>
  95. AZ::Component* CreateComponent(const AZ::EntityId& entityId, Args&&... args)
  96. {
  97. AZ::Entity* entity = nullptr;
  98. AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationRequests::FindEntity, entityId);
  99. if (entity != nullptr)
  100. {
  101. return CreateComponent<ComponentType>(*entity, AZStd::forward<Args>(args)...);
  102. }
  103. return nullptr;
  104. }
  105. using PluginParams = AZStd::unordered_map<AZStd::string, AZStd::string>;
  106. //! Get frame configuration from given plugin params
  107. //! @param pluginParams parameters of the plugin for which frame is created
  108. //! @return configuration of the frame
  109. ROS2FrameConfiguration GetFrameConfiguration(const HooksUtils::PluginParams& pluginParams);
  110. //! Find all parameters given in plugin element.
  111. //! Given a ROS 2 remapping argument, extracts only names of
  112. //! elements to be remapped, ignoring their namespaces.
  113. //! @param plugin plugin to extract parameters from
  114. //! @return a map of parameters present in plugin
  115. PluginParams GetPluginParams(const sdf::Plugins& plugins);
  116. //! Find value of any of specified plugin parameters.
  117. //! @param pluginParams map of plugin parameters defined in model description
  118. //! @param paramNames vector of parameter names in query
  119. //! @param defaultVal value to be returned when none of the parameters are present in the map
  120. //! @return value on any of the query parameters or defaultVal when none were present
  121. AZStd::string ValueOfAny(
  122. const PluginParams& pluginParams, const AZStd::vector<AZStd::string>& paramNames, const AZStd::string& defaultVal = "");
  123. //! Get the name of element's general topic after remapping.
  124. //! @param pluginParams map of plugin parameters
  125. //! @param element pointer to the sdf element
  126. //! @param defaultVal value to be returned when no remaps of the topic are present in the map
  127. //! @return remapped topic name or defaultVal when no remaps are present
  128. AZStd::string GetTopicName(const PluginParams& pluginParams, sdf::ElementPtr element, const AZStd::string& defaultVal = "");
  129. //! Get publisher frequency from plugin.
  130. //! @param pluginParams map of plugin parameters
  131. //! @param defaultVal value to be returned when frequency param does not appear in pluginParams
  132. //! @return publisher frequency or defaultVal when frequency is not specified by element description
  133. float GetFrequency(const PluginParams& pluginParams, const float defaultVal = 10.0);
  134. } // namespace HooksUtils
  135. } // namespace ROS2::SDFormat