LidarCore.cpp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  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 <Atom/RPI.Public/AuxGeom/AuxGeomFeatureProcessorInterface.h>
  9. #include <Atom/RPI.Public/Scene.h>
  10. #include <AzFramework/Components/TransformComponent.h>
  11. #include <AzFramework/Physics/PhysicsSystem.h>
  12. #include <Lidar/LidarCore.h>
  13. #include <Lidar/LidarRegistrarSystemComponent.h>
  14. #include <ROS2/ROS2Bus.h>
  15. #include <ROS2Sensors/Lidar/ClassSegmentationBus.h>
  16. namespace ROS2Sensors
  17. {
  18. void LidarCore::Reflect(AZ::ReflectContext* context)
  19. {
  20. LidarSensorConfiguration::Reflect(context);
  21. if (auto serialize = azrtti_cast<AZ::SerializeContext*>(context))
  22. {
  23. serialize->Class<LidarCore>()->Version(1)->Field("lidarConfiguration", &LidarCore::m_lidarConfiguration);
  24. if (AZ::EditContext* ec = serialize->GetEditContext())
  25. {
  26. ec->Class<LidarCore>("ROS2 Lidar Sensor", "Lidar sensor component")
  27. ->DataElement(
  28. AZ::Edit::UIHandlers::ComboBox, &LidarCore::m_lidarConfiguration, "Lidar configuration", "Lidar configuration")
  29. ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly);
  30. }
  31. }
  32. }
  33. RaycastResultFlags LidarCore::GetRaycastResultFlagsForConfig(const LidarSensorConfiguration& configuration)
  34. {
  35. RaycastResultFlags flags = RaycastResultFlags::Range | RaycastResultFlags::Point;
  36. if (configuration.m_lidarSystemFeatures & LidarSystemFeatures::Intensity)
  37. {
  38. flags |= RaycastResultFlags::Intensity;
  39. }
  40. if (configuration.m_lidarSystemFeatures & LidarSystemFeatures::Segmentation && configuration.m_isSegmentationEnabled)
  41. {
  42. if (ClassSegmentationInterface::Get())
  43. {
  44. flags |= RaycastResultFlags::SegmentationData;
  45. }
  46. else
  47. {
  48. AZ_Error(
  49. "ROS2",
  50. false,
  51. "Segmentation feature was enabled for this lidar sensor but the segmentation interface is not accessible. Make sure to "
  52. "either add the Class segmentation component to the level entity or disable the feature in the lidar component "
  53. "configuration.");
  54. }
  55. }
  56. return flags;
  57. }
  58. void LidarCore::ConnectToLidarRaycaster()
  59. {
  60. if (auto raycasterId = m_implementationToRaycasterMap.find(m_lidarConfiguration.m_lidarSystem);
  61. raycasterId != m_implementationToRaycasterMap.end())
  62. {
  63. m_lidarRaycasterId = raycasterId->second;
  64. return;
  65. }
  66. m_lidarRaycasterId = LidarId::CreateNull();
  67. LidarSystemRequestBus::EventResult(
  68. m_lidarRaycasterId, AZ_CRC(m_lidarConfiguration.m_lidarSystem), &LidarSystemRequestBus::Events::CreateLidar, m_entityId);
  69. AZ_Assert(!m_lidarRaycasterId.IsNull(), "Could not access selected Lidar System.");
  70. m_implementationToRaycasterMap.emplace(m_lidarConfiguration.m_lidarSystem, m_lidarRaycasterId);
  71. }
  72. void LidarCore::ConfigureLidarRaycaster()
  73. {
  74. LidarRaycasterRequestBus::Event(m_lidarRaycasterId, &LidarRaycasterRequestBus::Events::ConfigureRayOrientations, m_lastRotations);
  75. LidarRaycasterRequestBus::Event(
  76. m_lidarRaycasterId,
  77. &LidarRaycasterRequestBus::Events::ConfigureRayRange,
  78. RayRange{ m_lidarConfiguration.m_lidarParameters.m_minRange, m_lidarConfiguration.m_lidarParameters.m_maxRange });
  79. if ((m_lidarConfiguration.m_lidarSystemFeatures & LidarSystemFeatures::Noise) &&
  80. m_lidarConfiguration.m_lidarParameters.m_isNoiseEnabled)
  81. {
  82. LidarRaycasterRequestBus::Event(
  83. m_lidarRaycasterId,
  84. &LidarRaycasterRequestBus::Events::ConfigureNoiseParameters,
  85. m_lidarConfiguration.m_lidarParameters.m_noiseParameters.m_angularNoiseStdDev,
  86. m_lidarConfiguration.m_lidarParameters.m_noiseParameters.m_distanceNoiseStdDevBase,
  87. m_lidarConfiguration.m_lidarParameters.m_noiseParameters.m_distanceNoiseStdDevRisePerMeter);
  88. }
  89. m_resultFlags = GetRaycastResultFlagsForConfig(m_lidarConfiguration);
  90. LidarRaycasterRequestBus::Event(m_lidarRaycasterId, &LidarRaycasterRequestBus::Events::ConfigureRaycastResultFlags, m_resultFlags);
  91. if (m_lidarConfiguration.m_lidarSystemFeatures & LidarSystemFeatures::CollisionLayers)
  92. {
  93. LidarRaycasterRequestBus::Event(
  94. m_lidarRaycasterId,
  95. &LidarRaycasterRequestBus::Events::ConfigureIgnoredCollisionLayers,
  96. m_lidarConfiguration.m_ignoredCollisionLayers);
  97. }
  98. if (m_lidarConfiguration.m_lidarSystemFeatures & LidarSystemFeatures::EntityExclusion)
  99. {
  100. LidarRaycasterRequestBus::Event(
  101. m_lidarRaycasterId, &LidarRaycasterRequestBus::Events::ExcludeEntities, m_lidarConfiguration.m_excludedEntities);
  102. }
  103. if (m_lidarConfiguration.m_lidarSystemFeatures & LidarSystemFeatures::MaxRangePoints)
  104. {
  105. LidarRaycasterRequestBus::Event(
  106. m_lidarRaycasterId,
  107. &LidarRaycasterRequestBus::Events::ConfigureMaxRangePointAddition,
  108. m_lidarConfiguration.m_addPointsAtMax);
  109. }
  110. }
  111. void LidarCore::UpdatePoints(const RaycastResults& results)
  112. {
  113. const auto pointsField = results.GetConstFieldSpan<RaycastResultFlags::Point>().value();
  114. m_lastPoints.assign(pointsField.begin(), pointsField.end());
  115. }
  116. LidarCore::LidarCore(const AZStd::vector<LidarTemplate::LidarModel>& availableModels)
  117. : m_lidarConfiguration(availableModels)
  118. {
  119. }
  120. LidarCore::LidarCore(const LidarSensorConfiguration& lidarConfiguration)
  121. : m_lidarConfiguration(lidarConfiguration)
  122. {
  123. }
  124. void LidarCore::VisualizeResults() const
  125. {
  126. if (m_lastPoints.empty())
  127. {
  128. return;
  129. }
  130. if (m_drawQueue)
  131. {
  132. const uint8_t pixelSize = 2;
  133. AZ::RPI::AuxGeomDraw::AuxGeomDynamicDrawArguments drawArgs;
  134. drawArgs.m_verts = m_lastPoints.data();
  135. drawArgs.m_vertCount = m_lastPoints.size();
  136. drawArgs.m_colors = &AZ::Colors::Red;
  137. drawArgs.m_colorCount = 1;
  138. drawArgs.m_opacityType = AZ::RPI::AuxGeomDraw::OpacityType::Opaque;
  139. drawArgs.m_size = pixelSize;
  140. m_drawQueue->DrawPoints(drawArgs);
  141. }
  142. }
  143. void LidarCore::Init(AZ::EntityId entityId)
  144. {
  145. m_entityId = entityId;
  146. auto* entityScene = AZ::RPI::Scene::GetSceneForEntityId(m_entityId);
  147. m_drawQueue = AZ::RPI::AuxGeomFeatureProcessorInterface::GetDrawQueueForScene(entityScene);
  148. m_lastRotations = LidarTemplateUtils::PopulateRayRotations(m_lidarConfiguration.m_lidarParameters);
  149. m_lidarConfiguration.FetchLidarImplementationFeatures();
  150. ConnectToLidarRaycaster();
  151. ConfigureLidarRaycaster();
  152. }
  153. void LidarCore::Deinit()
  154. {
  155. for (auto& [implementation, raycasterId] : m_implementationToRaycasterMap)
  156. {
  157. LidarSystemRequestBus::Event(AZ_CRC(implementation), &LidarSystemRequestBus::Events::DestroyLidar, raycasterId);
  158. }
  159. m_implementationToRaycasterMap.clear();
  160. }
  161. LidarId LidarCore::GetLidarRaycasterId() const
  162. {
  163. return m_lidarRaycasterId;
  164. }
  165. RaycastResultFlags LidarCore::GetResultFlags() const
  166. {
  167. return m_resultFlags;
  168. }
  169. AZStd::optional<RaycastResults> LidarCore::PerformRaycast()
  170. {
  171. AZ::Entity* entity = nullptr;
  172. AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationRequests::FindEntity, m_entityId);
  173. const auto entityTransform = entity->FindComponent<AzFramework::TransformComponent>();
  174. AZ::Outcome<RaycastResults, const char*> results = AZ::Failure("EBus failure occurred.");
  175. LidarRaycasterRequestBus::EventResult(
  176. results, m_lidarRaycasterId, &LidarRaycasterRequestBus::Events::PerformRaycast, entityTransform->GetWorldTM());
  177. if (!results.IsSuccess())
  178. {
  179. AZ_Error(__func__, false, "Unable to obtain raycast results. %s", results.GetError());
  180. return {};
  181. }
  182. AZ_Warning("Lidar Sensor Component", !results.GetValue().IsEmpty(), "No results from raycast\n");
  183. UpdatePoints(results.GetValue());
  184. return results.GetValue();
  185. }
  186. } // namespace ROS2Sensors