Skip to content

Commit

Permalink
Enable StoreResolvedURIs when loading SDF (#2349)
Browse files Browse the repository at this point in the history

---------

Signed-off-by: Ian Chen <[email protected]>
  • Loading branch information
iche033 authored Apr 19, 2024
1 parent 363f582 commit 4e50fab
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 8 deletions.
20 changes: 19 additions & 1 deletion include/gz/sim/ServerConfig.hh
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ namespace gz
kSdfString,
};

/// \brief SDF error behavior
public: enum class SdfErrorBehavior
{
/// \brief Exit the server immediately
EXIT_IMMEDIATELY,
/// \brief Continue loading the server if possible
CONTINUE_LOADING
};

class PluginInfoPrivate;
/// \brief Information about a plugin that should be loaded by the
Expand Down Expand Up @@ -386,7 +394,17 @@ namespace gz
const std::string &_apiBackend);

/// \return Api backend for gui. See SetRenderEngineGuiApiBackend()
const std::string &RenderEngineGuiApiBackend() const;
public: const std::string &RenderEngineGuiApiBackend() const;

/// \brief Set the server behavior when SDF errors are encountered while
//// loading the server.
/// \param[in] _behavior Server behavior when SDF errors are encounted.
public: void SetBehaviorOnSdfErrors(SdfErrorBehavior _behavior);

/// \brief Get the behavior when SDF errors are encountered while
//// loading the server.
/// \return Server behavior when SDF errors are encounted.
public: SdfErrorBehavior BehaviorOnSdfErrors() const;

/// \brief Instruct simulation to attach a plugin to a specific
/// entity when simulation starts.
Expand Down
15 changes: 12 additions & 3 deletions src/Server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ Server::Server(const ServerConfig &_config)
}
gzmsg << msg;
sdf::ParserConfig sdfParserConfig = sdf::ParserConfig::GlobalConfig();
sdfParserConfig.SetStoreResolvedURIs(true);
sdfParserConfig.SetCalculateInertialConfiguration(
sdf::ConfigureResolveAutoInertials::SKIP_CALCULATION_IN_LOAD);
errors = this->dataPtr->sdfRoot.LoadSdfString(
Expand All @@ -145,6 +146,7 @@ Server::Server(const ServerConfig &_config)

sdf::Root sdfRoot;
sdf::ParserConfig sdfParserConfig = sdf::ParserConfig::GlobalConfig();
sdfParserConfig.SetStoreResolvedURIs(true);
sdfParserConfig.SetCalculateInertialConfiguration(
sdf::ConfigureResolveAutoInertials::SKIP_CALCULATION_IN_LOAD);

Expand All @@ -156,7 +158,8 @@ Server::Server(const ServerConfig &_config)
// a black screen (search for "Async resource download" in
// 'src/gui_main.cc'.
errors = sdfRoot.Load(filePath, sdfParserConfig);
if (errors.empty()) {
if (errors.empty() || _config.BehaviorOnSdfErrors() !=
ServerConfig::SdfErrorBehavior::EXIT_IMMEDIATELY) {
if (sdfRoot.Model() == nullptr) {
this->dataPtr->sdfRoot = std::move(sdfRoot);
}
Expand All @@ -171,7 +174,9 @@ Server::Server(const ServerConfig &_config)
return;
}
world->AddModel(*sdfRoot.Model());
if (errors.empty()) {
if (errors.empty() || _config.BehaviorOnSdfErrors() !=
ServerConfig::SdfErrorBehavior::EXIT_IMMEDIATELY)
{
errors = this->dataPtr->sdfRoot.UpdateGraphs();
}
}
Expand All @@ -196,7 +201,11 @@ Server::Server(const ServerConfig &_config)
{
for (auto &err : errors)
gzerr << err << "\n";
return;
if (_config.BehaviorOnSdfErrors() ==
ServerConfig::SdfErrorBehavior::EXIT_IMMEDIATELY)
{
return;
}
}

// Add record plugin
Expand Down
20 changes: 19 additions & 1 deletion src/ServerConfig.cc
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,8 @@ class gz::sim::ServerConfigPrivate
seed(_cfg->seed),
logRecordTopics(_cfg->logRecordTopics),
isHeadlessRendering(_cfg->isHeadlessRendering),
source(_cfg->source){ }
source(_cfg->source),
behaviorOnSdfErrors(_cfg->behaviorOnSdfErrors){ }

// \brief The SDF file that the server should load
public: std::string sdfFile = "";
Expand Down Expand Up @@ -292,6 +293,10 @@ class gz::sim::ServerConfigPrivate

/// \brief Type of source used.
public: ServerConfig::SourceType source{ServerConfig::SourceType::kNone};

/// \brief Server loading behavior in presence of SDF errors.
public: ServerConfig::SdfErrorBehavior behaviorOnSdfErrors{
ServerConfig::SdfErrorBehavior::EXIT_IMMEDIATELY};
};

//////////////////////////////////////////////////
Expand Down Expand Up @@ -598,6 +603,19 @@ const std::string &ServerConfig::RenderEngineGuiApiBackend() const
return this->dataPtr->renderEngineGuiApiBackend;
}

