moveit2
The MoveIt Motion Planning Framework for ROS 2.
Loading...
Searching...
No Matches
urdf_config.cpp
Go to the documentation of this file.
1/*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2021, PickNik Robotics, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 * * Neither the name of PickNik Robotics nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *********************************************************************/
34
38#include <fmt/format.h>
39#include <fmt/ranges.h>
40
41namespace moveit_setup
42{
44{
45 parent_node_->declare_parameter("robot_description", rclcpp::ParameterType::PARAMETER_STRING);
46}
47
48void URDFConfig::loadPrevious(const std::filesystem::path& /*config_package_path*/, const YAML::Node& node)
49{
50 if (!getYamlProperty(node, "package", urdf_pkg_name_))
51 {
52 throw std::runtime_error("cannot find package property in URDF");
53 }
54
55 if (!getYamlProperty(node, "relative_path", urdf_pkg_relative_path_))
56 {
57 throw std::runtime_error("cannot find relative_path property in URDF");
58 }
59
60 getYamlProperty(node, "xacro_args", xacro_args_);
62}
63
64YAML::Node URDFConfig::saveToYaml() const
65{
66 YAML::Node node;
67 node["package"] = urdf_pkg_name_;
68 node["relative_path"] = urdf_pkg_relative_path_.string();
69 if (!xacro_args_.empty())
70 {
71 node["xacro_args"] = xacro_args_;
72 }
73 return node;
74}
75
76void URDFConfig::loadFromPath(const std::filesystem::path& urdf_file_path, const std::string& xacro_args)
77{
78 urdf_path_ = urdf_file_path;
79 xacro_args_ = xacro_args;
82 load();
83}
84
85void URDFConfig::loadFromPath(const std::filesystem::path& urdf_file_path, const std::vector<std::string>& xacro_args)
86{
87 urdf_path_ = urdf_file_path;
88 xacro_args_vec_ = xacro_args;
89 xacro_args_ = fmt::format("{}", fmt::join(xacro_args_vec_, " "));
91 load();
92}
93
95{
96 // Reset to defaults: no package name, relative path is set to absolute path
97 urdf_pkg_name_ = "";
99
100 std::string pkg_name;
101 std::filesystem::path relative_path;
102 if (extractPackageNameFromPath(urdf_path_, pkg_name, relative_path))
103 {
104 // Check that ROS can find the package, update members accordingly
105 const std::filesystem::path robot_desc_pkg_path = getSharePath(pkg_name);
106 if (!robot_desc_pkg_path.empty())
107 {
108 urdf_pkg_name_ = pkg_name;
109 urdf_pkg_relative_path_ = relative_path;
110 }
111 else
112 {
113 RCLCPP_WARN(*logger_,
114 "Found package name '%s' but failed to resolve ROS package path."
115 "Attempting to load the URDF from absolute path, instead.",
116 pkg_name.c_str());
117 }
118 }
119}
120
121void URDFConfig::loadFromPackage(const std::filesystem::path& package_name, const std::filesystem::path& relative_path,
122 const std::string& xacro_args)
123{
124 const std::filesystem::path package_path = getSharePath(package_name.string());
125 if (package_path.empty())
126 {
127 throw std::runtime_error("URDF/COLLADA package not found: ''" + package_name.string());
128 }
129
130 urdf_pkg_name_ = package_name.string();
131 urdf_pkg_relative_path_ = relative_path;
132 xacro_args_ = xacro_args;
133
134 urdf_path_ = package_path / relative_path;
135 load();
136}
137
139{
140 RCLCPP_DEBUG_STREAM(*logger_, "URDF Package Name: " << urdf_pkg_name_);
141 RCLCPP_DEBUG_STREAM(*logger_, "URDF Package Path: " << urdf_pkg_relative_path_);
142
144 {
145 throw std::runtime_error("URDF/COLLADA file not found: " + urdf_path_.string());
146 }
147
149 {
150 throw std::runtime_error("Running xacro failed.\nPlease check console for errors.");
151 }
152
153 // Verify that file is in correct format / not an XACRO by loading into robot model
154 if (!urdf_model_->initString(urdf_string_))
155 {
156 throw std::runtime_error("URDF/COLLADA file is not a valid robot model.");
157 }
159
160 // Set parameter
161 parent_node_->set_parameter(rclcpp::Parameter("robot_description", urdf_string_));
162
163 RCLCPP_INFO_STREAM(*logger_, "Loaded " << urdf_model_->getName() << " robot model.");
164}
165
167{
169}
170
172{
173 return urdf_model_->getRoot() != nullptr;
174}
175
176void URDFConfig::collectDependencies(std::set<std::string>& packages) const
177{
178 packages.insert(urdf_pkg_name_);
179}
180
181void URDFConfig::collectVariables(std::vector<TemplateVariable>& variables)
182{
183 std::string urdf_location;
184 if (urdf_pkg_name_.empty())
185 {
186 urdf_location = urdf_path_.string();
187 }
188 else
189 {
190 urdf_location = "$(find " + urdf_pkg_name_ + ")/" + urdf_pkg_relative_path_.string();
191 }
192
193 variables.push_back(TemplateVariable("URDF_LOCATION", urdf_location));
194
196 {
197 variables.push_back(
198 TemplateVariable("URDF_LOAD_ATTRIBUTE", "command=\"xacro " + xacro_args_ + " '" + urdf_location + "'\""));
199 }
200 else
201 {
202 variables.push_back(TemplateVariable("URDF_LOAD_ATTRIBUTE", "textfile=\"" + urdf_location + "\""));
203 }
204}
205} // namespace moveit_setup
206
207#include <pluginlib/class_list_macros.hpp> // NOLINT
PLUGINLIB_EXPORT_CLASS(cached_ik_kinematics_plugin::CachedIKKinematicsPlugin< kdl_kinematics_plugin::KDLKinematicsPlugin >, kinematics::KinematicsBase)
where all the data for each part of the configuration is stored.
Definition config.hpp:58
rclcpp::Node::SharedPtr parent_node_
Definition config.hpp:162
std::shared_ptr< rclcpp::Logger > logger_
Definition config.hpp:164
void collectDependencies(std::set< std::string > &packages) const override
Collect the package dependencies generated by this configuration.
std::filesystem::path urdf_path_
Full file-system path to urdf.
void loadFromPath(const std::filesystem::path &urdf_file_path, const std::string &xacro_args="")
Load URDF File.
std::filesystem::path urdf_pkg_relative_path_
Path relative to urdf package (note: this may be same as urdf_path_).
YAML::Node saveToYaml() const override
Optionally save "meta" information for saving in the .setup_assistant yaml file.
bool isConfigured() const override
Return true if this part of the configuration is completely set up.
void loadFromPackage(const std::filesystem::path &package_name, const std::filesystem::path &relative_path, const std::string &xacro_args="")
std::vector< std::string > xacro_args_vec_
bool urdf_from_xacro_
Flag indicating whether the URDF was loaded from .xacro format.
std::shared_ptr< urdf::Model > urdf_model_
URDF robot model.
void onInit() override
Overridable initialization method.
void loadPrevious(const std::filesystem::path &package_path, const YAML::Node &node) override
Loads the configuration from an existing MoveIt configuration.
std::string xacro_args_
xacro arguments in two different formats
void collectVariables(std::vector< TemplateVariable > &variables) override
Collect key/value pairs for use in templates.
std::string urdf_string_
URDF robot model string.
std::string urdf_pkg_name_
Name of package containing urdf (note: this may be empty b/c user may not have urdf in pkg).
static bool loadXmlFileToString(std::string &buffer, const std::string &path, const std::vector< std::string > &xacro_args)
helper that branches between loadFileToString() and loadXacroFileToString() based on result of isXacr...
static bool isXacroFile(const std::string &path)
determine if given path points to a xacro file
bool getYamlProperty(const YAML::Node &node, const std::string &key, T &storage, const T &default_value=T())
std::filesystem::path getSharePath(const std::string &package_name)
Return a path for the given package's share folder.
Definition utilities.hpp:70
bool extractPackageNameFromPath(const std::filesystem::path &path, std::string &package_name, std::filesystem::path &relative_filepath)
Definition utilities.cpp:41
Simple Key/value pair for templates.
Definition templates.hpp:47