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  * along 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 <set>
26 #include <sstream>
27 #include <vector>
28 
30 
33 
34 #include <armarx/navigation/core/aron/Location.aron.generated.h>
36 
38 {
39 
40  std::string
42  {
43  if (not hasName())
44  {
45  return "anonymous";
46  }
47 
48  return aron.locationID.providerSegmentName + "/" + aron.locationID.entityName;
49  }
50 
51  bool
53  {
54  return not(aron.locationID.providerSegmentName.empty() and
55  aron.locationID.entityName.empty());
56  }
57 
58  bool
60  {
61  return _pose.has_value();
62  }
63 
66  {
67  ARMARX_CHECK(hasPose()) << "Pose for vertex `" << getName() << "` not set.";
68  return _pose.value();
69  }
70 
71  void
73  {
74  this->_pose = pose;
75  }
76 
77  Pose
79  {
80  ARMARX_CHECK(hasPose()) << "Pose for vertex '" << getName() << "' not set.";
81  ARMARX_CHECK_EMPTY(_pose->agent)
82  << "Pose for vertex '" << getName() << "' must be in the global frame. Agent is '"
83  << _pose->agent << "'.";
85  << "Pose for vertex '" << getName() << "' must be in the global frame. Frame is '"
86  << _pose->frame << "'.";
87  return Pose(_pose->toEigen());
88  }
89 
90  std::string
91  Graph::strEdge(ConstEdge edge) const
92  {
93  std::stringstream ss;
94  ss << semrel::RelationGraph<VertexAttribs, EdgeAttribs, GraphAttribs>::strEdge(edge);
95 
96  ss << " cost " << edge.attrib().cost()
97  << ", type: " << static_cast<int>(edge.attrib().strategy) << " , has traj "
98  << edge.attrib().trajectory.has_value();
99  // << ", aron: " << nlohmann::json(edge.attrib().aron);
100 
101  return ss.str();
102  }
103 } // namespace armarx::navigation::core
104 
105 namespace armarx::navigation
106 {
107 
108 
109  namespace detail
110  {
111 
112  std::vector<core::GraphPath>
113  findPathsTo(core::Graph::ConstVertex vertex,
114  const core::Graph& graph,
115  std::set<core::Graph::VertexDescriptor> visited)
116  {
117  using namespace core;
118 
119  // Stop recursion on loops.
120  if (visited.count(vertex.descriptor()) > 0)
121  {
122  return {};
123  }
124  // Mark vertex as visited for this branch.
125  visited.insert(vertex.descriptor());
126 
127  std::vector<GraphPath> paths;
128  // In any case, vertex is reachable from itself.
129  paths.push_back({vertex}); // Add [C]
130 
131  /**
132  * If not a leaf, e.g:
133  * A \
134  * C == vertex
135  * B /
136  * => [[C], [A, C], [B, C]}
137  */
138  for (const auto edge : vertex.inEdges())
139  {
140  std::vector<GraphPath> pathsToSource = findPathsTo(edge.source(), graph, visited);
141  for (auto path : pathsToSource)
142  {
143  // As we mark vertices as visited, it must not occur that we already have
144  // vertex in the path.
145  ARMARX_CHECK(std::find(path.begin(), path.end(), vertex) == path.end());
146 
147  // e.g., path = [A] => expand to [A, C]
148  path.push_back(vertex);
149  // Add to result paths
150  paths.push_back(path);
151  }
152  }
153 
154  return paths;
155  }
156  } // namespace detail
157 
158  std::vector<core::GraphPath>
159  core::findPathsTo(Graph::ConstVertex vertex, const Graph& graph)
160  {
161  std::set<Graph::VertexDescriptor> visited; // empty
162  return detail::findPathsTo(vertex, graph, visited);
163  }
164 
165  void
167  {
168  dto = {};
169  for (auto vertex : bo.vertices())
170  {
171  auto& v = dto.vertices.emplace_back(vertex.attrib().aron);
172  v.vertexID = static_cast<long>(vertex.objectID());
173  }
174  ARMARX_CHECK_EQUAL(dto.vertices.size(), bo.numVertices());
175 
176  for (auto edge : bo.edges())
177  {
178  auto& e = dto.edges.emplace_back(edge.attrib().aron);
179  e.sourceVertexID = static_cast<long>(edge.sourceObjectID());
180  e.targetVertexID = static_cast<long>(edge.targetObjectID());
181  }
182  ARMARX_CHECK_EQUAL(dto.edges.size(), bo.numEdges());
183  }
184 
185  core::Graph::ConstVertex
186  core::getVertexByName(const std::string& vertexName, const core::Graph& graph)
187  {
188  auto vertices = graph.vertices(); // begin() and end() are not const ...
189  const auto vertexIt =
190  std::find_if(vertices.begin(),
191  vertices.end(),
192  [&vertexName](const core::Graph::ConstVertex& vertex) -> bool
193  { return vertex.attrib().getName() == vertexName; });
194 
195  ARMARX_CHECK(vertexIt != vertices.end())
196  << "No vertex found with id `" << vertexName << "`";
197  return *vertexIt;
198  }
199 
200  bool
201  core::hasVertex(const std::string& vertexName, const core::Graph& graph)
202  {
203  auto vertices = graph.vertices(); // begin() and end() are not const ...
204  return std::any_of(vertices.begin(),
205  vertices.end(),
206  [&vertexName](const core::Graph::ConstVertex& vertex) -> bool
207  { return vertex.attrib().getName() == vertexName; });
208  }
209 
210  const core::Graph&
211  core::getSubgraph(const std::string& vertexName, const core::Graphs& graphs)
212  {
213  auto graphIt = std::find_if(graphs.begin(),
214  graphs.end(),
215  [&vertexName](const core::Graph& graph) -> bool
216  { return hasVertex(vertexName, graph); });
217 
218  ARMARX_CHECK(graphIt != graphs.end())
219  << "No subgraph found for vertex `" << vertexName << "`";
220  return *graphIt;
221  }
222 
223  void
225  {
226  bo = {};
227  for (const arondto::Vertex& vertex : dto.vertices)
228  {
229  auto v = bo.addVertex(semrel::ShapeID(vertex.vertexID));
230  v.attrib().aron = vertex;
231  }
232  ARMARX_CHECK_EQUAL(bo.numVertices(), dto.vertices.size());
233 
234  for (const arondto::Edge& edge : dto.edges)
235  {
236  auto e = bo.addEdge(semrel::ShapeID(edge.sourceVertexID),
237  semrel::ShapeID(edge.targetVertexID));
238  e.attrib().aron = edge;
239  }
240  ARMARX_CHECK_EQUAL(bo.numEdges(), dto.edges.size());
241  }
242 
243  void
244  core::resolveLocation(Graph::Vertex& vertex, const aron::data::DictPtr& locationData)
245  {
246  navigation::location::arondto::Location dto;
247  dto.fromAron(locationData);
248  FramedPose pose;
249  fromAron(dto.framedPose, pose);
250 
251  vertex.attrib().setPose(pose);
252  }
253 
254 
255 } // namespace armarx::navigation
armarx::navigation::core::resolveLocation
void resolveLocation(Graph::Vertex &vertex, const aron::data::DictPtr &locationData)
Definition: Graph.cpp:244
armarx::navigation::core::VertexAttribs::requireGlobal
Pose requireGlobal() const
Definition: Graph.cpp:78
armarx::navigation::core::Pose
Eigen::Isometry3f Pose
Definition: basic_types.h:31
framed.h
armarx::FramedPose
The FramedPose class.
Definition: FramedPose.h:258
armarx::navigation::core::fromAron
void fromAron(const arondto::GlobalTrajectoryPoint &dto, GlobalTrajectoryPoint &bo)
Definition: aron_conversions.cpp:25
ARMARX_CHECK_EMPTY
#define ARMARX_CHECK_EMPTY(c)
Definition: ExpressionException.h:218
armarx::navigation::core::VertexAttribs::getName
std::string getName() const
Definition: Graph.cpp:41
armarx::GlobalFrame
const std::string GlobalFrame
Definition: FramedPose.h:62
armarx::navigation::core::Graphs
std::vector< Graph > Graphs
Definition: Graph.h:104
armarx::navigation::core
This file is part of ArmarX.
Definition: aron_conversions.cpp:13
detail
Definition: OpenCVUtil.cpp:127
armarx::navigation::core::toAron
void toAron(arondto::GlobalTrajectoryPoint &dto, const GlobalTrajectoryPoint &bo)
Definition: aron_conversions.cpp:18
armarx::navigation::core::hasVertex
bool hasVertex(const std::string &vertexName, const Graph &graph)
Definition: Graph.cpp:201
armarx::navigation::core::Graph::strEdge
std::string strEdge(ConstEdge edge) const override
Get a string representation of the given vertex for usage in str().
Definition: Graph.cpp:91
armarx::navigation
This file is part of ArmarX.
Definition: aron_conversions.cpp:13
ARMARX_CHECK
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
Definition: ExpressionException.h:82
armarx::navigation::core::VertexAttribs::hasPose
bool hasPose() const
Definition: Graph.cpp:59
armarx::navigation::core::Graph
Definition: Graph.h:88
armarx::navigation::core::findPathsTo
std::vector< GraphPath > findPathsTo(Graph::ConstVertex vertex, const Graph &graph)
Definition: Graph.cpp:159
armarx::Graph
boost::subgraph< CloudGraph > Graph
Definition: Common.h:54
json_conversions.h
armarx::navigation::core::VertexAttribs::getPose
FramedPose getPose() const
Definition: Graph.cpp:65
armarx::navigation::core::VertexAttribs::hasName
bool hasName() const
Definition: Graph.cpp:52
memory_definitions.h
ExpressionException.h
armarx::aron::data::DictPtr
std::shared_ptr< Dict > DictPtr
Definition: Dict.h:41
Graph.h
armarx::ctrlutil::v
double v(double t, double v0, double a0, double j)
Definition: CtrlUtil.h:39
armarx::fromAron
void fromAron(const arondto::PackagePath &dto, PackageFileLocation &bo)
armarx::navigation::detail::findPathsTo
std::vector< core::GraphPath > findPathsTo(core::Graph::ConstVertex vertex, const core::Graph &graph, std::set< core::Graph::VertexDescriptor > visited)
Definition: Graph.cpp:113
ARMARX_CHECK_EQUAL
#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...
Definition: ExpressionException.h:130
armarx::navigation::core::VertexAttribs::aron
armarx::navigation::core::arondto::Vertex aron
Definition: Graph.h:45
armarx::navigation::core::VertexAttribs::setPose
void setPose(const FramedPose &pose)
Definition: Graph.cpp:72
armarx::aron::bo
const std::optional< BoT > & bo
Definition: aron_conversions.h:168
armarx::navigation::core::getSubgraph
const core::Graph & getSubgraph(const std::string &vertexName, const Graphs &graphs)
Definition: Graph.cpp:211
armarx::navigation::core::getVertexByName
Graph::ConstVertex getVertexByName(const std::string &vertexName, const Graph &graph)
Definition: Graph.cpp:186