Skip to content

Commit 507e48a

Browse files
authored
Merge ign-msgs8 ➡️ main (#289)
Signed-off-by: Louise Poubel <louise@openrobotics.org>
2 parents 22a600a + cb8cd21 commit 507e48a

File tree

2 files changed

+185
-50
lines changed

2 files changed

+185
-50
lines changed

src/Utility.cc

Lines changed: 58 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -54,31 +54,6 @@ namespace gz
5454
return _s;
5555
}
5656

57-
/// \brief Splits a string into tokens. This was copied from Gazebo
58-
/// common, gz-common/Util.hh, to avoid adding another dependency.
59-
/// Remove this function if gz-common every becomes a dependency.
60-
/// \param[in] _str Input string.
61-
/// \param[in] _delim Token delimiter.
62-
/// \return Vector of tokens.
63-
std::vector<std::string> split(const std::string &_str,
64-
const std::string &_delim)
65-
{
66-
std::vector<std::string> tokens;
67-
char *saveptr;
68-
char *str = strdup(_str.c_str());
69-
70-
auto token = ignstrtok(str, _delim.c_str(), &saveptr);
71-
72-
while (token)
73-
{
74-
tokens.push_back(token);
75-
token = ignstrtok(NULL, _delim.c_str(), &saveptr);
76-
}
77-
78-
free(str);
79-
return tokens;
80-
}
81-
8257
/////////////////////////////////////////////
8358
gz::math::Vector3d Convert(const msgs::Vector3d &_v)
8459
{
@@ -978,10 +953,12 @@ namespace gz
978953
case msgs::PointCloudPacked::Field::FLOAT64:
979954
offset += 8;
980955
break;
956+
// LCOV_EXCL_START
981957
default:
982958
std::cerr << "PointCloudPacked field datatype of ["
983959
<< _type << "] is invalid.\n";
984960
break;
961+
// LCOV_EXCL_STOP
985962
}
986963
};
987964

@@ -1185,31 +1162,46 @@ namespace gz
11851162
return false;
11861163
}
11871164

1188-
// Get the top level <model> element.
1189-
tinyxml2::XMLElement *modelElement = modelConfigDoc.FirstChildElement(
1165+
// Get the top level <model> or <world> element.
1166+
tinyxml2::XMLElement *topElement = modelConfigDoc.FirstChildElement(
11901167
"model");
1191-
if (!modelElement)
1168+
bool isModel = true;
1169+
if (!topElement)
11921170
{
1193-
std::cerr << "Model config string does not contain a <model> element\n";
1194-
return false;
1171+
topElement = modelConfigDoc.FirstChildElement("world");
1172+
if (!topElement)
1173+
{
1174+
std::cerr << "Model config string does not contain a "
1175+
<< "<model> or <world> element\n";
1176+
return false;
1177+
}
1178+
isModel = false;
11951179
}
11961180

11971181
// Read the name, which is a mandatory element.
1198-
tinyxml2::XMLElement *elem = modelElement->FirstChildElement("name");
1182+
tinyxml2::XMLElement *elem = topElement->FirstChildElement("name");
11991183
if (!elem || !elem->GetText())
12001184
{
12011185
std::cerr << "Model config string does not contain a <name> element\n";
12021186
return false;
12031187
}
12041188
meta.set_name(trimmed(elem->GetText()));
12051189

1190+
// Read the version, if present.
1191+
elem = topElement->FirstChildElement("version");
1192+
if (elem && elem->GetText())
1193+
{
1194+
auto version = std::stoi(trimmed(elem->GetText()));
1195+
meta.set_version(version);
1196+
}
1197+
12061198
// Read the description, if present.
1207-
elem = modelElement->FirstChildElement("description");
1199+
elem = topElement->FirstChildElement("description");
12081200
if (elem && elem->GetText())
12091201
meta.set_description(trimmed(elem->GetText()));
12101202

12111203
// Read the dependencies, if any.
1212-
elem = modelElement->FirstChildElement("depend");
1204+
elem = topElement->FirstChildElement("depend");
12131205
while (elem)
12141206
{
12151207
auto modelElem = elem->FirstChildElement("model");
@@ -1226,7 +1218,7 @@ namespace gz
12261218
}
12271219

12281220
// Read the authors, if any.
1229-
elem = modelElement->FirstChildElement("author");
1221+
elem = topElement->FirstChildElement("author");
12301222
while (elem)
12311223
{
12321224
gz::msgs::FuelMetadata::Contact *author = meta.add_authors();
@@ -1247,7 +1239,7 @@ namespace gz
12471239
}
12481240

12491241
// Get the most recent SDF file
1250-
elem = modelElement->FirstChildElement("sdf");
1242+
elem = topElement->FirstChildElement("sdf");
12511243
math::SemanticVersion maxVer;
12521244
while (elem)
12531245
{
@@ -1257,23 +1249,34 @@ namespace gz
12571249
math::SemanticVersion ver(trimmed(verStr));
12581250
if (ver > maxVer)
12591251
{
1260-
meta.mutable_model()->mutable_file_format()->set_name("sdf");
1261-
gz::msgs::Version *verMsg =
1262-
meta.mutable_model()->mutable_file_format()->mutable_version();
1252+
gz::msgs::Version *verMsg;
1253+
1254+
if (isModel)
1255+
{
1256+
meta.mutable_model()->mutable_file_format()->set_name("sdf");
1257+
verMsg =
1258+
meta.mutable_model()->mutable_file_format()->mutable_version();
1259+
meta.mutable_model()->set_file(trimmed(elem->GetText()));
1260+
}
1261+
else
1262+
{
1263+
meta.mutable_world()->mutable_file_format()->set_name("sdf");
1264+
verMsg =
1265+
meta.mutable_world()->mutable_file_format()->mutable_version();
1266+
meta.mutable_world()->set_file(trimmed(elem->GetText()));
1267+
}
12631268

12641269
verMsg->set_major(ver.Major());
12651270
verMsg->set_minor(ver.Minor());
12661271
verMsg->set_patch(ver.Patch());
12671272
verMsg->set_prerelease(ver.Prerelease());
12681273
verMsg->set_build(ver.Build());
1269-
1270-
meta.mutable_model()->set_file(trimmed(elem->GetText()));
12711274
}
12721275
}
12731276

12741277
elem = elem->NextSiblingElement("sdf");
12751278
}
1276-
if (meta.model().file().empty())
1279+
if (meta.model().file().empty() && meta.world().file().empty())
12771280
{
12781281
std::cerr << "Model config string does not contain an <sdf> element\n";
12791282
return false;
@@ -1299,7 +1302,11 @@ namespace gz
12991302
}
13001303

