Skip to content

Commit f3c2704

Browse files
chapulinaahcordeadlarkinnkoenigNate Koenig
authored
12 ➡️ 13 (main) (#1009)
* USD to SDF: Added Lights attached to models (#903) Signed-off-by: ahcorde <ahcorde@gmail.com> Co-authored-by: Ashton Larkin <42042756+adlarkin@users.noreply.github.com> * USD to SDF: Added diff drive plugin (#904) Signed-off-by: ahcorde <ahcorde@gmail.com> Co-authored-by: Ashton Larkin <42042756+adlarkin@users.noreply.github.com> * USD to SDF: some fixes (#991) Signed-off-by: ahcorde <ahcorde@gmail.com> * Added equality operators to Plugin (#912) * Added convenience constructor to plugin Signed-off-by: Nate Koenig <nate@openrobotics.org> * Added equality operators to Plugin Signed-off-by: Nate Koenig <nate@openrobotics.org> * Remove common dependency Signed-off-by: Nate Koenig <nate@openrobotics.org> * Fixed test Signed-off-by: Nate Koenig <nate@openrobotics.org> Co-authored-by: Nate Koenig <nate@openrobotics.org> Co-authored-by: Alejandro Hernández Cordero <ahcorde@gmail.com> Co-authored-by: Louise Poubel <louise@openrobotics.org> Co-authored-by: Alejandro Hernández Cordero <ahcorde@gmail.com> Co-authored-by: Ashton Larkin <42042756+adlarkin@users.noreply.github.com> Co-authored-by: Nate Koenig <nkoenig@users.noreply.github.com> Co-authored-by: Nate Koenig <nate@openrobotics.org>
2 parents 3099570 + a8bfc22 commit f3c2704

File tree

14 files changed

+296
-70
lines changed

14 files changed

+296
-70
lines changed

include/sdf/Plugin.hh

+12
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,18 @@ namespace sdf
144144
/// \return A reference to this plugin
145145
public: Plugin &operator=(Plugin &&_plugin) noexcept;
146146

147+
/// \brief Plugin equality operator.
148+
/// \param[in] _plugin Plugin to compare against.
149+
/// \return True if this plugin matches the provided plugin. The name,
150+
/// filename, and contents must all match to return true.
151+
public: bool operator==(const Plugin &_plugin) const;
152+
153+
/// \brief Plugin inequality operator.
154+
/// \param[in] _plugin Plugin to compare against.
155+
/// \return True if this plugin does not match the provided plugin.
156+
/// The name, filename, or contents must be different to return false.
157+
public: bool operator!=(const Plugin &_plugin) const;
158+
147159
/// \brief Output stream operator for a Plugin.
148160
/// \param[in] _out The output stream
149161
/// \param[in] _plugin Plugin to output

src/Plugin.cc

+13
Original file line numberDiff line numberDiff line change
@@ -259,3 +259,16 @@ Plugin &Plugin::operator=(Plugin &&_plugin) noexcept
259259
this->dataPtr = std::move(_plugin.dataPtr);
260260
return *this;
261261
}
262+
263+
/////////////////////////////////////////////////
264+
bool Plugin::operator==(const Plugin &_plugin) const
265+
{
266+
// Simplest thing to do is compare the string form of each plugin
267+
return _plugin.ToElement()->ToString("") == this->ToElement()->ToString("");
268+
}
269+
270+
/////////////////////////////////////////////////
271+
bool Plugin::operator!=(const Plugin &_plugin) const
272+
{
273+
return !(*this == _plugin);
274+
}

src/Plugin_TEST.cc

+31
Original file line numberDiff line numberDiff line change
@@ -385,3 +385,34 @@ TEST(DOMPlugin, InsertStringContent)
385385
EXPECT_EQ("name", plugin5.Name());
386386
EXPECT_TRUE(plugin5.Contents().empty());
387387
}
388+
389+
/////////////////////////////////////////////////
390+
TEST(DOMPlugin, EqualityOperators)
391+
{
392+
sdf::Plugin plugin("my-filename", "my-name",
393+
"<render_engine>ogre2</render_engine>");
394+
sdf::Plugin plugin2(plugin);
395+
sdf::Plugin plugin3;
396+
397+
EXPECT_EQ(plugin, plugin2);
398+
EXPECT_NE(plugin, plugin3);
399+
EXPECT_NE(plugin2, plugin3);
400+
401+
// Test contents
402+
plugin2.ClearContents();
403+
EXPECT_NE(plugin, plugin2);
404+
plugin.ClearContents();
405+
EXPECT_EQ(plugin, plugin2);
406+
407+
// test name
408+
plugin2.SetName("new-name");
409+
EXPECT_NE(plugin, plugin2);
410+
plugin.SetName("new-name");
411+
EXPECT_EQ(plugin, plugin2);
412+
413+
// test filename
414+
plugin2.SetFilename("new-filename");
415+
EXPECT_NE(plugin, plugin2);
416+
plugin.SetFilename("new-filename");
417+
EXPECT_EQ(plugin, plugin2);
418+
}

