Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Simulation features common test #362

Merged
merged 35 commits into from
Jul 8, 2022
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
0992cb8
Add more common test and refactor helper class
ahcorde Jun 20, 2022
0ecea70
Add feedback and more tests
ahcorde Jun 21, 2022
110ddf3
Merge branch 'main' into ahcorde/6/refactor_common_test
ahcorde Jun 21, 2022
7ebed3f
Added Simulation features common test
ahcorde Jun 21, 2022
55029e5
Fix windows build
ahcorde Jun 21, 2022
ef59f8f
try to fix windows build
ahcorde Jun 21, 2022
323970c
try to fix windows build
ahcorde Jun 21, 2022
1b99a98
try to fix windows build
ahcorde Jun 21, 2022
f9b9a18
Fix windows build
ahcorde Jun 21, 2022
cc2abe0
Fix windows build
ahcorde Jun 22, 2022
28b981d
Fix windows build
ahcorde Jun 22, 2022
75b834f
Merge branch 'ahcorde/6/refactor_common_test' into ahcorde/6/simulati…
ahcorde Jun 22, 2022
edf9540
Added joinpaths
ahcorde Jun 22, 2022
821d5bc
Fixed windows build
ahcorde Jun 23, 2022
b4e7c92
Remove old gtest version
mjcarroll Jun 27, 2022
62f4ca1
Add new vendored Googletest version
mjcarroll Jun 28, 2022
0bd6fd2
CMake updates for new googletest version
mjcarroll Jun 28, 2022
7776dd6
Test updates for new googletest version
mjcarroll Jun 28, 2022
cacc9f8
Remove unnecessary gtest_main functions
mjcarroll Jun 28, 2022
e9e377c
Update test/CMakeLists.txt
mjcarroll Jun 28, 2022
c6bef9d
Merge branch 'main' into ahcorde/6/refactor_common_test
ahcorde Jun 28, 2022
a53ac45
Merge branch 'ahcorde/6/refactor_common_test' into ahcorde/6/simulati…
ahcorde Jun 28, 2022
327a775
Fixed merge
ahcorde Jun 28, 2022
b173393
Merge branch 'main' into ahcorde/6/refactor_common_test
ahcorde Jun 28, 2022
73d7bac
Merge branch 'main' into bump_gtest
ahcorde Jun 28, 2022
7cc773d
Merge remote-tracking branch 'origin/bump_gtest' into ahcorde/6/refac…
ahcorde Jun 29, 2022
685fb75
Merge remote-tracking branch 'origin/main' into ahcorde/6/refactor_co…
ahcorde Jun 29, 2022
f435488
remove todo - skip test
ahcorde Jun 29, 2022
21a4dec
Merge branch 'main' into ahcorde/6/refactor_common_test
ahcorde Jun 29, 2022
0a36b2a
Merge remote-tracking branch 'origin/ahcorde/6/refactor_common_test' …
ahcorde Jun 30, 2022
1d5f7e7
Merge branch 'main' into ahcorde/6/refactor_common_test
ahcorde Jul 6, 2022
660c430
Merge remote-tracking branch 'origin/ahcorde/6/refactor_common_test' …
ahcorde Jul 6, 2022
1a76e1e
GTEST_SKIP
ahcorde Jul 6, 2022
9de2eef
Merge branch 'main' into ahcorde/6/simulation_features
ahcorde Jul 7, 2022
693a109
removed link_directories
ahcorde Jul 8, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions bullet/src/EntityManagementFeatures.cc
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,9 @@ Identity EntityManagementFeatures::GetWorld(
}

const std::string &EntityManagementFeatures::GetWorldName(
const Identity &) const
const Identity &_worldID) const
{
static const std::string worldName = "bullet";
static const std::string worldName = this->worlds.at(_worldID)->name;
return worldName;
}