13011304
out << "<?xml version='1.0'?>\n"
1302-
<< " <model>\n";
1305+
<< " <model>\n"
1306+
<< " <sdf version='"
1307+
<< _meta.model().file_format().version().major()
1308+
<< "." << _meta.model().file_format().version().minor() << "'>"
1309+
<< _meta.model().file() << "</sdf>\n";
13031310
}
13041311
else
13051312
{
@@ -1310,15 +1317,16 @@ namespace gz
13101317
}
13111318

13121319
out << "<?xml version='1.0'?>\n"
1313-
<< " <world>\n";
1320+
<< " <world>\n"
1321+
<< " <sdf version='"
1322+
<< _meta.world().file_format().version().major()
1323+
<< "." << _meta.world().file_format().version().minor() << "'>"
1324+
<< _meta.world().file() << "</sdf>\n";
13141325
}
13151326

13161327
out << " <name>" << _meta.name() << "</name>\n"
1317-
<< " <version>" << _meta.version() << "</version>\n"
1318-
<< " <sdf version='" << _meta.model().file_format().version().major()
1319-
<< "." << _meta.model().file_format().version().minor() << "'>"
1320-
<< _meta.model().file() << "</sdf>\n"
1321-
<< " <description>" << _meta.description() << "</description>\n";
1328+
<< " <version>" << _meta.version() << "</version>\n"
1329+
<< " <description>" << _meta.description() << "</description>\n";
13221330

13231331
// Output author information.
13241332
for (int i = 0; i < _meta.authors_size(); ++i)
@@ -1333,9 +1341,9 @@ namespace gz
13331341
for (int i = 0; i < _meta.dependencies_size(); ++i)
13341342
{
13351343
out << " <depend>\n"
1336-
<< " <model>"
1344+
<< " <model>\n"
13371345
<< " <uri>" << _meta.dependencies(i).uri() << "</uri>\n"
1338-
<< " </model>"
1346+
<< " </model>\n"
13391347
<< " </depend>\n";
13401348
}
13411349

src/Utility_TEST.cc

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,133 @@ TEST(UtilityTest, ConvertFloat)
478478
EXPECT_DOUBLE_EQ(s, 0.999f);
479479
}
480480

