296 const ::std::string& idTo,
297 const ::Ice::Current&)
305 std::stringstream s{};
306 s <<
"aStar: Node from: No node with ID: " << idFrom;
308 throw memoryx::EntityNotFoundException{s.str()};
313 std::stringstream s{};
315 s <<
"aStar: Node to: No node with ID: " << idTo;
316 throw memoryx::EntityNotFoundException{s.str()};
319 ARMARX_VERBOSE_S <<
"memoryx::GraphMemorySegment::aStar from " << start->getPose()->frame
320 <<
" to " << goal->getPose()->frame;
323 if (start->getScene() != goal->getScene())
325 std::stringstream s{};
327 s <<
"aStar: Nodes from and to belong to different scenes: " << start->getScene() <<
" | "
329 throw armarx::InvalidArgumentException{s.str()};
334 std::unordered_map<std::string, memoryx::GraphNodeBasePtr> nodes{};
338 nodes[node->getId()] = node;
342 nodes[start->getId()] = start;
343 nodes[goal->getId()] = goal;
347 auto dist = [](memoryx::GraphNodeBasePtr n1, memoryx::GraphNodeBasePtr n2)
349 auto p1 = n1->getPose();
350 auto p2 = n2->getPose();
351 const float dX = p1->position->x - p2->position->x;
352 const float dY = p1->position->y - p2->position->y;
353 return std::sqrt(dX * dX + dY * dY);
356 memoryx::GraphNodeBaseList path{};
357 memoryx::GraphNodeBaseList closedSet{};
358 memoryx::GraphNodeBaseList openSet{};
359 openSet.push_back(start);
361 std::unordered_map<std::string, float> gScore;
362 gScore[start->getId()] = 0.f;
363 std::unordered_map<std::string, float> fScore;
364 fScore[start->getId()] = gScore.at(start->getId()) + dist(start, goal);
365 std::unordered_map<std::string, memoryx::GraphNodeBasePtr> cameFrom;
366 cameFrom[goal->getId()] = start;
368 ARMARX_VERBOSE_S <<
"memoryx::GraphMemorySegment::aStar from " << idFrom <<
" to " << idTo
369 <<
". Start path search.";
371 while (!openSet.empty())
374 auto currentIT = std::min_element(
377 [&fScore](
const memoryx::GraphNodeBasePtr& a,
const memoryx::GraphNodeBasePtr& b)
378 { return fScore.at(a->getId()) < fScore.at(b->getId()); });
379 assert(currentIT != openSet.end());
380 memoryx::GraphNodeBasePtr current = *currentIT;
384 if (current->getId() == goal->getId())
386 auto cameFromNode = goal;
388 while (cameFromNode->getId() != start->getId())
390 path.insert(path.begin(), cameFromNode);
391 cameFromNode = cameFrom.at(cameFromNode->getId());
394 path.insert(path.begin(), start);
398 openSet.erase(currentIT);
399 closedSet.push_back(current);
402 for (
int i = 0; i < current->getOutdegree(); i++)
404 auto neighbor = nodes.at(current->getAdjacentNode(i)->getEntity()->getId());
408 if (std::find(closedSet.begin(), closedSet.end(), neighbor) != closedSet.end())
413 float tentativeGScore = gScore.at(current->getId()) + dist(current, neighbor);
414 bool notInOS = std::find(openSet.begin(), openSet.end(), neighbor) == openSet.end();
416 if (notInOS || tentativeGScore < gScore.at(neighbor->getId()))
418 cameFrom[neighbor->getId()] = current;
419 gScore[neighbor->getId()] = tentativeGScore;
420 fScore[neighbor->getId()] = tentativeGScore + dist(neighbor, goal);
424 openSet.push_back(neighbor);
430 ARMARX_VERBOSE_S <<
"memoryx::GraphMemorySegment::aStar from " << idFrom <<
" to " << idTo