Expand Down
6 changes: 3 additions & 3 deletions dartsim/src/ShapeFeatures.cc
Original file line number Diff line number Diff line change
Expand Up @@ -241,11 +241,11 @@ Vector3d ShapeFeatures::GetEllipsoidShapeRadii(
{
const auto *shapeInfo = this->ReferenceInterface<ShapeInfo>(_ellipsoidID);

dart::dynamics::EllipsoidShape *ellipsoid =
static_cast<dart::dynamics::EllipsoidShape *>(
dart::dynamics::MeshShape *ellipsoid =
static_cast<dart::dynamics::MeshShape *>(
shapeInfo->node->getShape().get());

return ellipsoid->getRadii();
return ellipsoid->getBoundingBox().getMax();
}

/////////////////////////////////////////////////
Expand Down
1 change: 1 addition & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ ExternalProject_Add(
add_subdirectory(benchmark)
add_subdirectory(common_test)
add_subdirectory(plugins)
add_subdirectory(helpers)
add_subdirectory(integration)
add_subdirectory(performance)
add_subdirectory(regression)
Expand Down
12 changes: 10 additions & 2 deletions test/common_test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ set(TEST_TYPE "COMMON_TEST")

set(tests
basic_test
construct_empty_world
simulation_features
)

link_directories(${PROJECT_BINARY_DIR}/test)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not related to this PR, but link_directories probably isn't necessary here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expand All @@ -19,11 +21,17 @@ foreach(test ${tests})

target_link_libraries(${TEST_TYPE}_${test}
PUBLIC
ignition-plugin${IGN_PLUGIN_VER}::loader
ignition-common5::ignition-common5
${PROJECT_LIBRARY_TARGET_NAME}
${PROJECT_LIBRARY_TARGET_NAME}-sdf
ignition-plugin${IGN_PLUGIN_VER}::loader
ignition-common${IGN_COMMON_VER}::ignition-common${IGN_COMMON_VER}
gtest
gtest_main
${PROJECT_NAME}_test_lib_loader
)

target_compile_definitions(${TEST_TYPE}_${test} PRIVATE
"TEST_WORLD_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}/worlds/\""
)

if (${BULLET_FOUND})
Expand Down
49 changes: 8 additions & 41 deletions test/common_test/basic_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
#include <gtest/gtest.h>

#include <gz/common/Console.hh>
#include <gz/common/Filesystem.hh>
#include <gz/common/Util.hh>
#include <gz/plugin/Loader.hh>

#include "../helpers/TestLibLoader.hh"

#include <gz/physics/FindFeatures.hh>
#include <gz/physics/GetEntities.hh>
#include <gz/physics/RequestEngine.hh>
Expand All @@ -31,21 +31,8 @@ using Features = gz::physics::FeatureList<
>;

class EntityManagementFeaturesTest:
public testing::Test
public testing::Test, public gz::physics::TestLibLoader
{
public: static void init(int argc, char *argv[])
{
if (argc != 2)
FAIL() << "Please provide the path to an engine plugin.\n"
<< "Usage COMMON_TEST_basic_test <physics engine path>\n";
libToTest = argv[1];
}

static std::string GetLibToTest()
{
return libToTest;
}

// Documentation inherited
public: void SetUp() override
{
Expand All @@ -58,36 +45,15 @@ class EntityManagementFeaturesTest:
pluginNames = gz::physics::FindFeatures3d<Features>::From(loader);
if (pluginNames.empty())
{
FAIL() << "No plugins with required features found in " << GetLibToTest();
std::cerr << "No plugins with required features found in " << GetLibToTest();
// TODO(ahcorde): If we update gtest we can use here GTEST_SKIP()
}
}

/// \brief Get Physics Engine name based on the plugin name
/// \param[in] _name Plugin name
/// \return Name of the Physics Engine
std::string PhysicsEngineName(std::string _name)
{
std::vector<std::string> tokens = gz::common::split(_name, "::");
if (tokens.size() == 4)
{
std::string physicsEngineName = tokens[2];
std::string physicsEnginePluginName = physicsEngineName;
if (physicsEngineName == "tpeplugin")
{
physicsEnginePluginName = "tpe";
}
return physicsEnginePluginName;
}
return "";
}

public: static std::string libToTest;
public: gz::plugin::Loader loader;
public: std::set<std::string> pluginNames;
public: gz::plugin::Loader loader;
};

std::string EntityManagementFeaturesTest::libToTest = std::string("");

/////////////////////////////////////////////////
TEST_F(EntityManagementFeaturesTest, ConstructEmptyWorld)
{
Expand All @@ -106,6 +72,7 @@ TEST_F(EntityManagementFeaturesTest, ConstructEmptyWorld)
int main(int argc, char *argv[])
{
::testing::InitGoogleTest(&argc, argv);
EntityManagementFeaturesTest::init(argc, argv);
if (!EntityManagementFeaturesTest::init(argc, argv))
return -1;
return RUN_ALL_TESTS();
}
248 changes: 248 additions & 0 deletions test/common_test/construct_empty_world.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
/*
* Copyright (C) 2022 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <gtest/gtest.h>

#include <gz/common/Console.hh>
#include <gz/plugin/Loader.hh>

#include "../helpers/TestLibLoader.hh"

#include <gz/physics/ConstructEmpty.hh>
#include <gz/physics/FindFeatures.hh>
#include <gz/physics/GetEntities.hh>
#include <gz/physics/RequestEngine.hh>
#include <gz/physics/RemoveEntities.hh>

#include "gz/physics/BoxShape.hh"

// The features that an engine must have to be loaded by this loader.
using Features = gz::physics::FeatureList<
gz::physics::GetEngineInfo,
gz::physics::GetWorldFromEngine,
gz::physics::ConstructEmptyWorldFeature,
gz::physics::ConstructEmptyModelFeature,
gz::physics::GetModelFromWorld,
gz::physics::GetLinkFromModel,
gz::physics::ConstructEmptyLinkFeature,
gz::physics::AttachBoxShapeFeature,
gz::physics::GetShapeFromLink,
gz::physics::GetBoxShapeProperties,
gz::physics::RemoveEntities,
gz::physics::GetNestedModelFromModel,
gz::physics::ConstructEmptyNestedModelFeature
>;

class ConstructEmptyWorldTest:
public testing::Test, public gz::physics::TestLibLoader
{
// Documentation inherited
public: void SetUp() override
{
gz::common::Console::SetVerbosity(4);

loader.LoadLib(ConstructEmptyWorldTest::GetLibToTest());

// TODO(ahcorde): We should also run the 3f, 2d, and 2f variants of
// FindFeatures
pluginNames = gz::physics::FindFeatures3d<Features>::From(loader);
if (pluginNames.empty())
{
std::cerr << "No plugins with required features found in "
<< GetLibToTest() << std::endl;
// TODO(ahcorde): If we update gtest we can use here GTEST_SKIP()
}
}

public: std::set<std::string> pluginNames;
public: gz::plugin::Loader loader;
};

/////////////////////////////////////////////////
TEST_F(ConstructEmptyWorldTest, ConstructEmptyWorld)
{
for (const std::string &name : pluginNames)
{
std::cout << "Testing plugin: " << name << std::endl;
gz::plugin::PluginPtr plugin = loader.Instantiate(name);

auto engine = gz::physics::RequestEngine3d<Features>::From(plugin);
ASSERT_NE(nullptr, engine);

auto world = engine->ConstructEmptyWorld("empty world");
ASSERT_NE(nullptr, world);
EXPECT_EQ("empty world", world->GetName());
EXPECT_EQ(engine, world->GetEngine());

auto model = world->ConstructEmptyModel("empty model");
ASSERT_NE(nullptr, model);
EXPECT_EQ("empty model", model->GetName());
EXPECT_EQ(world, model->GetWorld());
EXPECT_NE(model, world->ConstructEmptyModel("dummy"));

auto nestedModel = model->ConstructEmptyNestedModel("empty nested model");
ASSERT_NE(nullptr, nestedModel);
EXPECT_EQ("empty nested model", nestedModel->GetName());
EXPECT_EQ(1u, model->GetNestedModelCount());
EXPECT_EQ(0u, model->GetIndex());
EXPECT_EQ(nestedModel, model->GetNestedModel(0));
EXPECT_EQ(nestedModel, model->GetNestedModel("empty nested model"));
EXPECT_NE(nestedModel, nestedModel->ConstructEmptyNestedModel("dummy"));
// This should remain 1 since we're adding a nested model in `nestedModel` not
// in `model`.
EXPECT_EQ(1u, model->GetNestedModelCount());
EXPECT_EQ(1u, nestedModel->GetNestedModelCount());

auto link = model->ConstructEmptyLink("empty link");
ASSERT_NE(nullptr, link);
EXPECT_EQ("empty link", link->GetName());
EXPECT_EQ(model, link->GetModel());
EXPECT_NE(link, model->ConstructEmptyLink("dummy"));
EXPECT_EQ(model, link->GetModel());

auto child = model->ConstructEmptyLink("child link");
EXPECT_EQ(model, child->GetModel());

const std::string boxName = "box";
const Eigen::Vector3d boxSize(0.1, 0.2, 0.3);
auto box = link->AttachBoxShape(boxName, boxSize);
EXPECT_EQ(boxName, box->GetName());
EXPECT_NEAR((boxSize - box->GetSize()).norm(), 0.0, 1e-6);

EXPECT_EQ(1u, link->GetShapeCount());
auto boxCopy = link->GetShape(0u);
EXPECT_EQ(box, boxCopy);
}
}

/////////////////////////////////////////////////
TEST_F(ConstructEmptyWorldTest, RemoveEntities)
{
for (const std::string &name : pluginNames)
{
std::cout << "Testing plugin: " << name << std::endl;
gz::plugin::PluginPtr plugin = loader.Instantiate(name);

auto engine = gz::physics::RequestEngine3d<Features>::From(plugin);
ASSERT_NE(nullptr, engine);

auto world = engine->ConstructEmptyWorld("empty world");
ASSERT_NE(nullptr, world);
auto model = world->ConstructEmptyModel("empty model");
ASSERT_NE(nullptr, model);
auto modelAlias = world->GetModel(0);

model->Remove();
EXPECT_TRUE(model->Removed());
EXPECT_TRUE(modelAlias->Removed());
EXPECT_EQ(nullptr, world->GetModel(0));
EXPECT_EQ(nullptr, world->GetModel("empty model"));
EXPECT_EQ(0ul, world->GetModelCount());

auto model2 = world->ConstructEmptyModel("model2");
ASSERT_NE(nullptr, model2);
EXPECT_EQ(0ul, model2->GetIndex());
world->RemoveModel(0);
EXPECT_EQ(0ul, world->GetModelCount());

auto model3 = world->ConstructEmptyModel("model 3");
ASSERT_NE(nullptr, model3);
EXPECT_EQ(1u, world->GetModelCount());
world->RemoveModel("model 3");
EXPECT_EQ(0ul, world->GetModelCount());
EXPECT_EQ(nullptr, world->GetModel("model 3"));

auto parentModel = world->ConstructEmptyModel("parent model");
ASSERT_NE(nullptr, parentModel);
EXPECT_EQ(0u, parentModel->GetNestedModelCount());
auto nestedModel1 =
parentModel->ConstructEmptyNestedModel("empty nested model1");
ASSERT_NE(nullptr, nestedModel1);
EXPECT_EQ(1u, parentModel->GetNestedModelCount());

EXPECT_TRUE(parentModel->RemoveNestedModel(0));
EXPECT_EQ(0u, parentModel->GetNestedModelCount());
EXPECT_TRUE(nestedModel1->Removed());

auto nestedModel2 =
parentModel->ConstructEmptyNestedModel("empty nested model2");
ASSERT_NE(nullptr, nestedModel2);
EXPECT_EQ(nestedModel2, parentModel->GetNestedModel(0));
EXPECT_TRUE(parentModel->RemoveNestedModel("empty nested model2"));
EXPECT_EQ(0u, parentModel->GetNestedModelCount());
EXPECT_TRUE(nestedModel2->Removed());

auto nestedModel3 =
parentModel->ConstructEmptyNestedModel("empty nested model3");
ASSERT_NE(nullptr, nestedModel3);
EXPECT_EQ(nestedModel3, parentModel->GetNestedModel(0));
EXPECT_TRUE(nestedModel3->Remove());
EXPECT_EQ(0u, parentModel->GetNestedModelCount());
EXPECT_TRUE(nestedModel3->Removed());

auto nestedModel4 =
parentModel->ConstructEmptyNestedModel("empty nested model4");
ASSERT_NE(nullptr, nestedModel4);
EXPECT_EQ(nestedModel4, parentModel->GetNestedModel(0));
// Remove the parent model and check that the nested model is removed as well
EXPECT_TRUE(parentModel->Remove());
EXPECT_TRUE(nestedModel4->Removed());
}
}

TEST_F(ConstructEmptyWorldTest, ModelByIndexWithNestedModels)
{
for (const std::string &name : pluginNames)
{
std::cout << "Testing plugin: " << name << std::endl;
gz::plugin::PluginPtr plugin = loader.Instantiate(name);

auto engine = gz::physics::RequestEngine3d<Features>::From(plugin);
ASSERT_NE(nullptr, engine);

auto world = engine->ConstructEmptyWorld("empty world");
ASSERT_NE(nullptr, world);
auto model1 = world->ConstructEmptyModel("model1");
ASSERT_NE(nullptr, model1);
EXPECT_EQ(0ul, model1->GetIndex());

auto parentModel = world->ConstructEmptyModel("parent model");
ASSERT_NE(nullptr, parentModel);
EXPECT_EQ(1ul, parentModel->GetIndex());

auto nestedModel1 =
parentModel->ConstructEmptyNestedModel("empty nested model1");
ASSERT_NE(nullptr, nestedModel1);
EXPECT_EQ(0ul, nestedModel1->GetIndex());

auto model2 = world->ConstructEmptyModel("model2");
ASSERT_NE(nullptr, model2);
EXPECT_EQ(2ul, model2->GetIndex());
EXPECT_TRUE(model2->Remove());

auto model2Again = world->ConstructEmptyModel("model2_again");
ASSERT_NE(nullptr, model2Again);
EXPECT_EQ(2ul, model2Again->GetIndex());
}
}

int main(int argc, char *argv[])
{
::testing::InitGoogleTest(&argc, argv);
if (!ConstructEmptyWorldTest::init(argc, argv))
return -1;
return RUN_ALL_TESTS();
}
Loading