Reader.cpp
Go to the documentation of this file.
1#include "Reader.h"
2
3#include <optional>
4#include <string>
5
12
19
23
25{
26 Reader::~Reader() = default;
27
30 {
32
33 // clang-format off
34 auto& sel = qb
35 .coreSegments().withName(properties().coreSegmentName)
36 .providerSegments().withName(query.providerName)
37 .entities();
38 if (query.name.empty()){
39 sel = sel.all();
40 }else{
41 sel = sel.withName(query.name);
42 }
43 sel.snapshots().beforeOrAtTime(query.timestamp);
44 // clang-format on
45
46 return qb;
47 }
48
49 std::string
51 {
52 return "mem.nav.costmap.";
53 }
54
57 {
58 return {.memoryName = memory::constants::NavigationMemoryName,
60 }
61
62 namespace
63 {
65 asCostmap(const armem::wm::ProviderSegment& providerSegment)
66 {
67 ARMARX_CHECK_NOT_EMPTY(providerSegment) << "No entities";
68 ARMARX_CHECK_EQUAL(providerSegment.size(), 1) << "There should be only one entity!";
69
70 const armem::wm::EntityInstance* entityInstance = nullptr;
71 providerSegment.forEachEntity(
72 [&entityInstance](const armem::wm::Entity& entity)
73 {
74 const auto& entitySnapshot = entity.getLatestSnapshot();
75 ARMARX_CHECK(not entitySnapshot.empty()) << "No entity snapshot instances";
76
77 entityInstance = &entitySnapshot.getInstance(0);
78 ARMARX_DEBUG << VAROUT(entitySnapshot.time());
79 return false;
80 });
81 ARMARX_CHECK_NOT_NULL(entityInstance);
82 return algorithms::fromAron(*entityInstance);
83 }
84 } // namespace
85
86 Reader::Result
88 {
89 const auto qb = buildQuery(query);
90
91 ARMARX_DEBUG << "[MappingDataReader] query ... ";
92
93 const armem::client::QueryResult qResult = memoryReader().query(qb.buildQueryInput());
94
95 ARMARX_DEBUG << "[MappingDataReader] result: " << qResult;
96
97 if (not qResult.success)
98 {
99 ARMARX_WARNING << "Failed to query data from memory: " << qResult.errorMessage;
100 return {.costmap = std::nullopt,
101 .status = Result::Status::Error,
102 .errorMessage = qResult.errorMessage};
103 }
104
105 const auto coreSegment = qResult.memory.getCoreSegment(properties().coreSegmentName);
106
107 if (not coreSegment.hasProviderSegment(query.providerName))
108 {
109 ARMARX_VERBOSE << "Provider segment `" << query.providerName
110 << "` does not exist (yet).";
111 return {.costmap = std::nullopt, .status = Result::Status::NoData};
112 }
113
114 const armem::wm::ProviderSegment& providerSegment =
115 coreSegment.getProviderSegment(query.providerName);
116
117 if (providerSegment.empty())
118 {
119 ARMARX_VERBOSE << "No entities.";
120 return {.costmap = std::nullopt,
121 .status = Result::Status::NoData,
122 .errorMessage = "No entities"};
123 }
124
125 try
126 {
127 return Result{.costmap = asCostmap(providerSegment), .status = Result::Status::Success};
128 }
129 catch (...)
130 {
131 return Result{.status = Result::Status::Error,
132 .errorMessage = GetHandledExceptionString()};
133 }
134 }
135
137 Reader::waitForCostmap(std::string& providerName, std::string& name, int delayMs) const
138 {
140 while (true)
141 {
142 const auto timestamp = armarx::Clock::Now();
143
145 .providerName = "distance_to_obstacle_costmap_provider",
146 .name = "distance_to_obstacles",
147 .timestamp = timestamp};
148
149 const Result costmapResult = query(costmapQuery);
150
151 // if costmap is not available yet, wait
152 if (costmapResult.status != Result::Success)
153 {
154 ARMARX_INFO << deactivateSpam(10.) << "Waiting for costmap";
156 continue;
157 }
158
159 ARMARX_VERBOSE << "Received costmap \"" << providerName << "/" << name << "\"";
160
162
164 ARMARX_CHECK(costmapResult.costmap.has_value());
165 return costmapResult.costmap.value();
166 };
167 }
168
169} // namespace armarx::navigation::memory::client::costmap
std::string timestamp()
#define ARMARX_CHECK_NOT_EMPTY(c)
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition Logging.cpp:75
#define VAROUT(x)
static DateTime Now()
Current time on the virtual clock.
Definition Clock.cpp:93
static void WaitFor(const Duration &duration)
Wait for a certain duration on the virtual clock.
Definition Clock.cpp:99
static Duration MilliSeconds(std::int64_t milliSeconds)
Constructs a duration in milliseconds.
Definition Duration.cpp:48
CoreSegmentT & getCoreSegment(const std::string &name)
Definition MemoryBase.h:134
QueryResult query(const QueryInput &input) const
Perform a query on the WM.
Definition Reader.cpp:119
The query::Builder class provides a fluent-style specification of hierarchical queries.
Definition Builder.h:22
CoreSegmentSelector & coreSegments()
Start specifying core segments.
Definition Builder.cpp:42
CoreSegmentSelector & withName(const std::string &name) override
ProviderSegmentSelector & providerSegments()
Start specifying provider segments.
SnapshotSelector & snapshots()
Start specifying entity snapshots.
Definition selectors.cpp:92
ProviderSegmentSelector & withName(const std::string &name) override
EntitySelector & entities()
Start specifying entities.
SnapshotSelector & beforeOrAtTime(Time timestamp)
Definition selectors.cpp:73
const armem::client::Reader & memoryReader() const
Client-side working entity instance.
Client-side working memory entity.
Client-side working memory provider segment.
Properties defaultProperties() const override
Definition Reader.cpp:56
algorithms::Costmap waitForCostmap(std::string &providerName, std::string &name, int delayMs=200) const
Definition Reader.cpp:137
std::string propertyPrefix() const override
Definition Reader.cpp:50
::armarx::armem::client::query::Builder buildQuery(const Query &query) const
Definition Reader.cpp:29
Result query(const Query &query) const
Definition Reader.cpp:87
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
#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...
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
Definition Logging.h:184
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
Costmap fromAron(const armem::wm::EntityInstance &entityInstance)
constexpr const char * CostmapCoreSegmentName
Definition constants.h:36
constexpr const char * NavigationMemoryName
Definition constants.h:29
std::string GetHandledExceptionString()
auto & getLatestSnapshot(int snapshotIndex=0)
Retrieve the latest entity snapshot.
Result of a QueryInput.
Definition Query.h:51
wm::Memory memory
The slice of the memory that matched the query.
Definition Query.h:58
std::optional< algorithms::Costmap > costmap
Definition Reader.h:51
enum armarx::navigation::memory::client::costmap::Reader::Result::Status status
#define ARMARX_TRACE
Definition trace.h:77