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

Enable StoreResolvedURIs when loading SDF #2349

Merged
merged 10 commits into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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
Loading