20 #include <VisionX/libraries/armem_human/aron/FaceRecognition.aron.generated.h>
21 #include <VisionX/libraries/armem_human/aron/HumanPose.aron.generated.h>
22 #include <VisionX/libraries/armem_human/aron/PersonInstance.aron.generated.h>
23 #include <VisionX/libraries/armem_human/aron/Profile.aron.generated.h>
41 maxFaceHeadDistance(maxFaceHeadDistance)
62 if (faceRecognition.
profileID.has_value())
64 profileID = faceRecognition.
profileID.value();
69 <<
"Face recognition " + faceRecognitionID.
entityName +
70 " does not provide valid profileID, finding matching "
71 "personInstance is not possible.";
78 bool foundMatchingEntity =
false;
81 [&profileID, &personInstanceWriter, &faceRecognitionID, &foundMatchingEntity](
84 armarx::human::arondto::PersonInstance personInstance =
85 instance.
dataAs<armarx::human::arondto::PersonInstance>();
86 if (profileID.
entityName == personInstance.profileID.entityName)
89 toAron(personInstance.faceRecognitionID, faceRecognitionID);
93 update.instancesData = {personInstance.toAron()};
95 ARMARX_INFO <<
"Updated face recognition on personInstance '" +
98 foundMatchingEntity =
true;
102 if (foundMatchingEntity)
108 armarx::human::arondto::PersonInstance personInstance;
109 toAron(personInstance.faceRecognitionID, faceRecognitionID);
110 toAron(personInstance.profileID, profileID);
111 std::optional<armarx::armem::MemoryID> closestPoseID =
113 if (closestPoseID.has_value())
115 toAron(personInstance.poseID, closestPoseID.value());
118 if (faceRecognition.
profileID.value().entityName ==
"")
129 update.instancesData = {personInstance.toAron()};
131 ARMARX_INFO <<
"Created new personInstance for face recognition " +
166 std::optional<::armarx::armem::human::PersonInstance> matchingInstance = std::nullopt;
167 std::optional<::armarx::armem::MemoryID> matchingInstanceId = std::nullopt;
174 if (matchingInstance.has_value())
176 ARMARX_DEBUG <<
"Already got matching instance, returning";
180 armarx::human::arondto::PersonInstance personInstance =
181 instance.
dataAs<armarx::human::arondto::PersonInstance>();
183 fromAron(personInstance.poseID, currentPoseID);
184 auto pose = humanPoseFromMemId(currentPoseID, poseReader);
189 fromAron(personInstance.faceRecognitionID, currentRecognitionId);
192 faceRecognitionFromMemId(currentRecognitionId, faceRecognitionReader);
193 if (recognition.has_value())
196 if (checkForPlausability(humanPose, recognition.value()))
200 matchingInstance =
bo;
201 matchingInstanceId = instance.
id();
207 if (pose.has_value())
209 if (pose->humanTrackingId.has_value() or
213 <<
"A pose does not define a humanId. Unable to match...";
219 ARMARX_DEBUG <<
"Found matching poses based on humanId";
222 matchingInstance =
bo;
223 matchingInstanceId = instance.
id();
231 if (matchingInstance.has_value())
236 updateInstanceWithNewPoseId(matchingInstanceId.value(),
237 matchingInstance.value(),
239 personInstanceWriter);
243 ARMARX_DEBUG <<
"No matching instance found, creating new...";
244 createNewInstanceBasedOnPose(poseID, humanPose, mns);
262 UpdateConsumer::removePoseFromPersonInstance(
268 armarx::human::arondto::PersonInstance dto;
271 .instancesData = {dto.toAron()},
274 <<
"Removing pose from PersonInstance: " << personInstanceId.
entityName;
287 std::optional<armarx::FramedPosition> headPos = getHeadPos(pose);
288 if (headPos.has_value())
290 std::optional<armarx::armem::MemoryID> faceRecognitionID =
291 getClosestFaceID(headPos.value(), mns);
292 if (faceRecognitionID.has_value())
294 armarx::human::arondto::PersonInstance personInstance;
295 toAron(personInstance.faceRecognitionID, faceRecognitionID.value());
299 auto faceRecognition =
300 faceRecognitionFromMemId(faceRecognitionID.value(), faceRecognitionReader);
301 if (not faceRecognition.has_value())
307 const auto profileId = faceRecognition->profileID;
308 if (not profileId.has_value())
310 ARMARX_INFO <<
"While creating a new instance based on pose: closest face "
311 "recognition has no attached profile. Giving up.";
315 const std::string& entityName = profileId->entityName;
318 toAron(personInstance.profileID, profileId.value());
322 toAron(personInstance.poseID, poseId);
328 update.instancesData = {personInstance.toAron()};
352 oldInstance.
poseID = newPoseId;
353 armarx::human::arondto::PersonInstance dto;
357 .instancesData = {dto.toAron()},
362 ARMARX_DEBUG <<
"Committing new person instance with updated pose for entity: "
372 auto facePosFromPose = getHeadPos(pose);
373 if (not facePosFromPose.has_value())
379 float dist = getDistance(facePosFromFaceRecognition, facePosFromPose.value());
381 return dist <= maxFaceHeadDistance;
384 std::optional<armarx::armem::MemoryID>
393 float closestDistance = maxFaceHeadDistance;
398 [&facePos, &closestPoseID, &closestDistance](
401 armarx::human::arondto::HumanPose dto =
402 instance.
dataAs<armarx::human::arondto::HumanPose>();
405 std::optional<armarx::FramedPosition> headPos_opt = getHeadPos(pose);
406 if (headPos_opt.has_value())
409 float distance = getDistance(facePos, headPos);
412 closestPoseID = instance.
id();
418 return closestPoseID;
421 std::optional<armarx::armem::MemoryID>
430 std::optional<armarx::armem::MemoryID> closestFaceID = std::nullopt;
431 float closestDistance = maxFaceHeadDistance;
436 [&headPos, &closestFaceID, &closestDistance](
439 armarx::human::arondto::FaceRecognition dto =
440 instance.
dataAs<armarx::human::arondto::FaceRecognition>();
444 float distance = getDistance(faceRecognition.position3DGlobal, headPos);
447 closestFaceID = instance.
id();
452 return closestFaceID;
461 currentInstance.
poseID = poseId;
462 armarx::human::arondto::PersonInstance dto;
463 toAron(dto, currentInstance);
466 .instancesData = {dto.toAron()},
474 std::optional<armarx::armem::human::FaceRecognition>
488 auto result = recognitionReader.
query(qb);
489 if (not result.success)
494 std::optional<armarx::armem::human::FaceRecognition> resFace = std::nullopt;
495 result.memory.forEachInstance(
498 auto recognition = instance.
dataAs<armarx::human::arondto::FaceRecognition>();
504 if (not resFace.has_value())
511 std::optional<armarx::armem::human::HumanPose>
524 auto result = poseReader.
query(qb);
525 if (not result.success)
530 std::optional<armarx::armem::human::HumanPose> resPose;
531 result.memory.forEachInstance(
534 auto pose = instance.
dataAs<armarx::human::arondto::HumanPose>();
541 if (not resPose.has_value())
548 std::optional<armarx::FramedPosition>
551 std::optional<armarx::FramedPosition> headPos;
577 return sqrt(facePos.x() * headPos.x + facePos.y() * headPos.y + facePos.z() * headPos.z);