29 #include <unordered_map>
35 #include <ArmarXCore/interface/observers/ObserverInterface.h>
36 #include <ArmarXCore/interface/observers/VariantBase.h>
54 defineOptionalProperty<int>(
55 "MaxHistorySize", 5000,
"Maximum number of entries in the Observer history");
56 defineOptionalProperty<float>(
"MaxHistoryRecordFrequency",
58 "The Observer history is written with this maximum "
59 "frequency. Everything faster is being skipped.");
60 defineOptionalProperty<bool>(
61 "CreateUpdateFrequenciesChannel",
63 "If true, an additional channel is created that shows the update frequency of "
64 "every other channel in that observer.");
85 virtual public ObserverInterface,
95 std::string getObserverName()
const;
96 void getObserverName_async(
const AMD_ObserverInterface_getObserverNamePtr& amd,
97 const Ice::Current&)
const override;
109 CheckIdentifier installCheck(
const CheckConfiguration& configuration);
110 void installCheck_async(
const AMD_ObserverInterface_installCheckPtr& amd,
111 const CheckConfiguration& configuration,
112 const Ice::Current&)
override;
121 void removeCheck(
const CheckIdentifier&
id);
122 void removeCheck_async(
const AMD_ObserverInterface_removeCheckPtr& amd,
123 const CheckIdentifier&
id,
124 const Ice::Current&)
override;
135 const Ice::Current&
c = Ice::emptyCurrent)
const;
136 void getDataField_async(
const AMD_ObserverInterface_getDataFieldPtr& amd,
138 const Ice::Current&
c)
const override;
141 TimedVariantBasePtr getDatafieldByName(
const std::string& channelName,
142 const std::string& datafieldName)
const;
143 void getDatafieldByName_async(
const AMD_ObserverInterface_getDatafieldByNamePtr& amd,
144 const std::string& channelName,
145 const std::string& datafieldName,
146 const Ice::Current&)
const override;
150 void getDataFieldRef_async(
const AMD_ObserverInterface_getDataFieldRefPtr& amd,
152 const Ice::Current&)
const override;
155 DatafieldRefBasePtr getDatafieldRefByName(
const std::string& channelName,
156 const std::string& datafieldName)
const;
157 void getDatafieldRefByName_async(
const AMD_ObserverInterface_getDatafieldRefByNamePtr& amd,
158 const std::string& channelName,
159 const std::string& datafieldName,
160 const Ice::Current&)
const override;
171 const Ice::Current&
c);
172 void getDataFields_async(
const AMD_ObserverInterface_getDataFieldsPtr& amd,
174 const Ice::Current&
c)
override;
177 StringTimedVariantBaseMap getDatafieldsOfChannel(
const std::string& channelName)
const;
179 getDatafieldsOfChannel_async(
const AMD_ObserverInterface_getDatafieldsOfChannelPtr& amd,
180 const std::string& channelName,
181 const Ice::Current&)
const override;
191 ChannelRegistryEntry getChannel(
const std::string& channelName)
const;
192 void getChannel_async(
const AMD_ObserverInterface_getChannelPtr& amd,
193 const std::string& channelName,
194 const Ice::Current&)
const override;
204 ChannelRegistry getAvailableChannels(
bool includeMetaChannels);
205 void getAvailableChannels_async(
const AMD_ObserverInterface_getAvailableChannelsPtr& amd,
206 bool includeMetaChannels,
207 const Ice::Current&)
override;
217 StringConditionCheckMap getAvailableChecks();
218 void getAvailableChecks_async(
const AMD_ObserverInterface_getAvailableChecksPtr& amd,
219 const Ice::Current&)
override;
223 bool existsChannel(
const std::string& channelName)
const;
224 void existsChannel_async(
const AMD_ObserverInterface_existsChannelPtr& amd,
225 const std::string& channelName,
226 const Ice::Current&)
const override;
229 bool existsDataField(
const std::string& channelName,
230 const std::string& datafieldName)
const;
231 void existsDataField_async(
const AMD_ObserverInterface_existsDataFieldPtr& amd,
232 const std::string& channelName,
233 const std::string& datafieldName,
234 const Ice::Current&)
const override;
245 DatafieldRefBasePtr createFilteredDatafield(
const DatafieldFilterBasePtr& filter,
246 const DatafieldRefBasePtr& datafieldRef);
248 createFilteredDatafield_async(
const AMD_ObserverInterface_createFilteredDatafieldPtr& amd,
249 const DatafieldFilterBasePtr& filter,
250 const DatafieldRefBasePtr& datafieldRef,
251 const Ice::Current&)
override;
254 DatafieldRefBasePtr createNamedFilteredDatafield(
const std::string& filterDatafieldName,
255 const DatafieldFilterBasePtr& filter,
256 const DatafieldRefBasePtr& datafieldRef);
257 void createNamedFilteredDatafield_async(
258 const AMD_ObserverInterface_createNamedFilteredDatafieldPtr& amd,
259 const std::string& filterDatafieldName,
260 const DatafieldFilterBasePtr& filter,
261 const DatafieldRefBasePtr& datafieldRef,
262 const Ice::Current&)
override;
270 void removeFilteredDatafield(
const DatafieldRefBasePtr& datafieldRef);
272 removeFilteredDatafield_async(
const AMD_ObserverInterface_removeFilteredDatafieldPtr& amd,
273 const DatafieldRefBasePtr& datafieldRef,
274 const Ice::Current&)
override;
277 ChannelHistory getChannelHistory(
const std::string& channelName,
279 const Ice::Current&
c)
const;
280 void getChannelHistory_async(
const AMD_ObserverInterface_getChannelHistoryPtr& amd,
281 const std::string& channelName,
283 const Ice::Current&
c)
const override;
286 ChannelHistory getPartialChannelHistory(
const std::string& channelName,
290 const Ice::Current&
c)
const;
292 getPartialChannelHistory_async(
const AMD_ObserverInterface_getPartialChannelHistoryPtr& amd,
293 const std::string& channelName,
297 const Ice::Current&
c)
const override;
300 TimedVariantBaseList getDatafieldHistory(
const std::string& channelName,
301 const std::string& datafieldName,
303 const Ice::Current&
c)
const;
304 void getDatafieldHistory_async(
const AMD_ObserverInterface_getDatafieldHistoryPtr& amd,
305 const std::string& channelName,
306 const std::string& datafieldName,
308 const Ice::Current&
c)
const override;
311 TimedVariantBaseList getPartialDatafieldHistory(
const std::string& channelName,
312 const std::string& datafieldName,
316 const Ice::Current&
c)
const;
317 void getPartialDatafieldHistory_async(
318 const AMD_ObserverInterface_getPartialDatafieldHistoryPtr& amd,
319 const std::string& channelName,
320 const std::string& datafieldName,
324 const Ice::Current&
c)
const override;
338 void offerChannel(std::string channelName, std::string description);
350 void offerDataFieldWithDefault(std::string channelName,
351 std::string datafieldName,
353 std::string description);
365 void offerDataField(std::string channelName,
366 std::string datafieldName,
368 std::string description);
369 bool offerOrUpdateDataField(std::string channelName,
370 std::string datafieldName,
372 const std::string& description);
374 void offerOrUpdateDataFieldsFlatCopy(
const std::string& channelName,
384 void offerConditionCheck(std::string checkName,
ConditionCheck* conditionCheck);
396 void setDataField(
const std::string& channelName,
397 const std::string& datafieldName,
399 bool triggerFilterUpdate =
true);
400 void setDataFieldFlatCopy(
const std::string& channelName,
401 const std::string& datafieldName,
403 bool triggerFilterUpdate =
true);
404 void setDataFieldsFlatCopy(
const std::string& channelName,
406 bool triggerFilterUpdate =
true);
407 void setDataFieldsFlatCopy(
408 const std::string& channelName,
409 const std::unordered_map<::std::string, ::armarx::VariantBasePtr>& datafieldValues,
410 bool triggerFilterUpdate =
true);
411 void updateDatafieldTimestamps(
412 const std::string& channelName,
413 const std::unordered_map<std::string, Ice::Long>& datafieldValues);
414 void updateDatafieldTimestamps(
const std::string& channelName,
Ice::Long timestamp);
415 void maybeOfferChannelAndSetDataFieldsFlatCopy(
const std::string& channelName,
416 const std::string& description,
418 bool triggerFilterUpdate =
true);
428 updateChannel(
const std::string& channelName,
429 const std::set<std::string>& updatedDatafields = std::set<std::string>());
436 void removeChannel(std::string channelName);
440 std::set<std::string> updateDatafieldFilter(
const std::string& channelName,
441 const std::string& datafieldName,
444 void scheduleDatafieldFilterUpdate(
const std::string& channelName,
445 const std::string& datafieldName,
452 virtual void onInitObserver() = 0;
457 virtual void onConnectObserver() = 0;
467 void metaUpdateTask();
473 void setDataFieldFlatCopy(
const DataFieldRegistry::iterator& dataFieldIter,
481 const ChannelRegistryEntry& channel)
const;
485 getDefaultName()
const override
492 void onInitComponent()
override;
493 void postOnConnectComponent()
override;
494 void onConnectComponent()
override;
495 void preOnDisconnectComponent()
override;
496 void onExitComponent()
override;
498 void updateRefreshRateChannel(
const std::string& channelName);
500 void channelUpdateFunction();
501 void doChannelUpdate(
const std::string& channelName,
502 const std::set<std::string>& updatedDatafields);
504 void updateFilters();
506 void addToChannelHistory(
const std::pair<IceUtil::Time, ChannelRegistryEntry>& historyEntry,
507 const std::string& channelName);
510 void addWorkerJob(
const std::string& name, std::function<
void(
void)>&& f)
const;
511 void addWorkerJob(
const std::string& name, std::function<
void(
void)>&& f);
520 catch (std::exception& e)
523 amd->ice_exception(e);
529 amd->ice_exception(std::runtime_error{std::move(
s)});
534 template <
class... Params>
536 internalAddWorkerJob(
const std::string& name,
540 const Params&... ps)
const
544 [
this, derivedPtr, amd, fnc, params = std::make_tuple(ps...)]
546 callAndPassExceptionToAMD(
550 auto lambda = [&](auto&&... ps2)
551 { return (derivedPtr->*fnc)(std::move(ps2)...); };
552 using return_t = decltype(std::apply(lambda, params));
553 if constexpr (std::is_same_v<void, return_t>)
556 std::apply(lambda, params);
561 amd->ice_response(std::apply(lambda, params));
568 template <
class AMDPtr,
class FReturn,
class FOwner,
class... FParams,
class... Params>
572 FReturn (FOwner::*fnc)(FParams...)
const,
573 const Params&... ps)
const
575 static_assert(std::is_base_of_v<Observer, FOwner>);
576 internalAddWorkerJob(name,
dynamic_cast<const FOwner*
>(
this), amd, fnc, ps...);
579 template <
class AMDPtr,
class FReturn,
class FOwner,
class... FParams,
class... Params>
583 FReturn (FOwner::*fnc)(FParams...),
586 static_assert(std::is_base_of_v<Observer, FOwner>);
587 internalAddWorkerJob(name,
dynamic_cast<FOwner*
>(
this), amd, fnc, ps...);
590 virtual void preWorkerJobs();
591 virtual void postWorkerJobs();
592 using ClockT = std::chrono::high_resolution_clock;
603 std::unique_ptr<Impl>
impl;