HumanProfileReader.cpp
Go to the documentation of this file.
2
3#include <iterator>
4
7
9
10#include <VisionX/libraries/armem_human/aron/PersonInstance.aron.generated.h>
12
14{
16
17 armarx::armem::client::query::Builder
19 {
21
23 qb.coreSegments().withName(properties().coreSegmentName);
24
27 {
28 if (not query.providerName.empty())
29 {
30 return coreSegmentQuery.providerSegments().withName(query.providerName);
31 }
32 return coreSegmentQuery.providerSegments().all();
33 }();
34
35 providerQuery.entities().all().snapshots().beforeOrAtTime(query.timestamp);
36
37 return qb;
38 }
39
42 {
44
46 qb.coreSegments().withName(properties().coreSegmentName);
47
50 {
51 if (not query.providerName.empty())
52 {
53 return coreSegmentQuery.providerSegments().withName(query.providerName);
54 }
55 return coreSegmentQuery.providerSegments().all();
56 }();
57
58 providerQuery.entities().all().snapshots().latest();
59
60 return qb;
61 }
62
63 std::vector<armarx::armem::human::Person>
65 const DateTime& timestamp,
66 const Duration& maxAge) const
67 {
69 std::vector<Person> humanProfiles;
70
71 providerSegment.forEachEntity(
72 [&](const wm::Entity& entity)
73 {
75
76 const auto& entitySnapshot = entity.getLatestSnapshot();
77
78 entitySnapshot.forEachInstance(
79 [&humanProfiles, &timestamp, &maxAge](const auto& entityInstance)
80 {
82
83 const core::time::Duration dtToNow =
84 timestamp - entityInstance.metadata().referencedTime;
85
86 if (dtToNow < maxAge and dtToNow.isPositive())
87 {
88 const auto aronDto =
90 ARMARX_CHECK(aronDto) << "Failed casting to Profile";
91
92 Person humanProfile;
93 fromAron(*aronDto, humanProfile);
94
95 humanProfiles.push_back(humanProfile);
96 };
97 });
98 });
99
100 return humanProfiles;
101 }
102
103 std::string
105 {
106 return "mem.human.profile.";
107 }
108
111 {
112 return {.memoryName = "Human", .coreSegmentName = "Profile"};
113 }
114
116 ProfileReader::query(const Query& query, bool latest) const
117 {
119
121 if (latest)
122 {
124 }
125 else
126 {
127 qb = buildQuery(query);
128 }
129
130 ARMARX_DEBUG << "[MappingDataReader] query ... ";
131
133
134 ARMARX_DEBUG << "[MappingDataReader] result: " << qResult;
135
136 if (not qResult.success)
137 {
138 ARMARX_WARNING << "Failed to query data from memory: " << qResult.errorMessage;
139 return {.humanProfiles = {},
140 .status = Result::Status::Error,
141 .errorMessage = qResult.errorMessage};
142 }
143
145 const auto coreSegment = qResult.memory.getCoreSegment(properties().coreSegmentName);
146
147 if (query.providerName.empty())
148 {
150
151 std::vector<Person> allHumanProfiles;
152
153 coreSegment.forEachProviderSegment(
154 [this, &allHumanProfiles, &query](const auto& providerSegment)
155 {
156 const std::vector<Person> humanProfiles =
157 asPersonProfiles(providerSegment, query.timestamp, query.maxAge);
158 std::copy(humanProfiles.begin(),
159 humanProfiles.end(),
160 std::back_inserter(allHumanProfiles));
161 });
162
163 if (allHumanProfiles.empty())
164 {
165 // ARMARX_WARNING << "No entities.";
166 return {.humanProfiles = {},
167 .status = Result::Status::NoData,
168 .errorMessage = "No entities"};
169 }
170
171 return Result{.humanProfiles = allHumanProfiles, .status = Result::Status::Success};
172 }
173
175
176 // -> provider segment name is set
177 if (not coreSegment.hasProviderSegment(query.providerName))
178 {
179 ARMARX_INFO << deactivateSpam(5) << "Provider segment `" << query.providerName
180 << "` does not exist (yet).";
181 return {.humanProfiles = {}, .status = Result::Status::NoData};
182 }
183
185
186 const wm::ProviderSegment& providerSegment =
187 coreSegment.getProviderSegment(query.providerName);
188
189 if (providerSegment.empty())
190 {
191 ARMARX_WARNING << "No entities.";
192 return {.humanProfiles = {},
193 .status = Result::Status::NoData,
194 .errorMessage = "No entities"};
195 }
196
197 try
198 {
200
201 const auto humanProfiles =
202 asPersonProfiles(providerSegment, query.timestamp, query.maxAge);
203 return Result{.humanProfiles = humanProfiles, .status = Result::Status::Success};
204 }
205 catch (...)
206 {
207 return Result{.status = Result::Status::Error,
208 .errorMessage = GetHandledExceptionString()};
209 }
210 }
211
213 ProfileReader::queryPreferences(const std::string& firstName,
214 const std::string& lastName,
215 const Duration& maxAge,
216 const std::string& providerName)
217 {
218 Query queryDefinition = Query{//for now we query all provider segments
219 //for now we do not provide a timestamp
220 .providerName = providerName,
221 .timestamp = armem::Time::Now(),
222 .maxAge = maxAge};
223
224 auto queryResult = query(queryDefinition, true);
225
226 std::vector<Preference> preferences;
227
228 if (queryResult.status == Result::Status::Success)
229 {
230 for (const auto& profile : queryResult.humanProfiles)
231 {
232 if (profile.id.firstName == firstName && profile.id.lastName == lastName)
233 {
234 //we for now believe first and last name in combination uniquely define one person
235 return profile.preferences;
236 }
237 }
238
240 << "You tried to query a (Human) Profile, but the query was not successful "
241 << "because the person does not exist. Check first and last name.";
242 }
243 else
244 {
246 << "You tried to query a (Human) Profile, but the query was not successful";
247 }
248
249 return {};
250 }
251
252 Person
253 ProfileReader::queryLatestProfileByName(const std::string& firstName,
254 const std::string& lastName,
255 const std::string& providerName)
256 {
257 Query queryDefinition = Query{//for now we query all provider segments
258 //for now we do not provide a timestamp
259 .providerName = providerName,
260 .timestamp = armem::Time::Now(),
261 .maxAge = armarx::Duration::Minutes(1000)};
262
263 auto queryResult = query(queryDefinition, true);
264
265 Person preferences;
266
267 if (queryResult.status == Result::Status::Success)
268 {
269 for (const auto& profile : queryResult.humanProfiles)
270 {
271 if (profile.id.firstName == firstName && profile.id.lastName == lastName)
272 {
273 //we for now believe first and last name in combination uniquely define one person
274 return profile;
275 }
276 }
277
279 << "You tried to query a (Human) Profile, but the query was not successful "
280 << "because the person does not exist. Check first and last name.";
281 }
282 else
283 {
285 << "You tried to query a (Human) Profile, but the query was not successful";
286 }
287
288 ARMARX_WARNING << "empty profile being returned";
289 return {};
290 }
291
292 std::vector<std::string>
293 ProfileReader::getPreferredDrinks(const std::string& firstName,
294 const std::string& lastName,
295 const std::string& providerName)
296 {
297 Preferences preferences =
298 queryPreferences(firstName, lastName, armarx::Duration::Hours(1000), providerName);
299 if (!preferences.drink.has_value())
300 {
301 return {};
302 }
303 return preferences.drink->preferred;
304 }
305
306} // namespace armarx::armem::human::client
std::string timestamp()
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition Logging.cpp:75
static Duration Minutes(std::int64_t minutes)
Constructs a duration in minutes.
Definition Duration.cpp:96
static Duration Hours(std::int64_t hours)
Constructs a duration in hours.
Definition Duration.cpp:120
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.
ProviderSegmentSelector & all() override
SnapshotSelector & beforeOrAtTime(Time timestamp)
Definition selectors.cpp:73
const armem::client::Reader & memoryReader() const
std::vector< armarx::armem::human::Person > asPersonProfiles(const wm::ProviderSegment &providerSegment, const DateTime &timestamp, const Duration &maxAge) const
armarx::armem::human::Person queryLatestProfileByName(const std::string &firstName, const std::string &lastName, const std::string &providerName="All Profiles")
armarx::armem::human::Preferences queryPreferences(const std::string &firstName, const std::string &lastName, const Duration &maxAge, const std::string &providerName="All Profiles")
::armarx::armem::client::query::Builder buildQuery(const Query &query) const
Result query(const Query &query, bool latest) const
::armarx::armem::client::query::Builder buildLatestQuery(const Query &query) const
std::vector< std::string > getPreferredDrinks(const std::string &firstName, const std::string &lastName, const std::string &providerName="All Profiles")
Returns a list of a humans preferred drinks.
Represents a point in time.
Definition DateTime.h:25
static DateTime Now()
Definition DateTime.cpp:51
Represents a duration.
Definition Duration.h:17
bool isPositive() const
Tests whether the duration is positive (value in µs > 0).
Definition Duration.cpp:168
#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
void fromAron(const armarx::human::arondto::HumanPose &dto, HumanPose &bo)
armarx::core::time::Duration Duration
std::optional< AronClass > tryCast(const wm::EntityInstance &item)
Tries to cast a armem::EntityInstance to AronClass.
Definition util.h:45
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< Preference > drink
Definition types.h:184
#define ARMARX_TRACE
Definition trace.h:77