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

Implement SDFormat 1.8 Interface API #475

Merged
merged 76 commits into from
Mar 25, 2021
Merged
Show file tree
Hide file tree
Changes from 75 commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
c4e2ba4
Remove outdated error message
azeey Dec 12, 2020
89dc847
Add ParserConfig class to encapsulate file path settings
azeey Dec 12, 2020
7badb17
Use semi-colon as path separator in windows
azeey Dec 15, 2020
b4f1da3
Add header to CMakeLists
azeey Dec 15, 2020
e3e05f3
Merge remote-tracking branch 'upstream/master' into parser_config
azeey Dec 15, 2020
f9e3ef2
Address reviewer feedback
azeey Dec 19, 2020
deda523
Rename DefaultConfig to GlobalConfig
azeey Dec 19, 2020
b9bb22b
Fix style
azeey Dec 19, 2020
66d2967
Remove outdated error message
azeey Dec 12, 2020
d06e21d
Add ParserConfig class to encapsulate file path settings
azeey Dec 12, 2020
ad2f9a3
Use semi-colon as path separator in windows
azeey Dec 15, 2020
db1de1d
Add header to CMakeLists
azeey Dec 15, 2020
81d7998
Address reviewer feedback
azeey Dec 19, 2020
a00553d
Rename DefaultConfig to GlobalConfig
azeey Dec 19, 2020
e8e7237
Fix style
azeey Dec 19, 2020
84f80f4
Allow files paths for include URIs
azeey Dec 23, 2020
b84443b
WIP
azeey Dec 23, 2020
61eec3f
Update test expectations after merge
azeey Dec 24, 2020
b8a8f6b
WIP: TOML parser with array of tables
azeey Jan 7, 2021
2f498cc
WIP: Map of Maps TOML data structure
azeey Jan 9, 2021
b9a4be2
Add ign-utils dependency
azeey Jan 9, 2021
a8bfcf4
WIP: Add NestedIncludeData test
azeey Jan 9, 2021
46a4d68
Add InterfaceFrame
azeey Jan 14, 2021
ddafb64
Merge remote-tracking branch 'upstream/master' into parser_config
azeey Jan 14, 2021
e358786
Add InterfaceJoint
azeey Jan 21, 2021
74eacf0
Merge remote-tracking branch 'upstream/master' into parser_config
azeey Jan 21, 2021
f088be8
Fix test expectations after merge
azeey Jan 21, 2021
5084a6d
Merge remote-tracking branch 'upstream/master' into parser_config
azeey Jan 21, 2021
4099c44
Merge remote-tracking branch 'upstream/master' into interface_api
azeey Jan 22, 2021
52d57c1
Build pose relative-to and frame attached-to graphs for interface ele…
azeey Jan 29, 2021
5dfe1a0
Merge branch 'master' into parser_config
scpeters Feb 2, 2021
1cf635a
Merge branch 'master' into parser_config
scpeters Feb 2, 2021
e42bbda
sdf -> SDF
azeey Feb 2, 2021
6388959
Use ImplPtr for ParserConfig
azeey Feb 2, 2021
fde3b1b
Implement initString overload
azeey Feb 2, 2021
6f53a9f
List the search order in sdf::findFile
azeey Feb 2, 2021
8977cd1
Add test checking that URI paths have precedence over findFile callbacks
azeey Feb 2, 2021
5972b53
Codecheck
azeey Feb 2, 2021
1d321e0
Add reference to `sdf::findFile` in the docs of ParserConfig
azeey Feb 2, 2021
8a9e4e8
Expand documentation for ParserConfig::SetFindCallback
azeey Feb 3, 2021
53af3c7
Merge branch 'master' into parser_config
azeey Feb 3, 2021
ed20a74
Add test expecations with sdf::findFile
azeey Feb 3, 2021
b9b0b26
Handle interface models included by a model, start Reposture
azeey Feb 4, 2021
7a0c858
Merge remote-tracking branch 'origin/parser_config' into interface_api
azeey Feb 4, 2021
6eec877
Add ability to resolve to world for reposture
azeey Feb 4, 2021
2747f02
Revert error message changes
azeey Feb 4, 2021
e43b7ba
Codecheck
azeey Feb 4, 2021
8d3353f
Merge remote-tracking branch 'upstream/master' into interface_api
azeey Feb 19, 2021
44ca401
Fix codecheck
azeey Feb 19, 2021
1c0fa20
Add missing includes
azeey Feb 19, 2021
78ca98c
Add include files to CMakeLists, fix windows warning
azeey Feb 25, 2021
a699ba3
Merge remote-tracking branch 'upstream/master' into interface_api
azeey Mar 1, 2021
55a3379
Handle placement frames for Interface models
azeey Mar 1, 2021
cc995e0
Remove relative_to from InterfaceModel since its in NestedInclude
azeey Mar 2, 2021
37e1b62
Renamed loadInterfaceElements and moved it to Utils.cc
azeey Mar 3, 2021
75d839c
Fix order in which custom parsers are called
azeey Mar 3, 2021
0ab0a06
Address remaining todos, add duplicate name test
azeey Mar 3, 2021
11e48a1
Remove the possibility that an interface model can be a root model
azeey Mar 3, 2021
7fa3c16
Merge remote-tracking branch 'upstream/master' into interface_api
azeey Mar 3, 2021
d40348b
Update docs
azeey Mar 3, 2021
cbbc0e6
Update docs, simplify InterfaceModelPoseGraph
azeey Mar 3, 2021
d5d02e5
Merge remote-tracking branch 'upstream/master' into interface_api
azeey Mar 22, 2021
bbb8ef6
Change localModelName to std::optional
azeey Mar 24, 2021
0522877
Merge remote-tracking branch 'upstream/master' into interface_api
azeey Mar 24, 2021
80d3e86
Add InterfaceModelPoseGraph::ResolveNestedFramePose
azeey Mar 24, 2021
d9e6a58
Refactor reposture callback invocation, invoke recursively
azeey Mar 24, 2021
9a77c1d
Merge remote-tracking branch 'upstream/master' into interface_api
azeey Mar 24, 2021
62e6078
Add the "test" directory as an include in cppcheck
azeey Mar 24, 2021
d773f70
Minor fixes based on reviewer feedback
azeey Mar 24, 2021
a6a975f
Address reviewer feedback for interface_api test (part 1)
azeey Mar 24, 2021
154b845
Address reviewer feedback
azeey Mar 25, 2021
d832ed3
Move the toml parser into its own file
azeey Mar 25, 2021
90cafa2
Test a condition where multiple custom parsers can successfully parse…
azeey Mar 25, 2021
c0af826
Pass the entire `//include` element to custom parsers
azeey Mar 25, 2021
93f5977
Fix typos
azeey Mar 25, 2021
1676e5d
Ignore C4251 for NestedInclude
azeey Mar 25, 2021
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
6 changes: 6 additions & 0 deletions include/sdf/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ set (headers
Gui.hh
Heightmap.hh
Imu.hh
InterfaceElements.hh
InterfaceFrame.hh
InterfaceJoint.hh
InterfaceLink.hh
InterfaceModel.hh
InterfaceModelPoseGraph.hh
Joint.hh
JointAxis.hh
Lidar.hh
Expand Down
125 changes: 125 additions & 0 deletions include/sdf/InterfaceElements.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* Copyright 2021 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef SDF_INTERFACE_ELEMENTS_HH_
#define SDF_INTERFACE_ELEMENTS_HH_

#include <string>
#include <memory>

#include <ignition/math/Pose3.hh>

#include "sdf/Element.hh"
#include "sdf/InterfaceModel.hh"
#include "sdf/Types.hh"

#include "sdf/sdf_config.h"
#include "sdf/system_util.hh"

namespace sdf
{
inline namespace SDF_VERSION_NAMESPACE
{
/// \brief Contains the necessary information about an included model file
/// for custom model parsers to be able to find the file and parse it.
struct SDFORMAT_VISIBLE NestedInclude
{
/// \brief Provides the URI as specified in `//include/uri`. This may or may
/// not end with a file extension (it will not end with an extension if it
/// refers to a model package).
std::string uri;

/// \brief Provides the *resolved* absolute file path from the URI.
/// It is recommended to use this in `CustomModelParser` when checking
/// predicates on filenames -- however, the predicates should generally only
/// check the file extension.
std::string resolvedFileName;

/// \brief Name of the parent entity in absolute hierarchy.
/// Example: if the interface model's name is
/// `top_model::middle_model::my_new_model`, the absoluteParentName would be
/// `top_model::middle_model`. If the parent entity is the world, this would
/// be an empty string.
std::string absoluteParentName;

/// \brief Name relative to immediate parent as specified in
/// `//include/name`. This is nullopt if `//include/name` is not set. Then the
/// name of the model must be determined by the custom model parser from the
/// included model file.
/// Example: `my_new_model`
std::optional<std::string> localModelName;

/// \brief Whether the model is static as defined by `//include/static`. This
/// is nullopt if `//include/static` is not set.
std::optional<bool> isStatic;

/// \brief The raw pose as specified in //include/pose. This is nullopt if
/// `//include/pose` is not set.
std::optional<ignition::math::Pose3d> includeRawPose;

/// \brief The relative-to frame of the pose as specified in
/// `//include/pose/@relative_to`. This is nullopt if
/// `//include/pose/@relative_to` is not set.
std::optional<std::string> includePoseRelativeTo;

/// \brief The placement frame as specified in `//include/placement_frame`.
/// This is nullopt if `//include/placement_frame` is is not set.
std::optional<std::string> placementFrame;

/// This is the `//include` element. This can be used to pass custom elements
/// and attributes to the custom model parser.
sdf::ElementPtr includeElement;
};

/// Defines a custom model parser.
///
/// Every custom model parser should define it's own way of (quickly)
/// determining if it should parse a model. This should generally be done by
/// looking at the file extension of `include.resolvedFileName`, and
/// returning nullptr if it doesn't match a given criteria.
///
/// Custom model parsers are visited in the *reverse* of how they are defined.
/// The latest parser gains precedence.
///
/// Custom model parsers are *never* checked if resolved file extension ends
/// with `*.sdf` or `*.world`.
/// If libsdformat encounters a `*.urdf` file, it will first check custom
/// parser. If no custom parser is found, it will then convert the URDF XML to
/// SDFormat XML, and parse it as an SDFormat file.
///
/// \param[in] include The parsed //include information from which this model
/// should be parsed.
/// \param[out] errors Errors encountered during custom parsing.
/// If any errors are reported, this must return nullptr.
/// \return An optional ModelInterface.
/// * If not nullptr, the returned model interface is incorporated into the
/// existing model and its frames are exposed through the frame graph.
/// * If nullptr and no errors are reported, then libsdformat should
/// continue testing out other custom parsers registered under the same
/// extension (e.g. a parser for `.yaml`, which may cover many different
/// schemas).
///
/// If an exception is raised by this callback, libsdformat will *not* try to
/// intercept the exception.
///
/// To see an example implementation, please refer to
/// test/integration/interface_api.cc
using CustomModelParser =
std::function<sdf::InterfaceModelPtr(const sdf::NestedInclude &, Errors &)>;
}
}

#endif
65 changes: 65 additions & 0 deletions include/sdf/InterfaceFrame.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright 2021 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

#ifndef SDF_INTERFACE_FRAME_HH_
#define SDF_INTERFACE_FRAME_HH_

#include <string>

#include <ignition/math/Pose3.hh>
#include <ignition/utils/ImplPtr.hh>

#include "sdf/sdf_config.h"
#include "sdf/system_util.hh"

namespace sdf
{
inline namespace SDF_VERSION_NAMESPACE
{
/// \brief Interface element representing an explicit frame
class SDFORMAT_VISIBLE InterfaceFrame
{
/// \brief Constructor
/// \param[in] _name The *local* name.
/// \param[in] _attachedTo Name of the attached-to frame. This cannot be an
/// empty string. If the frame is attached to the model frame, this must be
/// "__model__" . The (implicit or explicit) frame must exist in the scope of
/// this frame.
/// \param[in] _pose The pose of the frame relative to the attached-to frame.
public: InterfaceFrame(const std::string &_name,
const std::string &_attachedTo, const ignition::math::Pose3d &_pose);

/// \brief Get the name of the frame.
/// \return Local name of the frame.
public: const std::string &Name() const;

/// \brief Get the name of the coordinate frame to which this frame is
/// attached.
/// \return The name of the attached-to frame.
public: const std::string &AttachedTo() const;

/// \brief Get the pose of this frame relative to the attached-to frame.
/// \return The pose of this frame in the attached-to frame.
public: const ignition::math::Pose3d &PoseInAttachedToFrame() const;

/// \brief Private data pointer.
IGN_UTILS_IMPL_PTR(dataPtr)
};
}
}

#endif
61 changes: 61 additions & 0 deletions include/sdf/InterfaceJoint.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright 2021 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

#ifndef SDF_INTERFACE_JOINT_HH_
#define SDF_INTERFACE_JOINT_HH_

#include <string>

#include <ignition/math/Pose3.hh>
#include <ignition/utils/ImplPtr.hh>

#include "sdf/sdf_config.h"
#include "sdf/system_util.hh"

namespace sdf
{
inline namespace SDF_VERSION_NAMESPACE
{
/// \brief Interface element representing a Joint
class SDFORMAT_VISIBLE InterfaceJoint
{
/// \brief Constructor
/// \param[in] name The *local* name.
/// \param[in] _childName Name of the child link or frame.
/// \param[in] _pose The pose of the joint relative to the child frame.
public: InterfaceJoint(const std::string &_name,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to include _parentName as a parameter and associated getter?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a comment in https://reviewable.io/reviews/osrf/sdformat/475#-MUP_KA_Ml7w3E1kCP9n-r7-40

Yeah, the only reason we need Joints in the Interface API is to build the frame graphs and the parent link doesn't play a role in that.

const std::string &_childName, const ignition::math::Pose3d &_pose);

/// \brief Get the name of the joint.
/// \return Local name of the joint.
public: const std::string &Name() const;

/// \brief Get the name of the joint's child.
/// \return The name of the joint's child link or frame.
public: const std::string &ChildName() const;

/// \brief Get the pose of this joint in the child frame.
/// \return The pose of this joint in the child frame.
public: const ignition::math::Pose3d &PoseInChildFrame() const;

/// \brief Private data pointer.
IGN_UTILS_IMPL_PTR(dataPtr)
};
}
}

#endif
56 changes: 56 additions & 0 deletions include/sdf/InterfaceLink.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright 2021 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

#ifndef SDF_INTERFACE_LINK_HH_
#define SDF_INTERFACE_LINK_HH_

#include <string>

#include <ignition/math/Pose3.hh>
#include <ignition/utils/ImplPtr.hh>

#include "sdf/sdf_config.h"
#include "sdf/system_util.hh"

namespace sdf
{
inline namespace SDF_VERSION_NAMESPACE
{
/// \brief Interface element representing a Link
class SDFORMAT_VISIBLE InterfaceLink
{
/// \brief Constructor
/// \param[in] name The *local* name.
/// \param[in] _pose The pose of the link relative to model frame.
public: InterfaceLink(
const std::string &_name, const ignition::math::Pose3d &_pose);

/// \brief Get the name of the link.
/// \return Local name of the link.
public: const std::string &Name() const;

/// \brief Get the pose of this link in the parent model frame.
/// \return The pose of this link in the parent model frame.
public: const ignition::math::Pose3d &PoseInModelFrame() const;

/// \brief Private data pointer.
IGN_UTILS_IMPL_PTR(dataPtr)
};
}
}

#endif
Loading