481+
482+
/////////////////////////////////////////////////
483+
TEST(UtilityTest, ConvertFuelMetadata)
484+
{
485+
msgs::FuelMetadata metaMsg;
486+
std::string modelConfigInput, worldConfigInput;
487+
488+
// test ConvertFuelMetadata(string, msgs::FuelMetadata)
489+
{
490+
EXPECT_FALSE(msgs::ConvertFuelMetadata(modelConfigInput, metaMsg));
491+
492+
metaMsg.Clear();
493+
modelConfigInput = "<test/>";
494+
EXPECT_FALSE(msgs::ConvertFuelMetadata(modelConfigInput, metaMsg));
495+
496+
metaMsg.Clear();
497+
modelConfigInput = "<model>test</model>";
498+
EXPECT_FALSE(msgs::ConvertFuelMetadata(modelConfigInput, metaMsg));
499+
500+
// Test <model>
501+
metaMsg.Clear();
502+
modelConfigInput = R"(
503+
<model>
504+
<name>test_model</name>
505+
</model>
506+
)";
507+
EXPECT_FALSE(msgs::ConvertFuelMetadata(modelConfigInput, metaMsg));
508+
509+
metaMsg.Clear();
510+
modelConfigInput = R"(<?xml version='1.0'?>
511+
<model>
512+
<sdf version='1.7'>model.sdf</sdf>
513+
<name>test_model</name>
514+
<version>3</version>
515+
<description>A model for testing</description>
516+
<author>
517+
<name>Foo Bar</name>
518+
<email>foo@bar.org</email>
519+
</author>
520+
<depend>
521+
<model>
522+
<uri>model://some_model</uri>
523+
</model>
524+
</depend>
525+
</model>
526+
)";
527+
528+
EXPECT_TRUE(msgs::ConvertFuelMetadata(modelConfigInput, metaMsg));
529+
EXPECT_EQ("test_model", metaMsg.name());
530+
EXPECT_EQ(3, metaMsg.version());
531+
EXPECT_EQ("A model for testing", metaMsg.description());
532+
EXPECT_EQ("model.sdf", metaMsg.model().file());
533+
EXPECT_EQ("sdf", metaMsg.model().file_format().name());
534+
EXPECT_EQ(1, metaMsg.model().file_format().version().major());
535+
EXPECT_EQ(7, metaMsg.model().file_format().version().minor());
536+
EXPECT_EQ(1, metaMsg.authors().size());
537+
EXPECT_EQ("Foo Bar", metaMsg.authors(0).name());
538+
EXPECT_EQ("foo@bar.org", metaMsg.authors(0).email());
539+
EXPECT_EQ(1, metaMsg.dependencies().size());
540+
EXPECT_EQ("model://some_model", metaMsg.dependencies(0).uri());
541+
542+
// Test <world>
543+
metaMsg.Clear();
544+
worldConfigInput = R"(<?xml version='1.0'?>
545+
<world>
546+
<sdf version='1.7'>world.sdf</sdf>
547+
<name>test_world</name>
548+
<version>2</version>
549+
<description>A world for testing</description>
550+
</world>
551+
)";
552+
EXPECT_TRUE(msgs::ConvertFuelMetadata(worldConfigInput, metaMsg));
553+
EXPECT_EQ("test_world", metaMsg.name());
554+
EXPECT_EQ(2, metaMsg.version());
555+
EXPECT_EQ("A world for testing", metaMsg.description());
556+
EXPECT_EQ("world.sdf", metaMsg.world().file());
557+
EXPECT_EQ("sdf", metaMsg.world().file_format().name());
558+
EXPECT_EQ(1, metaMsg.world().file_format().version().major());
559+
EXPECT_EQ(7, metaMsg.world().file_format().version().minor());
560+
EXPECT_EQ(0, metaMsg.authors().size());
561+
EXPECT_EQ(0, metaMsg.dependencies().size());
562+
}
563+
564+
// test ConvertFuelMetadata(msgs::FuelMetadata, string)
565+
{
566+
std::string modelConfig;
567+
568+
// Test <world>
569+
metaMsg.Clear();
570+
metaMsg.mutable_world()->set_file("world.sdf");
571+
EXPECT_FALSE(msgs::ConvertFuelMetadata(metaMsg, modelConfig));
572+
573+
metaMsg.set_name("test_world");
574+
metaMsg.set_description("A world for testing");
575+
metaMsg.set_version(2);
576+
metaMsg.mutable_world()->mutable_file_format()->set_name("sdf");
577+
metaMsg.mutable_world()->mutable_file_format()
578+
->mutable_version()->set_major(1);
579+
metaMsg.mutable_world()->mutable_file_format()
580+
->mutable_version()->set_minor(7);
581+
EXPECT_TRUE(msgs::ConvertFuelMetadata(metaMsg, modelConfig));
582+
583+
EXPECT_EQ(worldConfigInput, modelConfig);
584+
585+
// Test <model>
586+
metaMsg.Clear();
587+
metaMsg.mutable_model()->set_file("model.sdf");
588+
EXPECT_FALSE(msgs::ConvertFuelMetadata(metaMsg, modelConfig));
589+
590+
metaMsg.set_name("test_model");
591+
metaMsg.set_description("A model for testing");
592+
metaMsg.set_version(3);
593+
metaMsg.mutable_model()->mutable_file_format()->set_name("sdf");
594+
metaMsg.mutable_model()->mutable_file_format()
595+
->mutable_version()->set_major(1);
596+
metaMsg.mutable_model()->mutable_file_format()
597+
->mutable_version()->set_minor(7);
598+
EXPECT_TRUE(msgs::ConvertFuelMetadata(metaMsg, modelConfig));
599+
600+
metaMsg.add_authors()->set_name("Foo Bar");
601+
metaMsg.mutable_authors(0)->set_email("foo@bar.org");
602+
metaMsg.add_dependencies()->set_uri("model://some_model");
603+
EXPECT_TRUE(msgs::ConvertFuelMetadata(metaMsg, modelConfig));
604+
EXPECT_EQ(modelConfigInput, modelConfig);
605+
}
606+
}
607+
481608
/////////////////////////////////////////////////
482609
TEST(UtilityTest, ConvertTimePoint)
483610
{

0 commit comments

Comments
 (0)