Skip to content

Commit

Permalink
Merge branch 'sdf12' into ahcorde/sdf_to_usd_visuals
Browse files Browse the repository at this point in the history
  • Loading branch information
ahcorde authored Feb 24, 2022
2 parents 00a55c5 + 5a2b5df commit 0d483a7
Show file tree
Hide file tree
Showing 10 changed files with 120 additions and 7 deletions.
8 changes: 8 additions & 0 deletions include/sdf/Light.hh
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,14 @@ namespace sdf
/// \param[in] _cast True to indicate that the light casts shadows.
public: void SetCastShadows(const bool _cast);

/// \brief Get if the light is on
/// \return True if the light is on.
public: bool LightOn() const;

/// \brief Set if the light is ON/OFF
/// \param[in] _cast True to indicate that the light is on, False otherwise.
public: void SetLightOn(const bool _isLightOn);

/// \brief Get the light intensity
/// \return The light intensity
public: double Intensity() const;
Expand Down
12 changes: 12 additions & 0 deletions include/sdf/Model.hh
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,18 @@ namespace sdf
/// \return SDF element pointer with updated model values.
public: sdf::ElementPtr ToElement(bool _useIncludeTag = true) const;

/// \brief Check if a given name exists in the FrameAttachedTo graph at the
/// scope of the model.
/// \param[in] _name Name of the implicit or explicit frame to check.
/// To check for a frame in a nested model, prefix the frame name with
/// the sequence of nested models containing this frame, delimited by "::".
/// \return True if the frame name is found in the FrameAttachedTo graph.
/// False otherwise, or if the frame graph is invalid.
/// \note This function assumes the model has a valid FrameAttachedTo graph.
/// It will return false if the graph is invalid.
public: bool NameExistsInFrameAttachedToGraph(
const std::string &_name) const;

/// \brief Add a link to the model.
/// \param[in] _link Link to add.
/// \return True if successful, false if a link with the name already
Expand Down
4 changes: 4 additions & 0 deletions sdf/1.8/light.sdf
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
<description>When true, the light will cast shadows.</description>
</element>

<element name="light_on" type="bool" default="true" required="0">
<description>When true, the light is on.</description>
</element>

<element name="intensity" type="double" default="1" required="0">
<description>Scale factor to set the relative power of a light.</description>
</element>
Expand Down
4 changes: 4 additions & 0 deletions sdf/1.9/light.sdf
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
<description>When true, the light will cast shadows.</description>
</element>

<element name="light_on" type="bool" default="true" required="0">
<description>When true, the light is on.</description>
</element>

<element name="intensity" type="double" default="1" required="0">
<description>Scale factor to set the relative power of a light.</description>
</element>
Expand Down
18 changes: 18 additions & 0 deletions src/Light.cc
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ class sdf::Light::Implementation

/// \brief Spot light falloff.
public: double spotFalloff = 0.0;

/// \brief Is light on ?
public: bool isLightOn = true;
};

/////////////////////////////////////////////////
Expand Down Expand Up @@ -142,6 +145,9 @@ Errors Light::Load(ElementPtr _sdf)
// Load the pose. Ignore the return value since the light pose is optional.
loadPose(_sdf, this->dataPtr->pose, this->dataPtr->poseRelativeTo);

this->dataPtr->isLightOn = _sdf->Get<bool>("light_on",
this->dataPtr->isLightOn).first;

this->dataPtr->castShadows = _sdf->Get<bool>("cast_shadows",
this->dataPtr->castShadows).first;

Expand Down Expand Up @@ -317,6 +323,18 @@ void Light::SetCastShadows(const bool _cast)
this->dataPtr->castShadows = _cast;
}

/////////////////////////////////////////////////
bool Light::LightOn() const
{
return this->dataPtr->isLightOn;
}

/////////////////////////////////////////////////
void Light::SetLightOn(const bool _isLightOn)
{
this->dataPtr->isLightOn = _isLightOn;
}

/////////////////////////////////////////////////
ignition::math::Color Light::Diffuse() const
{
Expand Down
12 changes: 12 additions & 0 deletions src/Light_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ TEST(DOMLight, DefaultConstruction)
EXPECT_FALSE(semanticPose.Resolve(pose).empty());
}

EXPECT_TRUE(light.LightOn());
light.SetLightOn(false);
EXPECT_FALSE(light.LightOn());

