HumanPoseReader.cpp
Go to the documentation of this file.
1#include "HumanPoseReader.h"
2
3#include <iterator>
4
7
9
10#include <VisionX/libraries/armem_human/aron/HumanPose.aron.generated.h>
12
14{
15 Reader::~Reader() = default;
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
40 std::string
42 {
43 return "mem.human.pose.";
44 }
45
48 {
49 return {.memoryName = "Human", .coreSegmentName = "Pose"};
50 }
51
52 std::vector<HumanPose>
53 asHumanPoses(const wm::ProviderSegment& providerSegment,
54 const DateTime& timestamp,
55 const Duration& maxAge)
56 {
58
59 // ARMARX_CHECK(not providerSegment.empty()) << "No entities";
60 // ARMARX_CHECK(providerSegment.size() == 1) << "There should be only one entity!";
61
62 std::vector<HumanPose> humanPoses;
63 providerSegment.forEachEntity(
64 [&](const wm::Entity& entity)
65 {
67
68 const auto& entitySnapshot = entity.getLatestSnapshot();
69 // Not clear yet why, but it seems that this sometimes happens (not frequently).
70 // ARMARX_CHECK(not entitySnapshot.empty()) << "No entity snapshot instances";
71
72 entitySnapshot.forEachInstance(
73 [&humanPoses, &timestamp, &maxAge](const auto& entityInstance)
74 {
76
77 const core::time::Duration dtToNow =
78 timestamp - entityInstance.metadata().referencedTime;
79
80 if (dtToNow < maxAge and dtToNow.isPositive())
81 {
82 const auto aronDto =
84 ARMARX_CHECK(aronDto) << "Failed casting to HumanPose";
85
86 HumanPose humanPose;
87 fromAron(*aronDto, humanPose);
88 humanPose.timestamp = entityInstance.metadata().referencedTime;
89
90 humanPoses.push_back(humanPose);
91 };
92 });
93 });
94
95 // when no humans are in the scene, this is empty
96 //ARMARX_CHECK_NOT_EMPTY(humanPoses);
97
98 return humanPoses;
99 }
100
101 Reader::Result
103 {
105 const auto qb = buildQuery(query);
106
107 ARMARX_DEBUG << "[MappingDataReader] query ... ";
108
109 const armem::client::QueryResult qResult = memoryReader().query(qb.buildQueryInput());
110
111 ARMARX_DEBUG << "[MappingDataReader] result: " << qResult;
112
113 if (not qResult.success)
114 {
115 ARMARX_WARNING << "Failed to query data from memory: " << qResult.errorMessage;
116 return {.humanPoses = {},
117 .status = Result::Status::Error,
118 .errorMessage = qResult.errorMessage};
119 }
120
122 const auto coreSegment = qResult.memory.getCoreSegment(properties().coreSegmentName);
123
124 if (query.providerName.empty())
125 {
127
128 std::vector<HumanPose> allHumanPoses;
129
130 coreSegment.forEachProviderSegment(
131 [&allHumanPoses, &query](const auto& providerSegment)
132 {
133 const std::vector<HumanPose> humanPoses =
134 asHumanPoses(providerSegment, query.timestamp, query.maxAge);
135 std::copy(
136 humanPoses.begin(), humanPoses.end(), std::back_inserter(allHumanPoses));
137 });
138
139 if (allHumanPoses.empty())
140 {
141 // ARMARX_WARNING << "No entities.";
142 return {.humanPoses = {},
143 .status = Result::Status::NoData,
144 .errorMessage = "No entities"};
145 }
146
147 return Result{.humanPoses = allHumanPoses, .status = Result::Status::Success};
148 }
149
151
152 // -> provider segment name is set
153 if (not coreSegment.hasProviderSegment(query.providerName))
154 {
155 ARMARX_INFO << deactivateSpam(5) << "Provider segment `" << query.providerName
156 << "` does not exist (yet).";
157 return {.humanPoses = {}, .status = Result::Status::NoData};
158 }
159
161
162 const wm::ProviderSegment& providerSegment =
163 coreSegment.getProviderSegment(query.providerName);
164
165 if (providerSegment.empty())
166 {
167 ARMARX_WARNING << "No entities.";
168 return {
169 .humanPoses = {}, .status = Result::Status::NoData, .errorMessage = "No entities"};
170 }
171
172 try
173 {
175
176 const auto humanPoses = asHumanPoses(providerSegment, query.timestamp, query.maxAge);
177 return Result{.humanPoses = humanPoses, .status = Result::Status::Success};
178 }
179 catch (...)
180 {
181 return Result{.status = Result::Status::Error,
182 .errorMessage = GetHandledExceptionString()};
183 }
184 }
185
186} // 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
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
Properties defaultProperties() const override
std::string propertyPrefix() const override
::armarx::armem::client::query::Builder buildQuery(const Query &query) const
Result query(const Query &query) const
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
#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
std::vector< HumanPose > asHumanPoses(const wm::ProviderSegment &providerSegment, const DateTime &timestamp, const Duration &maxAge)
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