test/usd/upAxisZ.usda

+27-5
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,9 @@ def Xform "box" (
102102
double3 xformOp:translate = (0, 0, 0)
103103
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:rotateXYZ"]
104104

105-
def Cube "geometry"
105+
def Cube "geometry" (
106+
kind = "model"
107+
)
106108
{
107109
float3[] extent = [(-0.5, -0.5, -0.5), (0.5, 0.5, 0.5)]
108110
rel material:binding = </Looks/Material_1>
@@ -121,6 +123,18 @@ def Xform "box" (
121123
uniform token[] xformOpOrder = ["xformOp:scale"]
122124
}
123125
}
126+
127+
def DiskLight "boxModelLight" (
128+
prepend apiSchemas = ["ShapingAPI"]
129+
kind = "model"
130+
)
131+
{
132+
float inputs:intensity = 3000
133+
float inputs:specular = 0.5
134+
float3 xformOp:rotateZYX = (0, 0, 45)
135+
float3 xformOp:translate = (0, 0, 1000)
136+
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:rotateZYX"]
137+
}
124138
}
125139
}
126140

@@ -147,7 +161,9 @@ def Xform "cylinder"
147161
double3 xformOp:translate = (0, 0, 0)
148162
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:rotateXYZ"]
149163

150-
def Cylinder "geometry"
164+
def Cylinder "geometry" (
165+
kind = "model"
166+
)
151167
{
152168
float3[] extent = [(-0.5, -0.5, -0.5), (0.5, 0.5, 0.5)]
153169
double height = 1
@@ -190,7 +206,9 @@ def Xform "sphere"
190206
double3 xformOp:translate = (0, 0, 0)
191207
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:rotateXYZ"]
192208

193-
def Sphere "geometry"
209+
def Sphere "geometry" (
210+
kind = "model"
211+
)
194212
{
195213
float3[] extent = [(-0.5, -0.5, -0.5), (0.5, 0.5, 0.5)]
196214
rel material:binding = </Looks/Material_3>
@@ -231,7 +249,9 @@ def Xform "capsule"
231249
double3 xformOp:translate = (0, 0, 0)
232250
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:rotateZYX"]
233251

234-
def Capsule "geometry"
252+
def Capsule "geometry" (
253+
kind = "model"
254+
)
235255
{
236256
float3[] extent = [(-0.2, -0.2, -0.5), (0.2, 0.2, 0.5)]
237257
double height = 0.6
@@ -274,7 +294,9 @@ def Xform "ellipsoid"
274294
double3 xformOp:translate = (0, 0, 0)
275295
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:rotateXYZ"]
276296

277-
def Sphere "geometry"
297+
def Sphere "geometry" (
298+
kind = "model"
299+
)
278300
{
279301
float3[] extent = [(-0.5, -0.5, -0.5), (0.5, 0.5, 0.5)]
280302
rel material:binding = </Looks/Material_5>

usd/include/sdf/usd/usd_parser/Parser.hh

+4-1
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,15 @@ namespace sdf
3434
/// \brief Parse a USD file and convert it to a SDF file
3535
/// \param[in] _inputFilenameUsd Path of the USD file to parse
3636
/// \param[in] _outputFilenameSdf Path where the SDF file will be located
37+
/// \param[in] _useGazeboPlugins Whether _outputFilenameSdf should have
38+
/// gazebo plugins in it (true) or not (false)
3739
/// \return UsdErrors, which is a vector of UsdError objects. Each UsdError
3840
/// includes an error code and message. An empty vector indicates no error
3941
/// occurred when parsing the USD file to its SDF representation.
4042
UsdErrors IGNITION_SDFORMAT_USD_VISIBLE parseUSDFile(
4143
const std::string &_inputFilenameUsd,
42-
const std::string &_outputFilenameSdf);
44+
const std::string &_outputFilenameSdf,
45+
bool _useGazeboPlugins = true);
4346
}
4447
}
4548
}

