HumanActivityReader.cpp
Go to the documentation of this file.
2
3#include <iterator>
4
7
9
10#include <VisionX/libraries/armem_human/aron/HumanActivity.aron.generated.h>
12
14{
16
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<HumanActivity>
65 const DateTime& timestamp,
66 const Duration& maxAge) const
67 {
69 std::vector<HumanActivity> activities;
70
71 providerSegment.forEachEntity(
72 [&](const wm::Entity& entity)
73 {
75
76 const auto& entitySnapshot = entity.getLatestSnapshot();
77
78 entitySnapshot.forEachInstance(
79 [&activities, &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 HumanActivity";
91
92 HumanActivity activity;
93 fromAron(*aronDto, activity);
94
95 activities.push_back(activity);
96 };
97 });
98 });
99
100 return activities;
101 }
102
103 std::string
105 {
106 return "mem.human.activity.";
107 }
108
111 {
112 return {.memoryName = "Human", .coreSegmentName = "HumanActivity"};
113 }
114
116 ActivityReader::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 << "[ActivityReader] query ... ";
131
133
134 ARMARX_DEBUG << "[ActivityReader] result: " << qResult;
135
136 if (not qResult.success)
137 {
138 ARMARX_WARNING << "Failed to query data from memory: " << qResult.errorMessage;
139 return {.activities = {},
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<HumanActivity> allActivities;
152
153 coreSegment.forEachProviderSegment(
154 [this, &allActivities, &query](const auto& providerSegment)
155 {
156 const std::vector<HumanActivity> activities =
157 asHumanActivities(providerSegment, query.timestamp, query.maxAge);
158 std::copy(activities.begin(),
159 activities.end(),
160 std::back_inserter(allActivities));
161 });
162
163 if (allActivities.empty())
164 {
165 return {.activities = {},
166 .status = Result::Status::NoData,
167 .errorMessage = "No entities"};
168 }
169
170 return Result{.activities = allActivities, .status = Result::Status::Success};
171 }
172
174
175 // -> provider segment name is set
176 if (not coreSegment.hasProviderSegment(query.providerName))
177 {
178 ARMARX_INFO << deactivateSpam(5) << "Provider segment `" << query.providerName
179 << "` does not exist (yet).";
180 return {.activities = {}, .status = Result::Status::NoData};
181 }
182
184
185 const wm::ProviderSegment& providerSegment =
186 coreSegment.getProviderSegment(query.providerName);
187
188 if (providerSegment.empty())
189 {
190 ARMARX_WARNING << "No entities.";
191 return {.activities = {},
192 .status = Result::Status::NoData,
193 .errorMessage = "No entities"};
194 }
195
196 try
197 {
199
200 const auto activities = asHumanActivities(providerSegment, query.timestamp, query.maxAge);
201 return Result{.activities = activities, .status = Result::Status::Success};
202 }
203 catch (...)
204 {
205 return Result{.status = Result::Status::Error,
206 .errorMessage = GetHandledExceptionString()};
207 }
208 }
209
210 std::vector<HumanActivity>
211 ActivityReader::queryActivitiesForPerson(const std::string& firstName,
212 const std::string& lastName,
213 const Duration& maxAge,
214 const std::string& providerName)
215 {
216 Query queryDefinition = Query{.providerName = providerName,
217 .timestamp = armem::Time::Now(),
218 .maxAge = maxAge};
219
220 auto queryResult = query(queryDefinition, true);
221
222 std::vector<HumanActivity> matchingActivities;
223
224 if (queryResult.status == Result::Status::Success)
225 {
226 for (const auto& activity : queryResult.activities)
227 {
228 if (activity.personID.has_value() &&
229 activity.personID.value().firstName == firstName &&
230 activity.personID.value().lastName == lastName)
231 {
232 matchingActivities.push_back(activity);
233 }
234 }
235
236 if (matchingActivities.empty())
237 {
238 ARMARX_INFO << "No activities found for person " << firstName << " " << lastName;
239 }
240 }
241 else
242 {
243 ARMARX_WARNING << "Failed to query activities from memory";
244 }
245
246 return matchingActivities;
247 }
248
249 std::optional<HumanActivity>
251 const std::string& lastName,
252 const std::string& providerName)
253 {
254 Query queryDefinition = Query{.providerName = providerName,
255 .timestamp = armem::Time::Now(),
256 .maxAge = armarx::Duration::Minutes(1000)};
257
258 auto queryResult = query(queryDefinition, true);
259
260 if (queryResult.status == Result::Status::Success)
261 {
262 // Find the latest activity for the given person
263 std::optional<HumanActivity> latestActivity;
264 DateTime latestTime;
265
266 for (const auto& activity : queryResult.activities)
267 {
268 if (activity.personID.has_value() &&
269 activity.personID.value().firstName == firstName &&
270 activity.personID.value().lastName == lastName)
271 {
272 if (!latestActivity.has_value() || activity.startTime > latestTime)
273 {
274 latestActivity = activity;
275 latestTime = activity.startTime;
276 }
277 }
278 }
279
280 if (latestActivity.has_value())
281 {
282 return latestActivity;
283 }
284 else
285 {
286 ARMARX_INFO << "No activities found for person " << firstName << " " << lastName;
287 }
288 }
289 else
290 {
291 ARMARX_WARNING << "Failed to query activities from memory";
292 }
293
294 return std::nullopt;
295 }
296
297} // 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
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
Result query(const Query &query, bool latest) const
std::optional< HumanActivity > queryLatestActivityForPerson(const std::string &firstName, const std::string &lastName, const std::string &providerName="")
::armarx::armem::client::query::Builder buildQuery(const Query &query) const
std::vector< HumanActivity > queryActivitiesForPerson(const std::string &firstName, const std::string &lastName, const Duration &maxAge, const std::string &providerName="")
::armarx::armem::client::query::Builder buildLatestQuery(const Query &query) const
std::vector< HumanActivity > asHumanActivities(const wm::ProviderSegment &providerSegment, const DateTime &timestamp, const Duration &maxAge) const
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
#define ARMARX_TRACE
Definition trace.h:77