moveit2
The MoveIt Motion Planning Framework for ROS 2.
Loading...
Searching...
No Matches
utilities.cpp
Go to the documentation of this file.
1/*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2022, Metro Robots
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 Metro Robots 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
35/* Author: David V. Lu!! */
36
38
39namespace moveit_setup
40{
41bool extractPackageNameFromPath(const std::filesystem::path& path, std::string& package_name,
42 std::filesystem::path& relative_filepath)
43{
44 std::filesystem::path sub_path = path; // holds the directory less one folder
45 if (std::filesystem::is_regular_file(sub_path))
46 {
47 relative_filepath = sub_path.filename(); // holds the path after the sub_path
48 sub_path = sub_path.parent_path();
49 }
50 else
51 {
52 relative_filepath = sub_path;
53 }
54
55 // truncate path step by step and check if it contains a package.xml
56 // This runs until the path is either empty "" or at the root "/" or "C:\\"
57 while (!sub_path.empty() && sub_path != sub_path.root_path())
58 {
59 if (std::filesystem::is_regular_file(sub_path / "package.xml"))
60 {
61 // Search the <name> </name> string in the package.xml file
62 // This works assuming the package name is entered as <name>PACKAGE_NAME</name>
63 // Default package name to folder name
64 package_name = sub_path.filename().string();
65 tinyxml2::XMLDocument package_xml_file;
66 auto is_open = package_xml_file.LoadFile((sub_path / "package.xml").c_str());
67 if (is_open == tinyxml2::XML_SUCCESS)
68 {
69 auto name_potential =
70 package_xml_file.FirstChildElement("package")->FirstChildElement("name")->FirstChild()->ToText()->Value();
71 if (name_potential)
72 {
73 // Change package name if we have non-empty potential, else it defaults
74 package_name = name_potential;
75 }
76 }
77 return true;
78 }
79 relative_filepath = sub_path.filename() / relative_filepath;
80 sub_path = sub_path.parent_path();
81 }
82 // No package name found, we must be outside ROS
83 return false;
84}
85
86bool hasRequiredAttributes(const tinyxml2::XMLElement& e, const std::vector<XMLAttribute>& attributes)
87{
88 for (const auto& attr : attributes)
89 {
90 if (!attr.required)
91 continue; // attribute not required
92 const char* value = e.Attribute(attr.name);
93 if (value && strcmp(attr.value, value) == 0)
94 {
95 continue; // attribute has required value
96 }
97 else
98 {
99 return false;
100 }
101 }
102 return true;
103};
104
105tinyxml2::XMLElement* uniqueInsert(tinyxml2::XMLDocument& doc, tinyxml2::XMLElement& element, const char* tag,
106 const std::vector<XMLAttribute>& attributes, const char* text)
107{
108 // search for existing element with required tag name and attributes
109 tinyxml2::XMLElement* result = element.FirstChildElement(tag);
110 while (result && !hasRequiredAttributes(*result, attributes))
111 result = result->NextSiblingElement(tag);
112
113 if (!result) // if not yet present, create new element
114 {
115 result = doc.NewElement(tag);
116 element.InsertEndChild(result);
117 }
118
119 // set (not-yet existing) attributes
120 for (const auto& attr : attributes)
121 {
122 if (!result->Attribute(attr.name))
123 result->SetAttribute(attr.name, attr.value);
124 }
125
126 // insert text if required
127 if (text && !result->GetText())
128 {
129 tinyxml2::XMLText* text_el = doc.NewText(text);
130 result->InsertEndChild(text_el);
131 }
132
133 return result;
134}
135
136} // namespace moveit_setup
bool hasRequiredAttributes(const tinyxml2::XMLElement &e, const std::vector< XMLAttribute > &attributes)
Definition utilities.cpp:86
tinyxml2::XMLElement * uniqueInsert(tinyxml2::XMLDocument &doc, tinyxml2::XMLElement &element, const char *tag, const std::vector< XMLAttribute > &attributes={}, const char *text=nullptr)
Insert a new XML element with a given tag, attributes, and text.
bool extractPackageNameFromPath(const std::filesystem::path &path, std::string &package_name, std::filesystem::path &relative_filepath)
Definition utilities.cpp:41