28 #include <unordered_set>
29 #include <unordered_map>
35 GraphMemorySegmentBase()
45 std::unordered_set<std::string>
names {};
46 const auto ids = getAllEntityIds(
c);
48 for (
const auto&
id : ids)
50 auto elem = getNodeById(
id,
c);
54 names.insert(elem->getScene());
58 return Ice::StringSeq {
names.begin(),
names.end()};
63 memoryx::GraphNodeBaseList result {};
66 for (
auto& elem : filtered)
68 auto ptr = memoryx::GraphNodeBasePtr::dynamicCast(elem);
72 result.push_back(ptr);
81 return memoryx::GraphNodeBasePtr::dynamicCast(getEntityById(entityId,
c));
86 return memoryx::GraphNodeBasePtr::dynamicCast(getEntityById(entityId,
c));
91 return memoryx::GraphNodeBasePtr::dynamicCast(getEntityByName(entityName,
c));
96 memoryx::GraphNodeBaseList nodes {};
97 const auto ids = getAllEntityIds(
c);
99 for (
const auto&
id : ids)
101 auto elem = getNodeById(
id,
c);
105 nodes.push_back(elem);
114 ARMARX_INFO_S <<
"GraphMemorySegment: clearing scene " << sceneName <<
"...";
117 for (
auto& elem : filtered)
119 removeEntity(elem->getId(
c));
122 ARMARX_INFO_S <<
"GraphMemorySegment: clearing scene " << sceneName <<
". Removed " << filtered.size() <<
" elements";
127 GraphNodeBasePtr node = getNodeById(nodeId);
128 auto allnodes = getAllNodes();
129 for (
auto& curNode : allnodes)
131 if (curNode->removeAdjacentNode(nodeId))
133 updateEntity(curNode->getId(), curNode);
138 removeEntity(nodeId);
146 GraphNodeBasePtr startNode = getNodeById(startNodeId);
149 if (startNode->removeAdjacentNode(endNodeId))
151 updateEntity(startNodeId, startNode);
160 ARMARX_INFO_S <<
"GraphMemorySegment adding node " << (node ? node->getName() :
"NULL node");
161 return addEntity(node,
c);
166 ARMARX_INFO_S <<
"GraphMemorySegment adding edge " << fromId <<
" -> " << toId <<
"...";
167 auto fromNode = getNodeById(fromId,
c);
171 ARMARX_ERROR_S <<
"GraphMemorySegment addEdge: Id " << fromId <<
" does not reference a node";
175 auto toNode = getNodeById(toId,
c);
179 ARMARX_ERROR_S <<
"GraphMemorySegment addEdge: Id " << toId <<
" does not reference a node";
184 fromNode->addAdjacentNode(getEntityRefById(toId,
c),
c);
186 updateEntity(fromId, fromNode,
c);
187 ARMARX_INFO_S <<
"GraphMemorySegment adding edge " << fromId <<
" -> " << toId <<
"done!";
198 auto nodes = getNodesByScene(sceneName);
200 for (
const auto& node : nodes)
202 if (node->getName() == nodeName)
213 auto nodes = getNodesByScene(sceneName);
215 for (
const auto& node : nodes)
217 if (node->getName() == nodeName)
223 return memoryx::GraphNodeBasePtr {};
270 auto start = getNodeById(idFrom);
271 auto goal = getNodeById(idTo);
275 std::stringstream
s {};
276 s <<
"aStar: Node from: No node with ID: " << idFrom;
278 throw memoryx::EntityNotFoundException {
s.str()};
283 std::stringstream
s {};
285 s <<
"aStar: Node to: No node with ID: " << idTo;
286 throw memoryx::EntityNotFoundException {
s.str()};
289 ARMARX_VERBOSE_S <<
"memoryx::GraphMemorySegment::aStar from " << start->getPose()->frame <<
" to " << goal->getPose()->frame;
292 if (start->getScene() != goal->getScene())
294 std::stringstream
s {};
296 s <<
"aStar: Nodes from and to belong to different scenes: " << start->getScene() <<
" | " << goal->getScene();
297 throw armarx::InvalidArgumentException {
s.str()};
302 std::unordered_map<std::string, memoryx::GraphNodeBasePtr> nodes {};
304 for (
const auto& node : getNodesByScene(start->getScene()))
306 nodes[node->getId()] = node;
310 nodes[start->getId()] = start;
311 nodes[goal->getId()] = goal;
315 auto dist = [](memoryx::GraphNodeBasePtr n1, memoryx::GraphNodeBasePtr n2)
317 auto p1 = n1->getPose();
318 auto p2 = n2->getPose();
319 const float dX = p1->position->x - p2->position->x;
320 const float dY = p1->position->y - p2->position->y;
324 memoryx::GraphNodeBaseList path {};
325 memoryx::GraphNodeBaseList closedSet {};
326 memoryx::GraphNodeBaseList openSet {};
327 openSet.push_back(start);
329 std::unordered_map<std::string, float> gScore;
330 gScore[start->getId()] = 0.f;
331 std::unordered_map<std::string, float> fScore;
332 fScore[start->getId()] = gScore.at(start->getId()) + dist(start, goal);
333 std::unordered_map<std::string, memoryx::GraphNodeBasePtr> cameFrom;
334 cameFrom[goal->getId()] = start;
336 ARMARX_VERBOSE_S <<
"memoryx::GraphMemorySegment::aStar from " << idFrom <<
" to " << idTo <<
". Start path search.";
338 while (!openSet.empty())
342 std::min_element(openSet.begin(), openSet.end(),
343 [&fScore](
const memoryx::GraphNodeBasePtr &
a,
const memoryx::GraphNodeBasePtr & b)
345 return fScore.at(a->getId()) < fScore.at(b->getId());
348 assert(currentIT != openSet.end());
349 memoryx::GraphNodeBasePtr current = *currentIT;
353 if (current->getId() == goal->getId())
355 auto cameFromNode = goal;
357 while (cameFromNode->getId() != start->getId())
359 path.insert(path.begin(), cameFromNode);
360 cameFromNode = cameFrom.at(cameFromNode->getId());
363 path.insert(path.begin(), start);
367 openSet.erase(currentIT);
368 closedSet.push_back(current);
371 for (
int i = 0; i < current->getOutdegree(); i++)
373 auto neighbor = nodes.at(current->getAdjacentNode(i)->getEntity()->getId());
377 if (std::find(closedSet.begin(), closedSet.end(), neighbor) != closedSet.end())
382 float tentativeGScore = gScore.at(current->getId()) + dist(current, neighbor);
383 bool notInOS = std::find(openSet.begin(), openSet.end(), neighbor) == openSet.end();
385 if (notInOS || tentativeGScore < gScore.at(neighbor->getId()))
387 cameFrom[neighbor->getId()] = current;
388 gScore[neighbor->getId()] = tentativeGScore;
389 fScore[neighbor->getId()] = tentativeGScore + dist(neighbor, goal);
393 openSet.push_back(neighbor);
399 ARMARX_VERBOSE_S <<
"memoryx::GraphMemorySegment::aStar from " << idFrom <<
" to " << idTo <<
". Done!";