//////////////////////////////////////////////////
void ServerConfig::SetBehaviorOnSdfErrors(
ServerConfig::SdfErrorBehavior _behavior)
{
this->dataPtr->behaviorOnSdfErrors = _behavior;
}

//////////////////////////////////////////////////
ServerConfig::SdfErrorBehavior ServerConfig::BehaviorOnSdfErrors() const
{
return this->dataPtr->behaviorOnSdfErrors;
}

/////////////////////////////////////////////////
void ServerConfig::AddPlugin(const ServerConfig::PluginInfo &_info)
{
Expand Down
17 changes: 16 additions & 1 deletion src/Server_Rendering_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,10 @@ TEST_F(ServerFixture, GZ_UTILS_TEST_DISABLED_ON_MAC(LoadSdfModelRelativeUri))
};

gz::sim::ServerConfig serverConfig;

serverConfig.SetBehaviorOnSdfErrors(
ServerConfig::SdfErrorBehavior::CONTINUE_LOADING);
EXPECT_EQ(ServerConfig::SdfErrorBehavior::CONTINUE_LOADING,
serverConfig.BehaviorOnSdfErrors());
serverConfig.SetSdfFile(common::joinPaths(PROJECT_SOURCE_PATH,
"test", "worlds", "models", "relative_resource_uri", "model2.sdf"));

Expand Down Expand Up @@ -162,4 +165,16 @@ TEST_F(ServerFixture, GZ_UTILS_TEST_DISABLED_ON_MAC(LoadSdfModelRelativeUri))
}
ASSERT_TRUE(server.RunOnce());
ASSERT_TRUE(server.RunOnce(false));

// Tell server to stop loading if there are SDF errors
// Server should not load because V2's visual mesh URI can not be resolved
serverConfig.SetBehaviorOnSdfErrors(
ServerConfig::SdfErrorBehavior::EXIT_IMMEDIATELY);
EXPECT_EQ(ServerConfig::SdfErrorBehavior::EXIT_IMMEDIATELY,
serverConfig.BehaviorOnSdfErrors());
sim::Server server2 = Server(serverConfig);
EXPECT_FALSE(server2.HasEntity("relative_resource_uri"));
EXPECT_FALSE(server2.HasEntity("L1"));
EXPECT_FALSE(server2.HasEntity("V1"));
EXPECT_FALSE(server2.HasEntity("V2"));
}
7 changes: 5 additions & 2 deletions src/Server_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1012,8 +1012,11 @@ TEST_P(ServerFixture, GZ_UTILS_TEST_DISABLED_ON_WIN32(ResourcePath))

if (mesh)
{
EXPECT_EQ("model://scheme_resource_uri/meshes/box.dae",
mesh->Uri());
// StoreResolvedURIs is set to true so expect full path
EXPECT_NE(std::string::npos,
mesh->Uri().find("scheme_resource_uri/meshes/box.dae"));
EXPECT_FALSE(common::isRelativePath(mesh->Uri()));
EXPECT_TRUE(common::isFile(mesh->Uri()));
}

eachCount++;
Expand Down
7 changes: 7 additions & 0 deletions src/Util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -397,12 +397,19 @@ std::string asFullPath(const std::string &_uri, const std::string &_filePath)
{
return _uri;
}
#elif defined(_WIN32)
if (_uri.find("://") != std::string::npos ||
common::isFile(_uri))
{
return _uri;
}
#else
if (_uri.find("://") != std::string::npos ||
!common::isRelativePath(_uri))
{
return _uri;
}

#endif

// When SDF is loaded from a string instead of a file
Expand Down

0 comments on commit 4e50fab

Please sign in to comment.