ClassSegmentationConfigurationComponent.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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 <AzCore/Serialization/EditContext.h>
  9. #include <AzCore/Serialization/SerializeContext.h>
  10. #include <Lidar/ClassSegmentationConfigurationComponent.h>
  11. namespace ROS2
  12. {
  13. void ClassSegmentationConfigurationComponent::Reflect(AZ::ReflectContext* context)
  14. {
  15. SegmentationClassConfiguration::Reflect(context);
  16. if (auto* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
  17. {
  18. serializeContext->Class<ClassSegmentationConfigurationComponent, AZ::Component>()->Version(0)->Field(
  19. "Segmentation Classes", &ClassSegmentationConfigurationComponent::m_segmentationClasses);
  20. if (auto* editContext = serializeContext->GetEditContext())
  21. {
  22. editContext->Class<ClassSegmentationConfigurationComponent>("Class Segmentation Configuration", "")
  23. ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
  24. ->Attribute(AZ::Edit::Attributes::Category, "ROS2")
  25. ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZStd::vector<AZ::Crc32>({ AZ_CRC_CE("Level") }))
  26. ->DataElement(
  27. AZ::Edit::UIHandlers::Default,
  28. &ClassSegmentationConfigurationComponent::m_segmentationClasses,
  29. "Segmentation classes",
  30. "Segmentation classes and their colors.")
  31. ->Attribute(AZ::Edit::Attributes::AutoExpand, true)
  32. ->Attribute(
  33. AZ::Edit::Attributes::ChangeValidate, &ClassSegmentationConfigurationComponent::ValidateSegmentationClasses)
  34. ->Attribute(
  35. AZ::Edit::Attributes::ChangeNotify, &ClassSegmentationConfigurationComponent::OnSegmentationClassesChanged);
  36. }
  37. }
  38. }
  39. void ClassSegmentationConfigurationComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
  40. {
  41. provided.push_back(AZ_CRC_CE("ClassSegmentationConfig"));
  42. }
  43. void ClassSegmentationConfigurationComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
  44. {
  45. incompatible.push_back(AZ_CRC_CE("ClassSegmentationConfig"));
  46. }
  47. AZ::Color ClassSegmentationConfigurationComponent::GetClassColor(uint8_t classId) const
  48. {
  49. auto it = m_classIdToColor.find(classId);
  50. if (it == m_classIdToColor.end())
  51. {
  52. return AZ::Colors::White;
  53. }
  54. return it->second;
  55. }
  56. AZStd::optional<uint8_t> ClassSegmentationConfigurationComponent::GetClassIdForTag(LmbrCentral::Tag tag) const
  57. {
  58. auto it = m_tagToClassId.find(tag);
  59. if (it == m_tagToClassId.end())
  60. {
  61. return AZStd::nullopt;
  62. }
  63. return it->second;
  64. }
  65. const SegmentationClassConfigList& ClassSegmentationConfigurationComponent::GetClassConfigList() const
  66. {
  67. return m_segmentationClasses;
  68. }
  69. void ClassSegmentationConfigurationComponent::Activate()
  70. {
  71. ConstructSegmentationClassMaps();
  72. if (!ClassSegmentationInterface::Get())
  73. {
  74. ClassSegmentationInterface::Register(this);
  75. }
  76. }
  77. void ClassSegmentationConfigurationComponent::Deactivate()
  78. {
  79. if (ClassSegmentationInterface::Get() == this)
  80. {
  81. ClassSegmentationInterface::Unregister(this);
  82. }
  83. m_classIdToColor.clear();
  84. m_tagToClassId.clear();
  85. }
  86. AZ::Outcome<void, AZStd::string> ClassSegmentationConfigurationComponent::ValidateSegmentationClasses(
  87. void* newValue, const AZ::TypeId& valueType) const
  88. {
  89. AZ_Assert(azrtti_typeid<SegmentationClassConfigList>() == valueType, "Unexpected value type");
  90. if (azrtti_typeid<SegmentationClassConfigList>() != valueType)
  91. {
  92. return AZ::Failure(AZStd::string("Unexpectedly received an invalid type as segmentation classes!"));
  93. }
  94. const auto& segmentationClasses = *azrtti_cast<SegmentationClassConfigList*>(newValue);
  95. bool unknownPresent{ false }, groundPresent{ false };
  96. for (const auto& segmentationClass : segmentationClasses)
  97. {
  98. if (segmentationClass.m_classId == SegmentationClassConfiguration::UnknownClass.m_classId &&
  99. segmentationClass.m_className == SegmentationClassConfiguration::UnknownClass.m_className)
  100. {
  101. unknownPresent = true;
  102. }
  103. if (segmentationClass.m_classId == SegmentationClassConfiguration::GroundClass.m_classId &&
  104. segmentationClass.m_className == SegmentationClassConfiguration::GroundClass.m_className)
  105. {
  106. groundPresent = true;
  107. }
  108. }
  109. if (!unknownPresent || !groundPresent)
  110. {
  111. return AZ::Failure(
  112. AZStd::string::format("Segmentation class with name %s must exist.", (!unknownPresent ? "Unknown" : "Ground")));
  113. }
  114. return AZ::Success();
  115. }
  116. void ClassSegmentationConfigurationComponent::ConstructSegmentationClassMaps()
  117. {
  118. m_classIdToColor.reserve(m_segmentationClasses.size());
  119. m_tagToClassId.reserve(m_segmentationClasses.size());
  120. for (const auto& segmentationClass : m_segmentationClasses)
  121. {
  122. m_classIdToColor.insert(AZStd::make_pair(segmentationClass.m_classId, segmentationClass.m_classColor));
  123. m_tagToClassId.insert(AZStd::make_pair(LmbrCentral::Tag(segmentationClass.m_className), segmentationClass.m_classId));
  124. }
  125. }
  126. AZ::Crc32 ClassSegmentationConfigurationComponent::OnSegmentationClassesChanged()
  127. {
  128. bool unknownPresent{ false }, groundPresent{ false };
  129. for (auto& segmentationClass : m_segmentationClasses)
  130. {
  131. if (segmentationClass.m_classId == SegmentationClassConfiguration::UnknownClass.m_classId)
  132. {
  133. unknownPresent = true;
  134. }
  135. if (segmentationClass.m_classId == SegmentationClassConfiguration::GroundClass.m_classId)
  136. {
  137. groundPresent = true;
  138. }
  139. }
  140. if (unknownPresent && groundPresent)
  141. {
  142. return AZ::Edit::PropertyRefreshLevels::None;
  143. }
  144. if (!unknownPresent)
  145. {
  146. m_segmentationClasses.push_back(SegmentationClassConfiguration::UnknownClass);
  147. }
  148. if (!groundPresent)
  149. {
  150. m_segmentationClasses.push_back(SegmentationClassConfiguration::GroundClass);
  151. }
  152. return AZ::Edit::PropertyRefreshLevels::EntireTree;
  153. }
  154. } // namespace ROS2