50 #include <armarx/navigation/algorithms/aron/Costmap.aron.generated.h>
52 #include <armarx/navigation/core/aron/Graph.aron.generated.h>
53 #include <armarx/navigation/core/aron/Location.aron.generated.h>
54 #include <armarx/navigation/core/aron/Trajectory.aron.generated.h>
55 #include <armarx/navigation/core/aron/Twist.aron.generated.h>
57 #include <armarx/navigation/human/aron/Human.aron.generated.h>
59 #include <armarx/navigation/memory/aron/LaserScannerFeatures.aron.generated.h>
61 #include <armarx/navigation/rooms/aron/Room.aron.generated.h>
87 def->optional(properties.snapshotToLoad,
89 "Snapshot to load at start up \n"
90 "(e.g. 'R003' to load 'PriorKnowledgeData/navigation-graphs/R003').");
92 def->optional(properties.packageToLoad,
94 "Package to load snapshot at start up \n"
95 "(e.g. 'PriorKnowledgeData').");
97 def->optional(properties.locationGraph.visuLocations,
98 "p.locationGraph.visuLocation",
99 "Enable visualization of locations.");
102 properties.locationGraph.visuRelativeLocations,
103 "p.locationGraph.visuRelativeLocation",
104 "Enable visualization of relative locations (currently supported: robots, objects).");
106 def->optional(properties.locationGraph.visuGraphEdges,
107 "p.locationGraph.visuGraphEdges",
108 "Enable visualization of navigation graph edges.");
111 properties.visuCostmaps,
"p.visuCostmaps",
"Enable visualization of costmaps.");
112 def->optional(properties.zOffsetCostmap,
114 "Adjust the height of the visualized costmap.");
116 def->optional(properties.visuHumans,
"p.visuHumans",
"Enable visualization of humans.");
118 def->optional(properties.visuTransparent,
120 "Enable visualization of humans a bit transparent.");
122 def->optional(properties.visuHumanMaxAgeMs,
123 "p.visuHumanMaxAgeMs",
124 "The maximum age of humans to be drawn in ms.");
126 def->optional(properties.visuRooms,
"p.visuRooms",
"Enable visualization of rooms.");
128 def->optional(properties.visuFrequency,
130 "Visualization frequeny of locations and graph edges [Hz].");
153 algorithms::arondto::Costmap::ToAronType());
156 navigation::core::arondto::GlobalTrajectory::ToAronType());
158 navigation::core::arondto::LocalTrajectory::ToAronType());
170 navigation::location::arondto::Location::ToAronType());
172 navigation::core::arondto::Graph::ToAronType());
175 navigation::human::arondto::Human::ToAronType());
179 navigation::memory::arondto::LaserScannerFeatures::ToAronType())
180 .setMaxHistorySize(properties.laserScannerFeaturesMaxHistorySize);
185 navigation::rooms::arondto::Room::ToAronType());
194 if (properties.locationGraph.visuRelativeLocations)
206 tasks.visuTask->start();
228 return "navigation_memory";
237 tab.locationGraph.setup(*
this);
247 tab.locationGraph.update(*
this);
257 reloadSnapshot =
Button();
258 reloadSnapshot.setLabel(
"Reload from Snapshot '" + owner.properties.snapshotToLoad +
261 visuLocations.setValue(owner.properties.locationGraph.visuLocations);
262 visuGraphEdges.setValue(owner.properties.locationGraph.visuLocations);
264 grid.
add(reloadSnapshot, {row, 0}, {1, 2});
267 grid.
add(
Label(
"Visualize Locations"), {row, 0}).add(visuLocations, {row, 1});
270 grid.
add(
Label(
"Visualize Graph Edges"), {row, 0}).add(visuGraphEdges, {row, 1});
281 if (reloadSnapshot.wasClicked())
283 owner.loadSnapshot();
285 if (visuLocations.hasValueChanged() or visuGraphEdges.hasValueChanged())
287 std::scoped_lock lock(owner.propertiesMutex);
288 owner.properties.locationGraph.visuLocations = visuLocations.getValue();
289 owner.properties.locationGraph.visuGraphEdges = visuGraphEdges.getValue();
306 std::scoped_lock lock(propertiesMutex);
307 pp = properties.locationGraph;
312 while (tasks.visuTask and not tasks.visuTask->isStopped())
317 std::scoped_lock lock(propertiesMutex);
318 pp = properties.locationGraph;
321 std::vector<viz::Layer> layers;
325 if (properties.locationGraph.visuRelativeLocations)
335 if (properties.locationGraph.visuRelativeLocations)
345 visu.drawCostmaps(layers, p.visuCostmaps, p.zOffsetCostmap);
348 visu.drawHumans(layers,
353 visu.drawRooms(layers, p.visuRooms);
357 metronome.waitForNextTick();
362 Component::loadSnapshot()
364 if (properties.snapshotToLoad.empty())
367 <<
"Not loading any predefined locations or graphs as the params was empty ...";
371 ARMARX_INFO <<
"Loading snapshots from snapshot '" << properties.snapshotToLoad
372 <<
"' in package '" << properties.packageToLoad <<
"' ...";
375 properties.packageToLoad,
378 if (
auto graph = f.find(properties.snapshotToLoad); graph.has_value())
380 const std::string graphId = graph->getID();
381 ARMARX_DEBUG <<
"Found graph " << graphId <<
" with path: " << graph->getFullPath();
389 std::filesystem::path locationsFilePath = graph->getFullPath() /
"locations.json";
390 if (not std::filesystem::is_regular_file(locationsFilePath))
392 ARMARX_WARNING <<
"Found no locations file for graph '" << graphId <<
"'.";
406 std::ifstream ifs(locationsFilePath);
407 const std::string content((std::istreambuf_iterator<char>(ifs)),
408 (std::istreambuf_iterator<char>()));
411 nlohmann::json js = nlohmann::json::parse(content);
416 for (
const auto& location : locations)
419 if (location->type !=
423 <<
"Navigation memory received location '" + location->id.name +
424 "' which is not of type "
425 "'armarx::priorknowledge::util::LocationType:"
426 ":FRAMED_LOCATION' (e.g. you specified a "
427 "FRAMED_BOXED_LOCATION?). Only FramedLocations (i.e. "
428 "poses in 3D space) are navigatable. Ignoring this location "
429 "but please check the location.json file.";
433 auto& framedLocation =
436 navigation::location::arondto::Location loc;
439 loc.framedPose.header.
frame = framedLocation.frame;
440 loc.framedPose.header.agent = framedLocation.agent;
441 loc.framedPose.pose = framedLocation.pose;
442 toAron(loc.names, framedLocation.names);
447 up.referencedTime = now;
449 up.arrivedTime = now;
451 up.instancesData = {loc.toAron()};
463 std::filesystem::path graphFilesPath = graph->getFullPath() /
"Graph";
465 if (not std::filesystem::is_directory(graphFilesPath))
467 ARMARX_INFO <<
"Found no `Graph/` folder for graph '" << graphId <<
"'.";
481 up.referencedTime = now;
482 up.arrivedTime = now;
484 up.entityID = providerID.
withEntityName(properties.snapshotToLoad);
485 up.instancesData = {g.toAron()};
487 ARMARX_DEBUG <<
"Sending empty graph `" << properties.snapshotToLoad
493 ARMARX_DEBUG <<
"Loading graphs from " << graphFilesPath;
502 for (
const auto& graphFile : std::filesystem::directory_iterator(
505 if (std::filesystem::is_regular_file(graphFile.path()) and
509 const std::string graphName = graphFile.path().stem();
512 ARMARX_DEBUG <<
"Loading graph `" << graphName <<
" `from file `"
513 << graphFile.path() <<
"`.";
517 std::ifstream ifs(graphFile.path());
518 const std::string content((std::istreambuf_iterator<char>(ifs)),
519 (std::istreambuf_iterator<char>()));
522 const nlohmann::json j = nlohmann::json::parse(content);
524 const auto& jEdges = j.at(
"edges");
525 const auto& jVertices = j.at(
"vertices");
527 for (
const auto& jVertex : jVertices)
530 jVertex.at(
"locationID"));
532 armarx::navigation::core::arondto::Vertex
v;
533 v.vertexID = jVertex.at(
"vertexID");
534 toAron(
v.locationID, vertexLocationMemoryId);
536 v.locationID.instanceIndex = 0;
538 g.vertices.push_back(
v);
541 for (
const auto& jEdge : jEdges)
543 std::pair<std::int64_t, std::int64_t> edgeSourceTargetPair;
544 jEdge.get_to(edgeSourceTargetPair);
546 armarx::navigation::core::arondto::Edge e;
547 e.sourceVertexID = edgeSourceTargetPair.first;
548 e.targetVertexID = edgeSourceTargetPair.second;
549 g.edges.push_back(e);
554 up.referencedTime = now;
555 up.arrivedTime = now;
558 up.instancesData = {g.toAron()};
569 std::filesystem::path roomsFilePath = graph->getFullPath() /
"rooms.json";
570 if (not std::filesystem::is_regular_file(roomsFilePath))
572 ARMARX_INFO <<
"Found no rooms file for graph '" << graphId <<
"'.";
586 std::ifstream ifs(roomsFilePath);
587 const std::string content((std::istreambuf_iterator<char>(ifs)),
588 (std::istreambuf_iterator<char>()));
591 const nlohmann::json js = nlohmann::json::parse(content);
593 const auto rooms = js.at(
"rooms").get<std::map<std::string, nlohmann::json>>();
594 ARMARX_INFO <<
"Found " << rooms.size() <<
" rooms.";
595 for (
const auto& [roomId, j] : rooms)
597 auto roomMemoryId = providerID;
600 const std::string roomMemoryIdStr = roomMemoryId.str();
602 if (j.find(
"polygon") == j.end())
605 <<
"' has no 'polygon' member. Skipping "
610 if (j.find(
"height") == j.end())
613 <<
"' has no 'height' member. "
614 "Skipping this entity.";
618 navigation::rooms::arondto::Room room;
619 j.at(
"polygon").get_to(room.polygon);
620 j.at(
"height").get_to(room.height);
624 for (
auto& point : room.polygon)
632 up.referencedTime = now;
634 up.arrivedTime = now;
636 up.instancesData = {room.toAron()};
643 ARMARX_INFO <<
"Loaded NavigationMemory '" << properties.snapshotToLoad
644 <<
"' --> graph: '" << graphId <<
"'";
648 ARMARX_WARNING <<
"Could not load NavigationMemory '" << properties.snapshotToLoad
649 <<
"'. Continue with empty memory.";
654 store(
const std::map<armem::MemoryID, core::Graph>& graphs,
655 const std::filesystem::path& baseDirectory)
657 ARMARX_INFO <<
"Creating export directory `" << baseDirectory <<
"`.";
658 std::filesystem::create_directories(baseDirectory);
660 for (
const auto& [memoryId, graph] : graphs)
662 const std::filesystem::path nestedSubDir =
663 std::filesystem::path(memoryId.providerSegmentName) / memoryId.coreSegmentName;
664 const std::filesystem::path dir = baseDirectory / nestedSubDir;
666 std::filesystem::create_directories(dir);
671 std::vector<std::pair<std::size_t, std::size_t>> outgoingEdges;
674 std::back_inserter(outgoingEdges),
676 { return std::make_pair(edge.m_source, edge.m_target); });
678 j[
"edges"] = outgoingEdges;
681 for (
const auto& vertex : graph.m_vertices)
685 fromAron(vertex.m_property.aron.locationID, locationId);
687 nlohmann::json jVertex;
689 jVertex[
"vertexID"] = vertex.m_property.aron.vertexID;
691 j[
"vertices"].push_back(jVertex);
695 const std::filesystem::path
filename = dir / (memoryId.entityName +
".json");
698 ofs << std::setw(4) << j;
705 store(
const std::map<armem::MemoryID, location::arondto::Location>& locations,
706 const std::filesystem::path& baseDirectory)
708 ARMARX_INFO <<
"Creating export directory `" << baseDirectory <<
"`.";
709 std::filesystem::create_directories(baseDirectory);
712 std::map<std::string, nlohmann::json> js;
714 for (
const auto& [memoryId, location] : locations)
716 auto& j = js[memoryId.providerSegmentName];
718 if (j.count(
"locations") == 0)
724 nlohmann::json framedPose;
726 framedPose[
"agent"] = location.framedPose.header.agent;
727 framedPose[
"frame"] = location.framedPose.header.frame;
730 std::vector<std::vector<float>> poseAsVec;
732 framedPose[
"pose"] = poseAsVec;
734 jLoc[
"framedPose"] = framedPose;
736 auto entityId = memoryId.getEntityID();
737 j[
"locations"][entityId.providerSegmentName +
"/" + entityId.entityName] = jLoc;
741 for (
const auto& [providerId, j] : js)
743 const std::filesystem::path subDir = std::filesystem::path(providerId);
744 const std::filesystem::path dir = baseDirectory / subDir;
746 if (not std::filesystem::exists(dir))
748 std::filesystem::create_directories(dir);
751 const std::filesystem::path
filename = dir /
"locations.json";
754 ofs << std::setw(4) << j;
763 const Ice::Current& current)
772 const std::map<armem::MemoryID, location::arondto::Location> locations =
773 [&locationCoreSegment]()
775 std::map<armem::MemoryID, location::arondto::Location> locations;
785 locations[entity.id()].fromAron(instance->data());
797 const auto graphs = [&graphCoreSegment]()
799 std::map<armem::MemoryID, core::Graph> graphs;
811 aron.fromAron(instance->data());
827 store(locations, baseDirectory);
828 store(graphs, baseDirectory);