64 def->optional(properties.updateConsumer.maxFaceHeadDistance,
"maxFaceHeadDistance");
65 def->optional(properties.updateConsumer.enableBodyTracking,
67 "If false, body tracking (pose) data is ignored entirely. "
68 "PersonInstances are updated based on face detections only and their "
69 "poseID (and pose-derived global pose orientation) is left unset.");
71 def->optional(properties.faceRecognitionUpdateFrequency,
72 "faceRecognitionUpdateFrequency",
73 "Max rate [Hz] at which face recognition updates are processed. "
74 "Values <= 0 disable throttling (process every update).");
75 def->optional(properties.poseUpdateFrequency,
76 "poseUpdateFrequency",
77 "Max rate [Hz] at which pose updates are processed. "
78 "Values <= 0 disable throttling (process every update).");
91 this->updateConsumer =
92 std::make_unique<UpdateConsumer>(
memoryNameSystem(), properties.updateConsumer);
95 if (properties.faceRecognitionUpdateFrequency > 0.F)
97 faceRecognitionThrottler.emplace(properties.faceRecognitionUpdateFrequency);
99 if (properties.poseUpdateFrequency > 0.F)
101 poseThrottler.emplace(properties.poseUpdateFrequency);
104 faceRecognitionReader.emplace(
109 stopProcessing =
false;
110 processingThread = std::thread([
this] { processingLoop(); });
112 registerMemorySubscriptions();
119 for (
auto& handle : subscriptionHandles)
123 subscriptionHandles.clear();
127 std::lock_guard g{pendingMutex};
128 stopProcessing =
true;
130 pendingCondition.notify_all();
131 if (processingThread.joinable())
133 processingThread.join();
135 pendingFaceRecognitionIDs.clear();
136 pendingPoseIDs.clear();
138 faceRecognitionReader.reset();
141 faceRecognitionThrottler.reset();
142 poseThrottler.reset();
144 this->updateConsumer.reset();
148 PersonInstanceUpdater::processingLoop()
150 std::unique_lock lock{pendingMutex};
153 pendingCondition.wait(lock,
155 return stopProcessing or
156 not pendingFaceRecognitionIDs.empty() or
157 not pendingPoseIDs.empty();
166 const std::vector<armem::MemoryID> faceIDs = std::move(pendingFaceRecognitionIDs);
167 const std::vector<armem::MemoryID> poseIDs = std::move(pendingPoseIDs);
168 pendingFaceRecognitionIDs.clear();
169 pendingPoseIDs.clear();
176 if (not faceIDs.empty())
178 processFaceRecognitionUpdates(faceIDs);
180 if (not poseIDs.empty())
182 processPoseUpdates(poseIDs);
185 catch (
const std::exception& e)
188 <<
"Exception while processing memory updates: " << e.what();
193 <<
"Unknown exception while processing memory updates.";
200 PersonInstanceUpdater::processFaceRecognitionUpdates(
201 const std::vector<armem::MemoryID>& updatedSnapshotIDs)
204 armem::client::QueryResult result =
205 faceRecognitionReader->queryMemoryIDs(updatedSnapshotIDs);
212 armarx::human::arondto::FaceRecognition>& instance)
215 armarx::armem::human::FaceRecognition faceRecognition;
216 fromAron(instance.data(), faceRecognition);
219 updateConsumer->consumeFaceRecognitionUpdate(faceRecognition, instance.id());
225 PersonInstanceUpdater::processPoseUpdates(
226 const std::vector<armem::MemoryID>& updatedSnapshotIDs)
229 armem::client::QueryResult result = poseReader->queryMemoryIDs(updatedSnapshotIDs);
238 armarx::armem::human::HumanPose humanPose;
242 updateConsumer->consumePoseUpdate(humanPose, instance.
id());
253 PersonInstanceUpdater::registerMemorySubscriptions()
265 auto faceRecognitionCallback =
266 [
this](
const std::vector<armem::MemoryID>& updatedSnapshotIDs)
269 if (faceRecognitionThrottler.has_value() and
276 std::lock_guard g{pendingMutex};
278 pendingFaceRecognitionIDs = updatedSnapshotIDs;
280 pendingCondition.notify_one();
295 if (properties.updateConsumer.enableBodyTracking)
300 auto poseCallback = [
this](
const std::vector<armem::MemoryID>& updatedSnapshotIDs)
303 if (poseThrottler.has_value() and
310 std::lock_guard g{pendingMutex};
311 pendingPoseIDs = updatedSnapshotIDs;
313 pendingCondition.notify_one();
316 subscriptionHandles.push_back(
325 armem::client::Reader profileReader =
328 auto profileCallback =
329 [
this, profileReader](
const std::vector<armem::MemoryID>& updatedSnapshotIDs)
332 armem::client::QueryResult result =
339 { updateConsumer->consumeProfileUpdate(instance.
data(), instance.
id()); });
343 subscriptionHandles.push_back(
SpamFilterDataPtr deactivateSpam(float deactivationDurationSec=10.0f, const std::string &identifier="", bool deactivate=true) const
disables the logging for the current line for the given amount of seconds.