moveit2
The MoveIt Motion Planning Framework for ROS 2.
Loading...
Searching...
No Matches
srdf_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 *********************************************************************/
38
39namespace moveit_setup
40{
42{
43 parent_node_->declare_parameter("robot_description_semantic", rclcpp::ParameterType::PARAMETER_STRING);
44 changes_ = 0L;
45}
46
47void SRDFConfig::loadPrevious(const std::filesystem::path& package_path, const YAML::Node& node)
48{
49 if (!getYamlProperty(node, "relative_path", srdf_pkg_relative_path_))
50 {
51 throw std::runtime_error("cannot find relative_path property in SRDF");
52 }
54}
55
56YAML::Node SRDFConfig::saveToYaml() const
57{
58 YAML::Node node;
59 node["relative_path"] = srdf_pkg_relative_path_.string();
60 return node;
61}
62
64{
65 if (urdf_model_ != nullptr)
66 {
67 return;
68 }
69
70 auto urdf_config = config_data_->get<URDFConfig>("urdf");
71 urdf_model_ = urdf_config->getModelPtr();
72 srdf_.robot_name_ = urdf_model_->getName();
73 parent_node_->set_parameter(rclcpp::Parameter("robot_description_semantic", srdf_.getSRDFString()));
74}
75
76void SRDFConfig::loadSRDFFile(const std::filesystem::path& package_path, const std::filesystem::path& relative_path)
77{
78 srdf_pkg_relative_path_ = relative_path;
79 loadSRDFFile(std::filesystem::path(package_path) / relative_path);
80}
81// ******************************************************************************************
82// Load SRDF File to Parameter Server
83// ******************************************************************************************
84void SRDFConfig::loadSRDFFile(const std::filesystem::path& srdf_file_path, const std::vector<std::string>& xacro_args)
85{
86 srdf_path_ = srdf_file_path;
87
89
90 std::string srdf_string;
91 if (!rdf_loader::RDFLoader::loadXmlFileToString(srdf_string, srdf_path_, xacro_args))
92 {
93 throw std::runtime_error("SRDF file not found: " + srdf_path_.string());
94 }
95
96 // Verify that file is in correct format / not an XACRO by loading into robot model
97 if (!srdf_.initString(*urdf_model_, srdf_string))
98 {
99 throw std::runtime_error("SRDF file not a valid semantic robot description model.");
100 }
101
102 // Set parameter
103 parent_node_->set_parameter(rclcpp::Parameter("robot_description_semantic", srdf_string));
104
106
107 RCLCPP_INFO_STREAM(*logger_, "Robot semantic model successfully loaded.");
108}
109
111{
112 if (!srdf_pkg_relative_path_.empty())
113 {
114 return;
115 }
116 srdf_pkg_relative_path_ = std::filesystem::path("config") / (urdf_model_->getName() + ".srdf");
117}
118
119void SRDFConfig::updateRobotModel(long changed_information)
120{
121 // Initialize with a URDF Model Interface and a SRDF Model
123 if (changed_information > 0)
124 {
125 srdf_.updateSRDFModel(*urdf_model_);
126 }
127
128 robot_model_ = std::make_shared<moveit::core::RobotModel>(urdf_model_, srdf_.srdf_model_);
129
130 if (srdf_pkg_relative_path_.empty())
131 {
132 srdf_pkg_relative_path_ = std::filesystem::path("config") / (urdf_model_->getName() + ".srdf");
133 srdf_.robot_name_ = urdf_model_->getName();
134 changes_ |= OTHER;
135 }
136 changes_ |= changed_information;
137
138 // Reset the planning scene
139 planning_scene_.reset();
140}
141
142// ******************************************************************************************
143// Provide a shared planning scene
144// ******************************************************************************************
145planning_scene::PlanningScenePtr SRDFConfig::getPlanningScene()
146{
147 if (!planning_scene_)
148 {
149 // make sure kinematic model exists
151
152 // Allocate an empty planning scene
153 planning_scene_ = std::make_shared<planning_scene::PlanningScene>(robot_model_);
154 }
155 return planning_scene_;
156}
157
158std::vector<std::string> SRDFConfig::getLinkNames() const
159{
160 std::vector<std::string> names;
161 for (const moveit::core::LinkModel* link_model : robot_model_->getLinkModels())
162 {
163 names.push_back(link_model->getName());
164 }
165 return names;
166}
167
168std::string SRDFConfig::getChildOfJoint(const std::string& joint_name) const
169{
170 const moveit::core::JointModel* joint_model = getRobotModel()->getJointModel(joint_name);
171 // Check that a joint model was found
172 if (!joint_model)
173 {
174 return "";
175 }
176 return joint_model->getChildLinkModel()->getName();
177}
178
179void SRDFConfig::removePoseByName(const std::string& pose_name, const std::string& group_name)
180{
181 for (std::vector<srdf::Model::GroupState>::iterator pose_it = srdf_.group_states_.begin();
182 pose_it != srdf_.group_states_.end(); ++pose_it)
183 {
184 if (pose_it->name_ == pose_name && pose_it->group_ == group_name)
185 {
186 srdf_.group_states_.erase(pose_it);
188 return;
189 }
190 }
191}
192
193std::vector<std::string> SRDFConfig::getJointNames(const std::string& group_name, bool include_multi_dof,
194 bool include_passive)
195{
196 std::vector<std::string> names;
197 const moveit::core::JointModelGroup* joint_model_group = robot_model_->getJointModelGroup(group_name);
198
199 // Iterate through the joints
200 for (const moveit::core::JointModel* joint : joint_model_group->getActiveJointModels())
201 {
202 if (!include_multi_dof && joint->getVariableCount() > 1)
203 {
204 continue;
205 }
206 else if (!include_passive && joint->isPassive())
207 {
208 continue;
209 }
210 names.push_back(joint->getName());
211 }
212 return names;
213}
214
215void SRDFConfig::collectVariables(std::vector<TemplateVariable>& variables)
216{
217 variables.push_back(TemplateVariable("ROBOT_NAME", srdf_.robot_name_));
218 variables.push_back(TemplateVariable("ROBOT_ROOT_LINK", robot_model_->getRootLinkName()));
219 variables.push_back(TemplateVariable("PLANNING_FRAME", robot_model_->getModelFrame()));
220}
221
229{
231 {
232 return jm1->getName() < jm2->getName();
233 }
234};
235
237{
238 emitter << YAML::Comment("joint_limits.yaml allows the dynamics properties specified in the URDF "
239 "to be overwritten or augmented as needed");
240 emitter << YAML::Newline;
241
242 emitter << YAML::BeginMap;
243
244 emitter << YAML::Comment("For beginners, we downscale velocity and acceleration limits.") << YAML::Newline;
245 emitter << YAML::Comment("You can always specify higher scaling factors (<= 1.0) in your motion requests.");
246 emitter << YAML::Comment("Increase the values below to 1.0 to always move at maximum speed.");
247 emitter << YAML::Key << "default_velocity_scaling_factor";
248 emitter << YAML::Value << "0.1";
249
250 emitter << YAML::Key << "default_acceleration_scaling_factor";
251 emitter << YAML::Value << "0.1";
252
253 emitter << YAML::Newline << YAML::Newline;
254 emitter << YAML::Comment("Specific joint properties can be changed with the keys "
255 "[max_position, min_position, max_velocity, max_acceleration]")
256 << YAML::Newline;
257 emitter << YAML::Comment("Joint limits can be turned off with [has_velocity_limits, has_acceleration_limits]");
258
259 emitter << YAML::Key << "joint_limits";
260 emitter << YAML::Value << YAML::BeginMap;
261
262 // Union all the joints in groups. Uses a custom comparator to allow the joints to be sorted by name
263 std::set<const moveit::core::JointModel*, JointModelCompare> joints;
264
265 // Loop through groups
266 for (srdf::Model::Group& group : parent_.srdf_.groups_)
267 {
268 // Get list of associated joints
269 const moveit::core::JointModelGroup* joint_model_group = parent_.getRobotModel()->getJointModelGroup(group.name_);
270
271 const std::vector<const moveit::core::JointModel*>& joint_models = joint_model_group->getJointModels();
272
273 // Iterate through the joints
274 for (const moveit::core::JointModel* joint_model : joint_models)
275 {
276 // Check that this joint only represents 1 variable.
277 if (joint_model->getVariableCount() == 1)
278 joints.insert(joint_model);
279 }
280 }
281
282 // Add joints to yaml file, if no more than 1 dof
283 for (const moveit::core::JointModel* joint : joints)
284 {
285 emitter << YAML::Key << joint->getName();
286 emitter << YAML::Value << YAML::BeginMap;
287
288 const moveit::core::VariableBounds& b = joint->getVariableBounds()[0];
289
290 // Output property
291 emitter << YAML::Key << "has_velocity_limits";
292 if (b.velocity_bounded_)
293 {
294 emitter << YAML::Value << "true";
295 }
296 else
297 {
298 emitter << YAML::Value << "false";
299 }
300
301 // Output property
302 emitter << YAML::Key << "max_velocity";
303 emitter << YAML::Value << static_cast<double>(std::min(fabs(b.max_velocity_), fabs(b.min_velocity_)));
304
305 // Output property
306 emitter << YAML::Key << "has_acceleration_limits";
308 {
309 emitter << YAML::Value << "true";
310 }
311 else
312 {
313 emitter << YAML::Value << "false";
314 }
315
316 // Output property
317 emitter << YAML::Key << "max_acceleration";
318 emitter << YAML::Value << static_cast<double>(std::min(fabs(b.max_acceleration_), fabs(b.min_acceleration_)));
319
320 emitter << YAML::EndMap;
321 }
322
323 emitter << YAML::EndMap;
324 return true; // file created successfully
325}
326
327} // namespace moveit_setup
328
329#include <pluginlib/class_list_macros.hpp> // NOLINT
PLUGINLIB_EXPORT_CLASS(cached_ik_kinematics_plugin::CachedIKKinematicsPlugin< kdl_kinematics_plugin::KDLKinematicsPlugin >, kinematics::KinematicsBase)
const std::vector< const JointModel * > & getActiveJointModels() const
Get the active joints in this group (that have controllable DOF). This does not include mimic joints.
const std::vector< const JointModel * > & getJointModels() const
Get all the joints in this group (including fixed and mimic joints).
A joint from the robot. Models the transform that this joint applies in the kinematic chain....
const LinkModel * getChildLinkModel() const
Get the link that this joint connects to. There will always be such a link.
const std::string & getName() const
Get the name of the joint.
A link from the robot. Contains the constant transform applied to the link and its geometry.
Definition link_model.h:72
const std::string & getName() const
The name of this link.
Definition link_model.h:86
bool writeYaml(YAML::Emitter &emitter) override
void updateRobotModel(long changed_information=0L)
srdf::SRDFWriter srdf_
SRDF Data and Writer.
planning_scene::PlanningScenePtr planning_scene_
Shared planning scene.
void removePoseByName(const std::string &pose_name, const std::string &group_name)
std::shared_ptr< urdf::Model > urdf_model_
planning_scene::PlanningScenePtr getPlanningScene()
Provide a shared planning scene.
std::filesystem::path srdf_pkg_relative_path_
Path relative to loaded configuration package.
std::string getChildOfJoint(const std::string &joint_name) const
Return the name of the child link of a joint.
moveit::core::RobotModelPtr getRobotModel() const
moveit::core::RobotModelPtr robot_model_
std::vector< std::string > getJointNames(const std::string &group_name, bool include_multi_dof=true, bool include_passive=true)
std::filesystem::path srdf_path_
Full file-system path to srdf.
void loadSRDFFile(const std::filesystem::path &package_path, const std::filesystem::path &relative_path)
Load SRDF File.
YAML::Node saveToYaml() const override
Optionally save "meta" information for saving in the .setup_assistant yaml file.
void onInit() override
Overridable initialization method.
std::vector< std::string > getLinkNames() const
void collectVariables(std::vector< TemplateVariable > &variables) override
Collect key/value pairs for use in templates.
void loadPrevious(const std::filesystem::path &package_path, const YAML::Node &node) override
Loads the configuration from an existing MoveIt configuration.
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< DataWarehouse > config_data_
Definition config.hpp:161
std::shared_ptr< rclcpp::Logger > logger_
Definition config.hpp:164
const std::shared_ptr< urdf::Model > & getModelPtr() const
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...
bool getYamlProperty(const YAML::Node &node, const std::string &key, T &storage, const T &default_value=T())
Custom std::set comparator, used for sorting the joint_limits.yaml file into alphabetical order.
bool operator()(const moveit::core::JointModel *jm1, const moveit::core::JointModel *jm2) const
Simple Key/value pair for templates.
Definition templates.hpp:47