usd/src/cmd/usd2sdf.cc

+11-1
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,17 @@ struct Options
4343

4444
/// \brief output filename
4545
std::string outputFilename{"output.sdf"};
46+
47+
/// \brief Whether gazebo plugins should be used in the parsed sdf file
48+
/// (true) or not (false)
49+
bool useGazeboPlugins{true};
4650
};
4751

4852
void runCommand(const Options &_opt)
4953
{
5054
const auto errors =
51-
sdf::usd::parseUSDFile(_opt.inputFilename, _opt.outputFilename);
55+
sdf::usd::parseUSDFile(_opt.inputFilename, _opt.outputFilename,
56+
_opt.useGazeboPlugins);
5257
if (!errors.empty())
5358
{
5459
std::cerr << "Errors occurred when generating [" << _opt.outputFilename
@@ -70,6 +75,11 @@ void addFlags(CLI::App &_app)
7075
opt->outputFilename,
7176
"Output filename. Defaults to output.sdf unless otherwise specified.");
7277

78+
_app.add_option("use-gazebo-plugins",
79+
opt->useGazeboPlugins,
80+
"Whether gazebo plugins should be added to the output sdf file or not. "
81+
"Defaults to true.");
82+
7383
_app.callback([&_app, opt](){
7484
runCommand(*opt);
7585
});

usd/src/usd_parser/Parser.cc

+3-2
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,13 @@ namespace usd
2727
{
2828
UsdErrors parseUSDFile(
2929
const std::string &_inputFilenameUsd,
30-
const std::string &_outputFilenameSdf)
30+
const std::string &_outputFilenameSdf,
31+
bool _useGazeboPlugins)
3132
{
3233
UsdErrors errors;
3334
USD2SDF usd2sdf;
3435
sdf::Root root;
35-
errors = usd2sdf.Read(_inputFilenameUsd, root);
36+
errors = usd2sdf.Read(_inputFilenameUsd, _useGazeboPlugins, root);
3637
if (!errors.empty())
3738
{
3839
return errors;

usd/src/usd_parser/USD2SDF.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,14 @@ namespace sdf {
3131
inline namespace SDF_VERSION_NAMESPACE {
3232
namespace usd {
3333
////////////////////////////////////////////////
34-
UsdErrors USD2SDF::Read(const std::string &_fileName,
34+
UsdErrors USD2SDF::Read(const std::string &_fileName, bool _useGazeboPlugins,
3535
sdf::Root &_root)
3636
{
3737
UsdErrors errors;
3838

3939
sdf::World sdfWorld;
4040

41-
errors = parseUSDWorld(_fileName, sdfWorld);
41+
errors = parseUSDWorld(_fileName, _useGazeboPlugins, sdfWorld);
4242
if (!errors.empty())
4343
{
4444
errors.emplace_back(UsdError(

usd/src/usd_parser/USD2SDF.hh

+3
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,16 @@ inline namespace SDF_VERSION_NAMESPACE {
4040

4141
/// \brief convert USD file to a sdf::Root object
4242
/// \param[in] _fileName string containing USD filename.
43+
/// \param[in] _useGazeboPlugins Whether _root should have gazebo plugins
44+
/// in it (true) or not (false)
4345
/// \param[out] _root Root element to populate with the equivalent sdf
4446
/// information from _fileName.
4547
/// \return UsdErrors, which is a list of UsdError objects. An empty list
4648
/// means no errors occurred when populating _root with the contents
4749
/// of _fileName
4850
public: UsdErrors Read(
4951
const std::string &_fileName,
52+
bool _useGazeboPlugins,
5053
sdf::Root &_root);
5154
};
5255
}

usd/src/usd_parser/USDLinks.cc

+30-10
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ int ParseMeshSubGeom(const pxr::UsdPrim &_prim,
233233

234234
ignition::common::SubMesh subMeshSubset;
235235
subMeshSubset.SetPrimitiveType(ignition::common::SubMesh::TRISTRIPS);
236-
subMeshSubset.SetName("subgeommesh");
236+
subMeshSubset.SetName("subgeommesh_" + std::to_string(numSubMeshes));
237237

238238
if (it != _usdData.Materials().end())
239239
{
@@ -288,12 +288,18 @@ int ParseMeshSubGeom(const pxr::UsdPrim &_prim,
288288
_meshGeom.SetUri(directoryMesh + ".dae");
289289

290290
geomSubset.SetMeshShape(_meshGeom);
291-
visSubset.SetName("mesh_subset");
291+
visSubset.SetName("mesh_subset_" + std::to_string(numSubMeshes));
292292
visSubset.SetGeom(geomSubset);
293293

294294
ignition::math::Pose3d pose;
295295
ignition::math::Vector3d scale(1, 1, 1);
296-
GetTransform(child, _usdData, pose, scale, _link->Name());
296+
std::string linkName = pxr::TfStringify(_prim.GetPath());
297+
auto found = linkName.find(_link->Name());
298+
if (found != std::string::npos)
299+
{
300+
linkName = linkName.substr(0, found + _link->Name().size());
301+
}
302+
GetTransform(child, _usdData, pose, scale, linkName);
297303
_scale *= scale;
298304
visSubset.SetRawPose(pose);
299305
_link->AddVisual(visSubset);
@@ -386,15 +392,21 @@ UsdErrors ParseMesh(
386392

387393
ignition::math::Pose3d pose;
388394
ignition::math::Vector3d scale(1, 1, 1);
389-
std::string linkName = _link->Name();
395+
std::string linkName = pxr::TfStringify(_prim.GetPath());
396+
auto found = linkName.find(_link->Name());
397+
if (found != std::string::npos)
398+
{
399+
linkName = linkName.substr(0, found + _link->Name().size());
400+
}
401+
390402
size_t nSlash = std::count(linkName.begin(), linkName.end(), '/');
391403
if (nSlash == 1)
392404
{
393405
GetTransform(_prim, _usdData, pose, scale, "/");
394406
}
395407
else
396408
{
397-
GetTransform(_prim, _usdData, pose, scale, _link->Name());
409+
GetTransform(_prim, _usdData, pose, scale, linkName);
398410
}
399411

400412
_pose = pose;
@@ -522,7 +534,7 @@ void ParseCylinder(
522534
_geom.SetType(sdf::GeometryType::CYLINDER);
523535

524536
c.SetRadius(radius * _metersPerUnit * _scale.X());
525-
c.SetLength(height * _metersPerUnit * _scale.Y());
537+
c.SetLength(height * _metersPerUnit * _scale.Z());
526538

527539
_geom.SetCylinderShape(c);
528540
}
@@ -632,9 +644,9 @@ UsdErrors ParseUSDLinks(
632644
pxr::UsdModelAPI(parent).GetKind(&kindOfSchema);
633645
}
634646

635-
if (_prim.HasAPI<pxr::UsdPhysicsRigidBodyAPI>()
636-
|| pxr::KindRegistry::IsA(kindOfSchema, pxr::KindTokens->model)
637-
|| !collisionEnabled)
647+
if ((_prim.HasAPI<pxr::UsdPhysicsRigidBodyAPI>()
648+
|| pxr::KindRegistry::IsA(kindOfSchema, pxr::KindTokens->model))
649+
&& (!collisionEnabled || _prim.HasAPI<pxr::UsdPhysicsMassAPI>()))
638650
{
639651
double metersPerUnit = data.second->MetersPerUnit();
640652

@@ -696,7 +708,15 @@ UsdErrors ParseUSDLinks(
696708

697709
ignition::math::Pose3d poseCol;
698710
ignition::math::Vector3d scaleCol(1, 1, 1);
699-
GetTransform(_prim, _usdData, poseCol, scaleCol, _link->Name());
711+
std::string linkName = pxr::TfStringify(_prim.GetPath());
712+
auto found = linkName.find(_link->Name());
713+
if (found != std::string::npos)
714+
{
715+
linkName = linkName.substr(0, found + _link->Name().size());
716+
}
717+
GetTransform(_prim, _usdData, poseCol, scaleCol, linkName);
718+
719+
scaleCol *= _scale;
700720

701721
double metersPerUnit = data.second->MetersPerUnit();
702722

usd/src/usd_parser/USDStage_TEST.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ TEST(USDStage, Constructor)
3939

4040
EXPECT_EQ("Z", stage.UpAxis());
4141
EXPECT_DOUBLE_EQ(0.01, stage.MetersPerUnit());
42-
EXPECT_EQ(25u, stage.USDPaths().size());
42+
EXPECT_EQ(26u, stage.USDPaths().size());
4343
}
4444

4545
// Check up Axis equal to Y and metersPerUnit

0 commit comments

Comments
 (0)