EXPECT_FALSE(light.CastShadows());
light.SetCastShadows(true);
EXPECT_TRUE(light.CastShadows());
Expand Down Expand Up @@ -113,6 +117,7 @@ TEST(DOMLight, CopyConstructor)
light.SetRawPose({3, 2, 1, 0, IGN_PI, 0});
light.SetPoseRelativeTo("ground_plane");
light.SetCastShadows(true);
light.SetLightOn(false);
light.SetDiffuse(ignition::math::Color(0.4f, 0.5f, 0.6f, 1.0));
light.SetSpecular(ignition::math::Color(0.8f, 0.9f, 0.1f, 1.0));
light.SetAttenuationRange(3.2);
Expand All @@ -131,6 +136,7 @@ TEST(DOMLight, CopyConstructor)
EXPECT_EQ(ignition::math::Pose3d(3, 2, 1, 0, IGN_PI, 0), light2.RawPose());
EXPECT_EQ("ground_plane", light2.PoseRelativeTo());
EXPECT_TRUE(light2.CastShadows());
EXPECT_FALSE(light2.LightOn());
EXPECT_EQ(ignition::math::Color(0.4f, 0.5f, 0.6f, 1), light2.Diffuse());
EXPECT_EQ(ignition::math::Color(0.8f, 0.9f, 0.1f, 1), light2.Specular());
EXPECT_DOUBLE_EQ(3.2, light2.AttenuationRange());
Expand All @@ -153,6 +159,7 @@ TEST(DOMLight, CopyAssignmentOperator)
light.SetRawPose({3, 2, 1, 0, IGN_PI, 0});
light.SetPoseRelativeTo("ground_plane");
light.SetCastShadows(true);
light.SetLightOn(false);
light.SetDiffuse(ignition::math::Color(0.4f, 0.5f, 0.6f, 1.0));
light.SetSpecular(ignition::math::Color(0.8f, 0.9f, 0.1f, 1.0));
light.SetAttenuationRange(3.2);
Expand All @@ -172,6 +179,7 @@ TEST(DOMLight, CopyAssignmentOperator)
EXPECT_EQ(ignition::math::Pose3d(3, 2, 1, 0, IGN_PI, 0), light2.RawPose());
EXPECT_EQ("ground_plane", light2.PoseRelativeTo());
EXPECT_TRUE(light2.CastShadows());
EXPECT_FALSE(light2.LightOn());
EXPECT_EQ(ignition::math::Color(0.4f, 0.5f, 0.6f, 1), light2.Diffuse());
EXPECT_EQ(ignition::math::Color(0.8f, 0.9f, 0.1f, 1), light2.Specular());
EXPECT_DOUBLE_EQ(3.2, light2.AttenuationRange());
Expand All @@ -194,6 +202,7 @@ TEST(DOMLight, MoveConstructor)
light.SetRawPose({3, 2, 1, 0, IGN_PI, 0});
light.SetPoseRelativeTo("ground_plane");
light.SetCastShadows(true);
light.SetLightOn(false);
light.SetDiffuse(ignition::math::Color(0.4f, 0.5f, 0.6f, 1.0));
light.SetSpecular(ignition::math::Color(0.8f, 0.9f, 0.1f, 1.0));
light.SetAttenuationRange(3.2);
Expand All @@ -212,6 +221,7 @@ TEST(DOMLight, MoveConstructor)
EXPECT_EQ(ignition::math::Pose3d(3, 2, 1, 0, IGN_PI, 0), light2.RawPose());
EXPECT_EQ("ground_plane", light2.PoseRelativeTo());
EXPECT_TRUE(light2.CastShadows());
EXPECT_FALSE(light2.LightOn());
EXPECT_EQ(ignition::math::Color(0.4f, 0.5f, 0.6f, 1), light2.Diffuse());
EXPECT_EQ(ignition::math::Color(0.8f, 0.9f, 0.1f, 1), light2.Specular());
EXPECT_DOUBLE_EQ(3.2, light2.AttenuationRange());
Expand All @@ -234,6 +244,7 @@ TEST(DOMLight, MoveAssignment)
light.SetRawPose({3, 2, 1, 0, IGN_PI, 0});
light.SetPoseRelativeTo("ground_plane");
light.SetCastShadows(true);
light.SetLightOn(false);
light.SetDiffuse(ignition::math::Color(0.4f, 0.5f, 0.6f, 1.0));
light.SetSpecular(ignition::math::Color(0.8f, 0.9f, 0.1f, 1.0));
light.SetAttenuationRange(3.2);
Expand All @@ -253,6 +264,7 @@ TEST(DOMLight, MoveAssignment)
EXPECT_EQ(ignition::math::Pose3d(3, 2, 1, 0, IGN_PI, 0), light2.RawPose());
EXPECT_EQ("ground_plane", light2.PoseRelativeTo());
EXPECT_TRUE(light2.CastShadows());
EXPECT_FALSE(light2.LightOn());
EXPECT_EQ(ignition::math::Color(0.4f, 0.5f, 0.6f, 1), light2.Diffuse());
EXPECT_EQ(ignition::math::Color(0.8f, 0.9f, 0.1f, 1), light2.Specular());
EXPECT_DOUBLE_EQ(3.2, light2.AttenuationRange());
Expand Down
10 changes: 10 additions & 0 deletions src/Model.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1062,3 +1062,13 @@ void Model::ClearFrames()
{
this->dataPtr->frames.clear();
}

