Reader.cpp
Go to the documentation of this file.
1#include "Reader.h"
2
3#include <string>
4
10
17
18#include <armarx/navigation/human/aron/Human.aron.generated.h>
22
24{
25 Reader::~Reader() = default;
26
28 Reader::buildHumansQuery(const Query& query) const
29 {
31
32 // clang-format off
33 qb
34 .coreSegments().withName(properties().coreSegmentName)
36 .entities().withName("humans")
38 // clang-format on
39
40 return qb;
41 }
42
45 {
47
48 // clang-format off
49 qb
50 .coreSegments().withName(properties().coreSegmentName)
52 .entities().withName("groups")
54 // clang-format on
55
56 return qb;
57 }
58
59 std::string
61 {
62 return "mem.nav.human.";
63 }
64
67 {
68 return {.memoryName = memory::constants::NavigationMemoryName,
70 }
71
72 namespace
73 {
74
76 asHumans(const armem::wm::ProviderSegment& providerSegment,
77 const DateTime& timestamp,
78 const Duration& maxAge)
79 {
81
82 ARMARX_CHECK(not providerSegment.empty()) << "No entities";
83 ARMARX_CHECK(providerSegment.size() == 1) << "There should be only one entity!";
84
85 providerSegment.forEachEntity(
86 [&humans, &timestamp, &maxAge](const armem::wm::Entity& entity)
87 {
88 const auto& entitySnapshot = entity.getLatestSnapshot();
89 //ARMARX_CHECK(not entitySnapshot.empty()) << "No entity snapshot instances";
90 if (entitySnapshot.empty())
91 {
92 ARMARX_INFO << "No entity snapshot instances";
93 return;
94 }
95
96 entitySnapshot.forEachInstance(
97 [&](const armem::wm::EntityInstance& entityInstance)
98 {
99 const Duration dtToNow =
100 timestamp - entityInstance.metadata().referencedTime;
101
102 if (dtToNow < maxAge and dtToNow.isPositive())
103 {
104 const auto dto = navigation::human::arondto::Human::FromAron(
105 entityInstance.data());
106
108 fromAron(dto, human);
109 humans.push_back(human);
110 }
111 });
112 });
113
114 return humans;
115 }
116
118 asGroups(const armem::wm::ProviderSegment& providerSegment,
119 const DateTime& timestamp,
120 const Duration& maxAge)
121 {
123
124 ARMARX_CHECK(not providerSegment.empty()) << "No entities";
125 ARMARX_CHECK(providerSegment.size() == 1) << "There should be only one entity!";
126
127 providerSegment.forEachEntity(
128 [&humans, &timestamp, &maxAge](const armem::wm::Entity& entity)
129 {
130 const auto& entitySnapshot = entity.getLatestSnapshot();
131 ARMARX_CHECK(not entitySnapshot.empty()) << "No entity snapshot instances";
132
133 entitySnapshot.forEachInstance(
134 [&](const armem::wm::EntityInstance& entityInstance)
135 {
136 const Duration dtToNow =
137 timestamp - entityInstance.metadata().referencedTime;
138
139 if (dtToNow < maxAge and dtToNow.isPositive())
140 {
141 const auto dto = navigation::human::arondto::HumanGroup::FromAron(
142 entityInstance.data());
143
144 navigation::human::HumanGroup human;
145 fromAron(dto, human);
146 humans.push_back(human);
147 }
148 });
149 });
150
151 return humans;
152 }
153
154 } // namespace
155
157 Reader::queryHumanGroups(const Query& query) const
158 {
159 const auto qb = buildHumansQuery(query);
160
161 ARMARX_DEBUG << "[MappingDataReader] query ... ";
162
163 const armem::client::QueryResult qResult = memoryReader().query(qb.buildQueryInput());
164
165 ARMARX_DEBUG << "[MappingDataReader] result: " << qResult;
166
167 if (not qResult.success)
168 {
169 ARMARX_WARNING << "Failed to query data from memory: " << qResult.errorMessage;
170 return {.groups = {},
172 .errorMessage = qResult.errorMessage};
173 }
174
175 const auto coreSegment = qResult.memory.getCoreSegment(properties().coreSegmentName);
176
177 if (not coreSegment.hasProviderSegment(query.providerName))
178 {
179 ARMARX_DEBUG << "Provider segment " << QUOTED(query.providerName) << " does not exist (yet).";
180 return {.groups = {}, .status = HumanGroupResult::Status::NoData};
181 }
182
183 const armem::wm::ProviderSegment& providerSegment =
184 coreSegment.getProviderSegment(query.providerName);
185
186 if (providerSegment.empty())
187 {
188 ARMARX_DEBUG << "No entities.";
189 return {.groups = {},
191 .errorMessage = "No entities"};
192 }
193
194 try
195 {
196 return HumanGroupResult{.groups =
197 asGroups(providerSegment, query.timestamp, query.maxAge),
199 }
200 catch (...)
201 {
202 return HumanGroupResult{.groups = {},
204 .errorMessage = GetHandledExceptionString()};
205 }
206 }
207
209 Reader::queryHumans(const Query& query) const
210 {
211 const auto qb = buildHumansQuery(query);
212
213 ARMARX_DEBUG << "[MappingDataReader] query ... ";
214
215 const armem::client::QueryResult qResult = memoryReader().query(qb.buildQueryInput());
216
217 ARMARX_DEBUG << "[MappingDataReader] result: " << qResult;
218
219 if (not qResult.success)
220 {
221 ARMARX_WARNING << "Failed to query data from memory: " << qResult.errorMessage;
222 return {.humans = {},
224 .errorMessage = qResult.errorMessage};
225 }
226
227 const auto coreSegment = qResult.memory.getCoreSegment(properties().coreSegmentName);
228
229 if (not coreSegment.hasProviderSegment(query.providerName))
230 {
231 ARMARX_DEBUG << "Provider segment " << QUOTED(query.providerName) << " does not exist (yet).";
232 return {.humans = {}, .status = HumanResult::Status::NoData};
233 }
234
235 const armem::wm::ProviderSegment& providerSegment =
236 coreSegment.getProviderSegment(query.providerName);
237
238 if (providerSegment.empty())
239 {
240 ARMARX_VERBOSE << "No entities.";
241 return {.humans = {},
243 .errorMessage = "No entities"};
244 }
245
246 try
247 {
248 return HumanResult{.humans = asHumans(providerSegment, query.timestamp, query.maxAge),
250 }
251 catch (...)
252 {
253 return HumanResult{.humans = {},
255 .errorMessage = GetHandledExceptionString()};
256 }
257 }
258
259} // namespace armarx::navigation::memory::client::human
std::string timestamp()
#define QUOTED(x)
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.
EntitySelector & withName(const std::string &name) override
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.
Represents a point in time.
Definition DateTime.h:25
Represents a duration.
Definition Duration.h:17
bool isPositive() const
Tests whether the duration is positive (value in µs > 0).
Definition Duration.cpp:168
Properties defaultProperties() const override
Definition Reader.cpp:66
std::string propertyPrefix() const override
Definition Reader.cpp:60
HumanGroupResult queryHumanGroups(const Query &query) const
Definition Reader.cpp:157
HumanResult queryHumans(const Query &query) const
Definition Reader.cpp:209
::armarx::armem::client::query::Builder buildHumansQuery(const Query &query) const
Definition Reader.cpp:28
::armarx::armem::client::query::Builder buildHumanGroupsQuery(const Query &query) const
Definition Reader.cpp:44
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#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
std::vector< Human > Humans
Definition types.h:48
std::vector< HumanGroup > HumanGroups
Definition types.h:60
constexpr const char * HumanCoreSegmentName
Definition constants.h:38
constexpr const char * NavigationMemoryName
Definition constants.h:29
void fromAron(const arondto::Circle &dto, Circle &bo)
std::string GetHandledExceptionString()
Time referencedTime
Time this instance refers to.
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