UpdateConsumer.cpp
Go to the documentation of this file.
1 #include "UpdateConsumer.h"
2 
8 
10 #include <VisionX/libraries/armem_human/aron/FaceRecognition.aron.generated.h>
11 #include <VisionX/libraries/armem_human/aron/HumanPose.aron.generated.h>
12 #include <VisionX/libraries/armem_human/aron/PersonInstance.aron.generated.h>
13 #include <VisionX/libraries/armem_human/aron/Profile.aron.generated.h>
22 
24 {
25 
26  UpdateConsumer::UpdateConsumer() : maxFaceHeadDistance(1000.0)
27  {
28  }
29 
30  UpdateConsumer::UpdateConsumer(int maxFaceHeadDistance) :
31  maxFaceHeadDistance(maxFaceHeadDistance)
32  {
33  }
34 
35  //TODO: add some form of history to allow for better understanding of memory changed of the personInstances
36  //TODO: add visualization of
37  void
40  armarx::armem::MemoryID faceRecognitionID,
42  {
43  armarx::armem::client::Writer personInstanceWriter =
45  armarx::armem::client::Reader personInstanceReader =
49  armarx::armem::MemoryID profileID;
50 
51  if (faceRecognition.profileID.has_value())
52  {
53  profileID = faceRecognition.profileID.value();
54  }
55  else
56  {
57  ARMARX_INFO << "Face recognition " + faceRecognitionID.entityName +
58  " does not provide valid profileID, finding matching "
59  "personInstance is not possible.";
60  return;
61  }
62 
63  if (queryResult.success)
64  {
65  //TODO: add early return in case face recognition id is already used by a personInstance
66  bool foundMatchingEntity = false;
67  queryResult.memory.forEachInstance(
68  [&profileID, &personInstanceWriter, &faceRecognitionID, &foundMatchingEntity](
69  const armarx::armem::wm::EntityInstance& instance)
70  {
71  armarx::human::arondto::PersonInstance personInstance =
72  instance.dataAs<armarx::human::arondto::PersonInstance>();
73  if (profileID.entityName == personInstance.profileID.entityName)
74  {
75  //update matching personInstance
76  toAron(personInstance.faceRecognitionID, faceRecognitionID);
78  update.entityID = instance.id();
79  update.referencedTime = armarx::armem::Time::Now();
80  update.instancesData = {personInstance.toAron()};
81  personInstanceWriter.commit(update);
82  ARMARX_INFO << "Updated face recognition on personInstance " +
83  instance.id().entityName + ".";
84  //TODO: check for plausibility of personInstance, remove in case plausibility is no longer ensured, restart consume process afterwards to generate new personInstance
85  foundMatchingEntity = true;
86  return;
87  }
88  });
89  if (foundMatchingEntity)
90  {
91  return;
92  }
93  //create new personInstance in case no matching personInstance could be found
94  {
95  armarx::human::arondto::PersonInstance personInstance;
96  toAron(personInstance.faceRecognitionID, faceRecognitionID);
97  toAron(personInstance.profileID, profileID);
98  std::optional<armarx::armem::MemoryID> closestPoseID =
99  getClosestPoseID(faceRecognition.position3DGlobal, mns);
100  if (closestPoseID.has_value())
101  {
102  toAron(personInstance.poseID, closestPoseID.value());
103  }
107  .withEntityName(faceRecognition.profileID.value().entityName);
108  update.referencedTime = armarx::armem::Time::Now();
109  update.instancesData = {personInstance.toAron()};
110  personInstanceWriter.commit(update);
111  ARMARX_INFO << "Created new personInstance for face recognition " +
112  faceRecognitionID.entityName + ".";
113  }
114  }
115  }
116 
117  void
121  {
122  armarx::armem::client::Writer personInstanceWriter =
124  armarx::armem::client::Reader personInstanceReader =
128  if (queryResult.success)
129  {
130  bool poseKnown = false;
131  queryResult.memory.forEachInstance(
132  [&poseKnown, &poseID](const armarx::armem::wm::EntityInstance& instance)
133  {
134  armarx::human::arondto::PersonInstance personInstance =
135  instance.dataAs<armarx::human::arondto::PersonInstance>();
136  armarx::armem::MemoryID currentPoseID;
137  fromAron(personInstance.poseID, currentPoseID);
138  poseKnown = poseKnown or (currentPoseID == poseID);
139  });
140 
141  if (poseKnown)
142  {
143  //TODO: check for plausibility of personInstance, remove in case plausibility is no longer ensured, restart consume process afterwards to generate new personInstance
144  return;
145  }
146  std::optional<armarx::FramedPosition> headPos = getHeadPos(humanPose);
147  if (headPos.has_value())
148  {
149  std::optional<armarx::armem::MemoryID> faceRecognitionID =
150  getClosestFaceID(headPos.value(), mns);
151  if (faceRecognitionID.has_value())
152  {
153  armarx::human::arondto::PersonInstance personInstance;
154  toAron(personInstance.faceRecognitionID, faceRecognitionID.value());
155  //TODO: get profile id
156  //toAron(personInstance.profileID, profileID);
157  toAron(personInstance.poseID, poseID);
159  update.entityID =
162  //.withEntityName(faceRecognition.profileID.value().entityName);
163  update.referencedTime = armarx::armem::Time::Now();
164  update.instancesData = {personInstance.toAron()};
165  personInstanceWriter.commit(update);
166  ARMARX_INFO << "Created new personInstance for human pose " +
167  poseID.entityName + ".";
168  }
169  }
170  }
171  }
172 
173  void
175  armarx::armem::MemoryID profileID,
177  {
178  //TODO: implement profile update logic
179  }
180 
181  std::optional<armarx::armem::MemoryID>
182  UpdateConsumer::getClosestPoseID(Eigen::Matrix<float, 3, 1> facePos,
184  {
188 
189  armarx::armem::MemoryID closestPoseID;
190  float closestDistance = maxFaceHeadDistance;
191 
192  if (queryResult.success)
193  {
194  queryResult.memory.forEachInstance(
195  [&facePos, &closestPoseID, &closestDistance](
196  const armarx::armem::wm::EntityInstance& instance)
197  {
198  armarx::human::arondto::HumanPose dto =
199  instance.dataAs<armarx::human::arondto::HumanPose>();
201  fromAron(dto, pose);
202  std::optional<armarx::FramedPosition> headPos_opt = getHeadPos(pose);
203  if (headPos_opt.has_value())
204  {
205  armarx::FramedPosition headPos = headPos_opt.value();
206  float distance = getDistance(facePos, headPos);
207  if (distance < closestDistance)
208  {
209  closestPoseID = instance.id();
210  closestDistance = distance;
211  }
212  }
213  });
214  }
215  return closestPoseID;
216  }
217 
218  std::optional<armarx::armem::MemoryID>
219  UpdateConsumer::getClosestFaceID(armarx::FramedPosition headPos,
221  {
222  armarx::armem::client::Reader faceRecognitionReader =
226 
227  armarx::armem::MemoryID closestFaceID;
228  float closestDistance = maxFaceHeadDistance;
229 
230  if (queryResult.success)
231  {
232  queryResult.memory.forEachInstance(
233  [&headPos, &closestFaceID, &closestDistance](
234  const armarx::armem::wm::EntityInstance& instance)
235  {
236  armarx::human::arondto::FaceRecognition dto =
237  instance.dataAs<armarx::human::arondto::FaceRecognition>();
239  fromAron(dto, faceRecognition);
240 
241  float distance = getDistance(faceRecognition.position3DGlobal, headPos);
242  if (distance < closestDistance)
243  {
244  closestFaceID = instance.id();
245  closestDistance = distance;
246  }
247  });
248  }
249  return closestFaceID;
250  }
251 
252  std::optional<armarx::FramedPosition>
253  UpdateConsumer::getHeadPos(armarx::armem::human::HumanPose pose)
254  {
255  std::optional<armarx::FramedPosition> headPos;
257  {
258  //TODO: implement pose type
259  }
261  {
264  .positionGlobal;
265  }
267  {
268  //TODO: implement pose type
269  }
270  else
271  {
272  ARMARX_WARNING << "Unknown pose model ID '" << pose.poseModelId;
273  }
274  return headPos;
275  }
276 
277  float
278  UpdateConsumer::getDistance(Eigen::Matrix<float, 3, 1> facePos, armarx::FramedPosition headPos)
279  {
280  return sqrt(facePos.x() * headPos.x + facePos.y() * headPos.y + facePos.z() * headPos.z);
281  }
282 } // namespace VisionX::components::person_instance_updater
armarx::armem::detail::SuccessHeader::success
bool success
Definition: SuccessHeader.h:20
GfxTL::sqrt
VectorXD< D, T > sqrt(const VectorXD< D, T > &a)
Definition: VectorXD.h:662
VisionX::components::person_instance_updater::UpdateConsumer::UpdateConsumer
UpdateConsumer()
Definition: UpdateConsumer.cpp:26
armarx::armem::client::Reader
Reads data from a memory server.
Definition: Reader.h:24
VisionX::components::person_instance_updater::PersonInstanceUpdater::provider_name
static const std::string provider_name
Definition: PersonInstanceUpdater.h:49
Reader.h
armarx::armem::client::QueryResult::memory
wm::Memory memory
The slice of the memory that matched the query.
Definition: Query.h:58
armarx::armem::client::Reader::getLatestSnapshotsIn
QueryResult getLatestSnapshotsIn(const MemoryID &id, armem::query::DataMode dataMode=armem::query::DataMode::WithData) const
Get the latest snapshots under the given memory ID.
Definition: Reader.cpp:343
Writer.h
armarx::human::FaceRecognitionCoreSegmentID
const armem::MemoryID FaceRecognitionCoreSegmentID
Definition: memory_ids.cpp:31
armarx::armem::wm::EntityInstance
Client-side working entity instance.
Definition: memory_definitions.h:32
VisionX::components::person_instance_updater::UpdateConsumer::consumeFaceRecognitionUpdate
void consumeFaceRecognitionUpdate(armarx::armem::human::FaceRecognition faceRecognition, armarx::armem::MemoryID faceRecognitionID, armarx::armem::client::MemoryNameSystem mns)
Definition: UpdateConsumer.cpp:38
armarx::core::time::DateTime::Now
static DateTime Now()
Definition: DateTime.cpp:55
MemoryID.h
armarx::armem::human::FaceRecognition
Definition: types.h:59
memory_ids.h
armarx::armem::client::QueryResult
Result of a QueryInput.
Definition: Query.h:50
VisionX::components::person_instance_updater
Definition: PersonInstanceUpdater.cpp:43
armarx::armem::client::MemoryNameSystem::getWriter
Writer getWriter(const MemoryID &memoryID)
Get a writer to the given memory name.
Definition: MemoryNameSystem.cpp:270
k4a_bt_body_32.h
VisionX::components::person_instance_updater::UpdateConsumer::consumeProfileUpdate
void consumeProfileUpdate(armarx::human::arondto::Profile profile, armarx::armem::MemoryID profileID, armarx::armem::client::MemoryNameSystem mns)
Definition: UpdateConsumer.cpp:174
armarx::human::pose::model::k4a_bt_body_32::Joints::Head
@ Head
PersonInstanceUpdater.h
armarx::armem::human::HumanPose::poseModelId
std::string poseModelId
Definition: types.h:32
armarx::armem::base::EntityInstanceBase::dataAs
AronDtoT dataAs() const
Get the data converted to a generated Aron DTO class.
Definition: EntityInstanceBase.h:157
armarx::armem::MemoryID::withProviderSegmentName
MemoryID withProviderSegmentName(const std::string &name) const
Definition: MemoryID.cpp:412
armarx::armem::MemoryID
A memory ID.
Definition: MemoryID.h:47
armarx::human::pose::model::k4a_bt_body_32::JointNames
const simox::meta::EnumNames< Joints > JointNames
Names of the joints as defined in the body model.
Definition: k4a_bt_body_32.h:78
PoseSegment.h
VisionX::components::person_instance_updater::UpdateConsumer::consumePoseUpdate
void consumePoseUpdate(armarx::armem::human::HumanPose humanPose, armarx::armem::MemoryID poseID, armarx::armem::client::MemoryNameSystem mns)
Definition: UpdateConsumer.cpp:118
armarx::FramedPosition
The FramedPosition class.
Definition: FramedPose.h:142
armarx::armem::server::human::profile::Profile
armarx::human::arondto::Profile Profile
Definition: Segment.cpp:43
armarx::armem::EntityUpdate
An update of an entity for a specific point in time.
Definition: Commit.h:27
armarx::armem::client::Writer
Helps a memory client sending data to a memory.
Definition: Writer.h:22
armarx::armem::client::Writer::commit
CommitResult commit(const Commit &commit) const
Writes a Commit to the memory.
Definition: Writer.cpp:59
armarx::armem::base::detail::MemoryItem::id
MemoryID & id()
Definition: MemoryItem.h:27
armarx::armem::human::HumanPose
Definition: types.h:30
armarx::armem::MemoryID::entityName
std::string entityName
Definition: MemoryID.h:53
armarx::armem::server::ltm::util::mongodb::detail::update
bool update(mongocxx::collection &coll, const nlohmann::json &query, const nlohmann::json &update)
Definition: mongodb.cpp:67
aron_conversions.h
armarx::human::pose::model::k4a_bt_body_32::ModelId
const std::string ModelId
Definition: k4a_bt_body_32.h:34
UpdateConsumer.h
armarx::human::PersonInstanceCoreSegmentID
const armem::MemoryID PersonInstanceCoreSegmentID
Definition: memory_ids.cpp:37
armarx::armem::human::FaceRecognition::position3DGlobal
Eigen::Matrix< float, 3, 1 > position3DGlobal
Definition: types.h:62
openpose_body_25.h
armarx::armem::MemoryID::withEntityName
MemoryID withEntityName(const std::string &name) const
Definition: MemoryID.cpp:420
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
aron_conversions.h
Segment.h
armarx::human::pose::model::openpose_body_25::ModelId
const std::string ModelId
Definition: openpose_body_25.h:30
Segment.h
armarx::armem::base::detail::ForEachEntityInstanceMixin::forEachInstance
bool forEachInstance(InstanceFunctionT &&func)
Definition: iteration_mixins.h:146
armarx::fromAron
void fromAron(const arondto::PackagePath &dto, PackageFileLocation &bo)
armarx::armem::client::MemoryNameSystem
The memory name system (MNS) client.
Definition: MemoryNameSystem.h:69
Eigen::Matrix< float, 3, 1 >
distance
double distance(const Point &a, const Point &b)
Definition: point.hpp:88
armarx::human::PoseCoreSegmentID
const armem::MemoryID PoseCoreSegmentID
Definition: memory_ids.cpp:40
mmm_body_68.h
MemoryNameSystem.h
armarx::armem::human::HumanPose::keypoints
KeyPointMap keypoints
Definition: types.h:35
armarx::toAron
void toAron(arondto::PackagePath &dto, const PackageFileLocation &bo)
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:186
armarx::armem::client::MemoryNameSystem::getReader
Reader getReader(const MemoryID &memoryID)
Get a reader to the given memory name.
Definition: MemoryNameSystem.cpp:177
armarx::armem::human::FaceRecognition::profileID
std::optional< armarx::armem::MemoryID > profileID
Definition: types.h:70
armarx::human::pose::model::mmm_body_68::ModelId
const std::string ModelId
Definition: mmm_body_68.h:30