/////////////////////////////////////////////////
bool Model::NameExistsInFrameAttachedToGraph(const std::string &_name) const
{
if (!this->dataPtr->frameAttachedToGraph)
return false;

return this->dataPtr->frameAttachedToGraph.VertexIdByName(sdf::JoinName(
this->Name(), _name)) != ignition::math::graph::kNullId;
}
10 changes: 3 additions & 7 deletions src/parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2549,9 +2549,7 @@ void checkJointParentChildNames(const sdf::Root *_root, Errors &_errors)
const std::string parentLocalName = sdf::SplitName(parentName).second;

if (parentName != "world" && parentLocalName != "__model__" &&
!_model->LinkNameExists(parentName) &&
!_model->JointNameExists(parentName) &&
!_model->FrameNameExists(parentName))
!_model->NameExistsInFrameAttachedToGraph(parentName))
{
errors.push_back({ErrorCode::JOINT_PARENT_LINK_INVALID,
"parent frame with name[" + parentName +
Expand All @@ -2568,10 +2566,8 @@ void checkJointParentChildNames(const sdf::Root *_root, Errors &_errors)
joint->Name() + "] in model with name[" + _model->Name() + "]."});
}

if (childLocalName != "__model__" && !_model->LinkNameExists(childName) &&
!_model->JointNameExists(childName) &&
!_model->FrameNameExists(childName) &&
!_model->ModelNameExists(childName))
if (childLocalName != "__model__" &&
!_model->NameExistsInFrameAttachedToGraph(childName))
{
errors.push_back({ErrorCode::JOINT_CHILD_LINK_INVALID,
"child frame with name[" + childName +
Expand Down
32 changes: 32 additions & 0 deletions test/integration/interface_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1246,3 +1246,35 @@ TEST_F(InterfaceAPIMergeInclude, JointModelChild)
EXPECT_EQ("base", body);
}
}

/////////////////////////////////////////////////
TEST_F(InterfaceAPI, JointParentOrChildInNestedModel)
{
this->config.RegisterCustomModelParser(customTomlParser);

const std::string testSdf = R"(
<sdf version="1.8">
<model name="parent_model">
<link name="L1"/>
<joint name="J1" type="fixed">
<parent>L1</parent>
<child>double_pendulum::base</child>
</joint>
<include>
<uri>double_pendulum.toml</uri>
<name>double_pendulum</name>
</include>
<joint name="J2" type="fixed">
<parent>double_pendulum::child_dp::base</parent>
<child>L2</child>
</joint>
<link name="L2"/>
</model>
</sdf>)";
sdf::Root root;
sdf::Errors errors = root.LoadSdfString(testSdf, this->config);
EXPECT_TRUE(errors.empty()) << errors;
}
17 changes: 17 additions & 0 deletions test/integration/model_dom.cc
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,23 @@ TEST(DOMRoot, MultiNestedModel)
EXPECT_EQ(innerModel->FrameByIndex(0),
outerModel->FrameByName(innerFrameNestedName));
EXPECT_NE(nullptr, outerModel->FrameByName(innerFrameNestedName));


// Check that each implicit/explicit frame is in the frame attached to graph
EXPECT_TRUE(outerModel->NameExistsInFrameAttachedToGraph("outer_link"));
EXPECT_TRUE(outerModel->NameExistsInFrameAttachedToGraph("outer_joint"));
EXPECT_TRUE(outerModel->NameExistsInFrameAttachedToGraph("outer_frame"));
EXPECT_TRUE(outerModel->NameExistsInFrameAttachedToGraph("mid_model"));

// Check that mid_link does not exist directly under outer_model, but can be
// accessed via its scoped name
EXPECT_FALSE(outerModel->NameExistsInFrameAttachedToGraph("mid_link"));
EXPECT_TRUE(
outerModel->NameExistsInFrameAttachedToGraph("mid_model::mid_link"));

// Check multiple levels of nesting
EXPECT_TRUE(outerModel->NameExistsInFrameAttachedToGraph(
"mid_model::inner_model::inner_joint"));
}

/////////////////////////////////////////////////
Expand Down

0 comments on commit 0d483a7

Please sign in to comment.