Graph.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * ArmarX is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * ArmarX is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * astd::int64_t with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * @author Rainer Kartmann ( rainer dot kartmann at kit dot edu )
17 * @date 2021
18 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
19 * GNU General Public License
20 */
21
22#include "Graph.h"
23
24#include <algorithm>
25#include <cstdint>
26#include <set>
27#include <sstream>
28#include <string>
29#include <vector>
30
32
33#include <RobotAPI/libraries/armem_locations/aron/Location.aron.generated.h>
37
38#include <armarx/navigation/core/aron/Graph.aron.generated.h>
40
41#include <SemanticObjectRelations/RelationGraph/RelationGraph.h>
42#include <SemanticObjectRelations/Shapes/Shape.h>
43
45{
46
47 std::string
49 {
50 if (not hasLocationName())
51 {
52 return "anonymous";
53 }
54
55 return aron.locationID.entityName;
56
57 // return aron.locationID.providerSegmentName + "/" + aron.locationID.entityName;
58 }
59
60 std::string
62 {
63 return aron.locationID.providerSegmentName;
64
65 // return aron.locationID.providerSegmentName + "/" + aron.locationID.entityName;
66 }
67
68 bool
70 {
71 return not(aron.locationID.providerSegmentName.empty() and
72 aron.locationID.entityName.empty());
73 }
74
75 bool
77 {
78 return _pose.has_value();
79 }
80
83 {
84 ARMARX_CHECK(hasPose()) << "Pose for vertex " << QUOTED(getLocationName()) << " not set.";
85 return _pose.value();
86 }
87
88 void
90 {
91 this->_pose = pose;
92 }
93
94 Pose
96 {
97 ARMARX_CHECK(hasPose()) << "Pose for vertex " << QUOTED(getLocationName()) << " not set.";
98 ARMARX_CHECK_EMPTY(_pose->agent)
99 << "Pose for vertex " << QUOTED(getLocationName()) << " must be in the global frame. Agent is '"
100 << _pose->agent << "'.";
102 << "Pose for vertex " << QUOTED(getLocationName()) << " must be in the global frame. Frame is '"
103 << _pose->frame << "'.";
104 return Pose(_pose->toEigen());
105 }
106
107 std::string
108 Graph::strEdge(ConstEdge edge) const
109 {
110 std::stringstream ss;
111 ss << semrel::RelationGraph<VertexAttribs, EdgeAttribs, GraphAttribs>::strEdge(edge);
112
113 ss << " cost " << edge.attrib().cost()
114 << ", type: " << static_cast<int>(edge.attrib().strategy) << " , has traj "
115 << edge.attrib().trajectory.has_value();
116 // << ", aron: " << nlohmann::json(edge.attrib().aron);
117
118 return ss.str();
119 }
120
121 std::string
123 {
124 return getProviderName() + "::" + getLocationName();
125 }
126} // namespace armarx::navigation::core
127
128namespace armarx::navigation
129{
130
131
132 namespace detail
133 {
134
135 std::vector<core::GraphPath>
136 findPathsTo(core::Graph::ConstVertex vertex,
137 const core::Graph& graph,
138 std::set<core::Graph::VertexDescriptor> visited)
139 {
140 using namespace core;
141
142 // Stop recursion on loops.
143 if (visited.count(vertex.descriptor()) > 0)
144 {
145 return {};
146 }
147 // Mark vertex as visited for this branch.
148 visited.insert(vertex.descriptor());
149
150 std::vector<GraphPath> paths;
151 // In any case, vertex is reachable from itself.
152 paths.push_back({vertex}); // Add [C]
153
154 /**
155 * If not a leaf, e.g:
156 * A \
157 * C == vertex
158 * B /
159 * => [[C], [A, C], [B, C]}
160 */
161 for (const auto edge : vertex.inEdges())
162 {
163 std::vector<GraphPath> pathsToSource = findPathsTo(edge.source(), graph, visited);
164 for (auto path : pathsToSource)
165 {
166 // As we mark vertices as visited, it must not occur that we already have
167 // vertex in the path.
168 ARMARX_CHECK(std::find(path.begin(), path.end(), vertex) == path.end());
169
170 // e.g., path = [A] => expand to [A, C]
171 path.push_back(vertex);
172 // Add to result paths
173 paths.push_back(path);
174 }
175 }
176
177 return paths;
178 }
179 } // namespace detail
180
181 std::vector<core::GraphPath>
182 core::findPathsTo(Graph::ConstVertex vertex, const Graph& graph)
183 {
184 std::set<Graph::VertexDescriptor> visited; // empty
185 return detail::findPathsTo(vertex, graph, visited);
186 }
187
188 void
189 core::toAron(arondto::Graph& dto, const Graph& bo)
190 {
191 dto = {};
192 for (auto vertex : bo.vertices())
193 {
194 auto& v = dto.vertices.emplace_back(vertex.attrib().aron);
195 v.vertexID = static_cast<std::int64_t>(vertex.objectID());
196 }
197 ARMARX_CHECK_EQUAL(dto.vertices.size(), bo.numVertices());
198
199 for (auto edge : bo.edges())
200 {
201 auto& e = dto.edges.emplace_back(edge.attrib().aron);
202 e.sourceVertexID = static_cast<std::int64_t>(edge.sourceObjectID());
203 e.targetVertexID = static_cast<std::int64_t>(edge.targetObjectID());
204 }
205 ARMARX_CHECK_EQUAL(dto.edges.size(), bo.numEdges());
206 }
207
208 core::Graph::ConstVertex
209 core::getVertexByName(const std::string& vertexName, const core::Graph& graph)
210 {
211 auto vertices = graph.vertices(); // begin() and end() are not const ...
212 const auto vertexIt =
213 std::find_if(vertices.begin(),
214 vertices.end(),
215 [&vertexName](const core::Graph::ConstVertex& vertex) -> bool
216 { return vertex.attrib().getLocationName() == vertexName; });
217
218 ARMARX_CHECK(vertexIt != vertices.end())
219 << "No vertex found with id " << QUOTED(vertexName);
220 return *vertexIt;
221 }
222
223 bool
224 core::hasVertex(const std::string& vertexName, const core::Graph& graph)
225 {
226 auto vertices = graph.vertices(); // begin() and end() are not const ...
227 return std::any_of(vertices.begin(),
228 vertices.end(),
229 [&vertexName](const core::Graph::ConstVertex& vertex) -> bool
230 { return vertex.attrib().getLocationName() == vertexName; });
231 }
232
233 const core::Graph&
234 core::getSubgraph(const std::string& vertexName, const core::Graphs& graphs)
235 {
236 auto graphIt = std::find_if(graphs.begin(),
237 graphs.end(),
238 [&vertexName](const core::Graph& graph) -> bool
239 { return hasVertex(vertexName, graph); });
240
241 ARMARX_CHECK(graphIt != graphs.end())
242 << "No subgraph found for vertex " << QUOTED(vertexName);
243 return *graphIt;
244 }
245
246 void
247 core::fromAron(const arondto::Graph& dto, Graph& bo)
248 {
249 bo = {};
250 for (const arondto::Vertex& vertex : dto.vertices)
251 {
252 auto v = bo.addVertex(semrel::ShapeID(vertex.vertexID));
253 v.attrib().aron = vertex;
254 }
255 ARMARX_CHECK_EQUAL(bo.numVertices(), dto.vertices.size());
256
257 for (const arondto::Edge& edge : dto.edges)
258 {
259 auto e = bo.addEdge(semrel::ShapeID(edge.sourceVertexID),
260 semrel::ShapeID(edge.targetVertexID));
261 e.attrib().aron = edge;
262 }
263 ARMARX_CHECK_EQUAL(bo.numEdges(), dto.edges.size());
264 }
265
266 void
267 core::resolveLocation(Graph::Vertex& vertex, const aron::data::DictPtr& locationData)
268 {
269 navigation::location::arondto::Location dto;
270 dto.fromAron(locationData);
271 FramedPose pose;
272 fromAron(dto.framedPose, pose);
273
274 vertex.attrib().setPose(pose);
275 }
276
277
278} // namespace armarx::navigation
#define ARMARX_CHECK_EMPTY(c)
#define QUOTED(x)
The FramedPose class.
Definition FramedPose.h:281
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#define ARMARX_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
std::string const GlobalFrame
Variable of the global coordinate system.
Definition FramedPose.h:65
std::shared_ptr< Dict > DictPtr
Definition Dict.h:42
This file is part of ArmarX.
Graph::ConstVertex getVertexByName(const std::string &vertexName, const Graph &graph)
Definition Graph.cpp:209
std::vector< Graph > Graphs
Definition Graph.h:109
bool hasVertex(const std::string &vertexName, const Graph &graph)
Definition Graph.cpp:224
std::vector< GraphPath > findPathsTo(Graph::ConstVertex vertex, const Graph &graph)
Definition Graph.cpp:182
void resolveLocation(Graph::Vertex &vertex, const aron::data::DictPtr &locationData)
Definition Graph.cpp:267
void toAron(arondto::GlobalTrajectoryPoint &dto, const GlobalTrajectoryPoint &bo)
Eigen::Isometry3f Pose
Definition basic_types.h:31
void fromAron(const arondto::GlobalTrajectoryPoint &dto, GlobalTrajectoryPoint &bo)
const core::Graph & getSubgraph(const std::string &vertexName, const Graphs &graphs)
Definition Graph.cpp:234
std::vector< core::GraphPath > findPathsTo(core::Graph::ConstVertex vertex, const core::Graph &graph, std::set< core::Graph::VertexDescriptor > visited)
Definition Graph.cpp:136
This file is part of ArmarX.
Definition Visu.h:48
This file is part of ArmarX.
void fromAron(const arondto::PackagePath &dto, PackageFileLocation &bo)
std::string getProviderName() const
Definition Graph.cpp:61
armarx::navigation::core::arondto::Vertex aron
Definition Graph.h:46
std::string getLocationName() const
Definition Graph.cpp:48
void setPose(const FramedPose &pose)
Definition Graph.cpp:89