ROS2FrameComponentTest.cpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  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/Asset/AssetManagerComponent.h>
  9. #include <AzCore/Component/ComponentApplication.h>
  10. #include <AzCore/Component/ComponentApplicationBus.h>
  11. #include <AzCore/Component/Entity.h>
  12. #include <AzCore/Component/EntityId.h>
  13. #include <AzCore/RTTI/RTTIMacros.h>
  14. #include <AzCore/Serialization/SerializeContext.h>
  15. #include <AzCore/Slice/SliceAssetHandler.h>
  16. #include <AzCore/UserSettings/UserSettingsComponent.h>
  17. #include <AzCore/std/containers/array.h>
  18. #include <AzCore/std/string/string_view.h>
  19. #include <AzQtComponents/Utilities/QtPluginPaths.h>
  20. #include <AzTest/GemTestEnvironment.h>
  21. #include <AzToolsFramework/Entity/EditorEntityContextComponent.h>
  22. #include <AzToolsFramework/ToolsComponents/TransformComponent.h>
  23. #include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
  24. #include <AzToolsFramework/UnitTest/ToolsTestApplication.h>
  25. #include <Clients/ROS2SystemComponent.h>
  26. #include <ROS2/Frame/ROS2FrameComponent.h>
  27. #include <ROS2/ROS2Bus.h>
  28. #include <QApplication>
  29. #include <gtest/gtest.h>
  30. #include <memory>
  31. #include <string>
  32. #include <string_view>
  33. #include <vector>
  34. namespace UnitTest
  35. {
  36. class ROS2FrameComponentTestEnvironment : public AZ::Test::GemTestEnvironment
  37. {
  38. // AZ::Test::GemTestEnvironment overrides ...
  39. void AddGemsAndComponents() override;
  40. AZ::ComponentApplication* CreateApplicationInstance() override;
  41. void PostSystemEntityActivate() override;
  42. public:
  43. ROS2FrameComponentTestEnvironment() = default;
  44. ~ROS2FrameComponentTestEnvironment() override = default;
  45. };
  46. void ROS2FrameComponentTestEnvironment::AddGemsAndComponents()
  47. {
  48. AddActiveGems(AZStd::to_array<AZStd::string_view>({ "ROS2" }));
  49. AddDynamicModulePaths({});
  50. AddComponentDescriptors(AZStd::initializer_list<AZ::ComponentDescriptor*>{ ROS2::ROS2FrameComponent::CreateDescriptor(),
  51. ROS2::ROS2SystemComponent::CreateDescriptor() });
  52. AddRequiredComponents(AZStd::to_array<AZ::TypeId const>({ ROS2::ROS2SystemComponent::TYPEINFO_Uuid() }));
  53. }
  54. AZ::ComponentApplication* ROS2FrameComponentTestEnvironment::CreateApplicationInstance()
  55. {
  56. // Using ToolsTestApplication to have AzFramework and AzToolsFramework components.
  57. return aznew UnitTest::ToolsTestApplication("ROS2FrameComponent");
  58. }
  59. void ROS2FrameComponentTestEnvironment::PostSystemEntityActivate()
  60. {
  61. AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize);
  62. }
  63. class ROS2FrameComponentFixture : public ::testing::Test
  64. {
  65. };
  66. TEST_F(ROS2FrameComponentFixture, SingleFrameDefault)
  67. {
  68. ROS2::ROS2FrameConfiguration config;
  69. AZ::Entity entity;
  70. const std::string entityName = entity.GetName().c_str();
  71. entity.CreateComponent<AzFramework::TransformComponent>();
  72. auto frame = entity.CreateComponent<ROS2::ROS2FrameComponent>(config);
  73. entity.Init();
  74. entity.Activate();
  75. const std::string jointName(frame->GetJointName().GetCStr());
  76. const std::string frameId(frame->GetFrameID().c_str());
  77. EXPECT_EQ(entity.GetState(), AZ::Entity::State::Active);
  78. EXPECT_STRCASEEQ(jointName.c_str(), ("o3de_" + entityName + "/").c_str());
  79. EXPECT_STRCASEEQ(frameId.c_str(), ("o3de_" + entityName + "/sensor_frame").c_str());
  80. }
  81. TEST_F(ROS2FrameComponentFixture, ThreeFramesDefault)
  82. {
  83. ROS2::ROS2FrameConfiguration config;
  84. std::vector<AZStd::unique_ptr<AZ::Entity>> entities;
  85. std::vector<const ROS2::ROS2FrameComponent*> frames;
  86. constexpr int numOfEntities = 3;
  87. for (int i = 0; i < numOfEntities; i++)
  88. {
  89. entities.push_back(AZStd::make_unique<AZ::Entity>());
  90. }
  91. for (int i = 0; i < numOfEntities; i++)
  92. {
  93. entities[i]->CreateComponent<AzFramework::TransformComponent>();
  94. entities[i]->SetName(("entity" + std::to_string(i)).c_str());
  95. entities[i]->Init();
  96. entities[i]->Activate();
  97. if (i != 0)
  98. {
  99. AZ::TransformBus::Event(entities[i]->GetId(), &AZ::TransformBus::Events::SetParent, entities[i - 1]->GetId());
  100. }
  101. entities[i]->Deactivate();
  102. auto frame = entities[i]->CreateComponent<ROS2::ROS2FrameComponent>(config);
  103. frames.push_back(frame);
  104. entities[i]->Activate();
  105. }
  106. for (int i = 0; i < numOfEntities; i++)
  107. {
  108. const std::string jointName(frames[i]->GetJointName().GetCStr());
  109. const std::string frameId(frames[i]->GetFrameID().c_str());
  110. EXPECT_EQ(entities[i]->GetState(), AZ::Entity::State::Active);
  111. EXPECT_STRCASEEQ(jointName.c_str(), (entities[0]->GetName() + "/").c_str());
  112. EXPECT_STRCASEEQ(frameId.c_str(), (entities[0]->GetName() + "/sensor_frame").c_str());
  113. }
  114. }
  115. TEST_F(ROS2FrameComponentFixture, UpdateNamespace)
  116. {
  117. ROS2::ROS2FrameConfiguration config;
  118. AZ::Entity entity;
  119. const std::string entityName = entity.GetName().c_str();
  120. entity.CreateComponent<AzFramework::TransformComponent>();
  121. auto frame = entity.CreateComponent<ROS2::ROS2FrameComponent>(config);
  122. entity.Init();
  123. entity.Activate();
  124. auto rosifiedName = "o3de_" + entityName;
  125. ASSERT_STREQ(frame->GetNamespace().c_str(), rosifiedName.c_str());
  126. // Note that namespace parameter is only applied using Custom strategy
  127. frame->UpdateNamespaceConfiguration("MyCustomNamespace", ROS2::NamespaceConfiguration::NamespaceStrategy::Custom);
  128. EXPECT_STREQ(frame->GetNamespace().c_str(), "MyCustomNamespace");
  129. // Empty strategy clears the namespace
  130. frame->UpdateNamespaceConfiguration("MyCustomNamespace", ROS2::NamespaceConfiguration::NamespaceStrategy::Empty);
  131. EXPECT_STREQ(frame->GetNamespace().c_str(), "");
  132. // From Entity Name strategy uses rosified version of Entity Name
  133. frame->UpdateNamespaceConfiguration("MyCustomNamespace", ROS2::NamespaceConfiguration::NamespaceStrategy::FromEntityName);
  134. EXPECT_STREQ(frame->GetNamespace().c_str(), rosifiedName.c_str());
  135. // Default strategy is like From Entity Name strategy if the entity is on top of hierarchy ...
  136. frame->UpdateNamespaceConfiguration("MyCustomNamespace", ROS2::NamespaceConfiguration::NamespaceStrategy::Default);
  137. EXPECT_STREQ(frame->GetNamespace().c_str(), rosifiedName.c_str());
  138. AZ::Entity newRootEntity;
  139. AZStd::string newRootName = "new_root";
  140. newRootEntity.SetName(newRootName);
  141. newRootEntity.CreateComponent<AzFramework::TransformComponent>();
  142. newRootEntity.CreateComponent<ROS2::ROS2FrameComponent>(config);
  143. newRootEntity.Init();
  144. newRootEntity.Activate();
  145. AZ::TransformBus::Event(entity.GetId(), &AZ::TransformBus::Events::SetParent, newRootEntity.GetId());
  146. // If there is a parent Default strategy concatenates parent's namespace with rosified name
  147. frame->UpdateNamespaceConfiguration("MyCustomNamespace", ROS2::NamespaceConfiguration::NamespaceStrategy::Default);
  148. EXPECT_STREQ(frame->GetNamespace().c_str(), AZStd::string::format("%s/%s", newRootName.c_str(), rosifiedName.c_str()).c_str());
  149. }
  150. } // namespace UnitTest
  151. // required to support running integration tests with Qt and PhysX
  152. AZTEST_EXPORT int AZ_UNIT_TEST_HOOK_NAME(int argc, char** argv)
  153. {
  154. ::testing::InitGoogleMock(&argc, argv);
  155. AzQtComponents::PrepareQtPaths();
  156. QApplication app(argc, argv);
  157. AZ::Test::printUnusedParametersWarning(argc, argv);
  158. AZ::Test::addTestEnvironments({ new UnitTest::ROS2FrameComponentTestEnvironment() });
  159. int result = RUN_ALL_TESTS();
  160. return result;
  161. }
  162. IMPLEMENT_TEST_EXECUTABLE_MAIN();