Observer.h
Go to the documentation of this file.
1 /*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5 *
6 * ArmarX is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ArmarX is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * @package ArmarX::Core
19 * @author Kai Welke (welke@kit.edu)
20 * @date 2011
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24 
25 #pragma once
26 
27 #include <functional>
28 #include <mutex>
29 #include <unordered_map>
30 
35 #include <ArmarXCore/interface/observers/ObserverInterface.h>
36 #include <ArmarXCore/interface/observers/VariantBase.h>
38 
39 namespace armarx
40 {
41 
42  class DatafieldRef;
44 
45  /**
46  * \class DebugObserverPropertyDefinitions
47  * \brief
48  */
50  {
51  public:
53  {
54  defineOptionalProperty<int>(
55  "MaxHistorySize", 5000, "Maximum number of entries in the Observer history");
56  defineOptionalProperty<float>("MaxHistoryRecordFrequency",
57  50.f,
58  "The Observer history is written with this maximum "
59  "frequency. Everything faster is being skipped.");
60  defineOptionalProperty<bool>(
61  "CreateUpdateFrequenciesChannel",
62  false,
63  "If true, an additional channel is created that shows the update frequency of "
64  "every other channel in that observer.");
65  }
66  };
67 
68  /**
69  @class Observer
70  @brief Baseclass for all ArmarX Observers
71  @ingroup ObserversGrp
72 
73  A subclass of the observer should implement the two framework hooks onInitObserver and onConnectObserver.
74  The onInitObserver method should register all channels, datafields, and available condition checks
75  (see offerChannel, offerDattField, offerCheck).
76  Further, a subclass should implement a SensorActorUnitListener Ice interface.
77  Each interface method should correspond to one channel.
78  The observer should map the actual sensor values to the observer superclass
79  using the dataField method.
80  Finally, after all values have been updated, the updateChannel method needs
81  to be called in order to verify all currently active conditions and
82  generate associated events.
83  */
85  virtual public ObserverInterface,
86  virtual public Component
87  {
88  // ////////////////////////////////////////////////////////////////// //
89  // ice interface + local ice doubles
90  public:
91  Observer();
92 
93  ~Observer();
94 
95  std::string getObserverName() const;
96  void getObserverName_async(const AMD_ObserverInterface_getObserverNamePtr& amd,
97  const Ice::Current&) const override;
98 
99  public:
100  /**
101  * Installs a condition check with the observer
102  *
103  * @param configuration configuration of the check
104  * @param listener literal of the conditional expression that is associated with this check
105  * @param c ice context
106  * @throw InvalidConditionException
107  * @return identifier of installed condition as required for removal (see removeCondition)
108  */
109  CheckIdentifier installCheck(const CheckConfiguration& configuration);
110  void installCheck_async(const AMD_ObserverInterface_installCheckPtr& amd,
111  const CheckConfiguration& configuration,
112  const Ice::Current&) override;
113 
114  public:
115  /**
116  * Removes a condition check from the observer. If the condition has already been removed, the function immidiately returns.
117  *
118  * @param id identifier of installed condition
119  * @param c ice context
120  */
121  void removeCheck(const CheckIdentifier& id);
122  void removeCheck_async(const AMD_ObserverInterface_removeCheckPtr& amd,
123  const CheckIdentifier& id,
124  const Ice::Current&) override;
125 
126  public:
127  /**
128  * Retrieve data field from observer
129  * @param identifier Identifier of datafield
130  * @param c ice context
131  *
132  * @return timestamped variant corresponding to the data field
133  */
134  TimedVariantBasePtr getDataField(const DataFieldIdentifierBasePtr& identifier,
135  const Ice::Current& c = Ice::emptyCurrent) const;
136  void getDataField_async(const AMD_ObserverInterface_getDataFieldPtr& amd,
137  const DataFieldIdentifierBasePtr& identifier,
138  const Ice::Current& c) const override;
139 
140  public:
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;
147 
148  public:
149  DatafieldRefBasePtr getDataFieldRef(const DataFieldIdentifierBasePtr& identifier) const;
150  void getDataFieldRef_async(const AMD_ObserverInterface_getDataFieldRefPtr& amd,
151  const DataFieldIdentifierBasePtr& identifier,
152  const Ice::Current&) const override;
153 
154  public:
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;
161 
162  public:
163  /**
164  * Retrieve list of data field from observer
165  * @param identifier list of identifiers of datafield
166  * @param c ice context
167  *
168  * @return list of timestamped variants corresponding to the data fields given
169  */
170  TimedVariantBaseList getDataFields(const DataFieldIdentifierBaseList& identifiers,
171  const Ice::Current& c);
172  void getDataFields_async(const AMD_ObserverInterface_getDataFieldsPtr& amd,
174  const Ice::Current& c) override;
175 
176  public:
177  StringTimedVariantBaseMap getDatafieldsOfChannel(const std::string& channelName) const;
178  void
179  getDatafieldsOfChannel_async(const AMD_ObserverInterface_getDatafieldsOfChannelPtr& amd,
180  const std::string& channelName,
181  const Ice::Current&) const override;
182 
183 
184  public:
185  /**
186  * Retrieve information on all sensory data channels available from the observer.
187  * @param c ice context
188  *
189  * @return the ChannelRegistry contains information on each channel including its datafields and associated types and current values.
190  */
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;
195 
196 
197  public:
198  /**
199  * Retrieve information on all sensory data channels available from the observer.
200  * @param c ice context
201  *
202  * @return the ChannelRegistry contains information on each channel including its datafields and associated types and current values.
203  */
204  ChannelRegistry getAvailableChannels(bool includeMetaChannels);
205  void getAvailableChannels_async(const AMD_ObserverInterface_getAvailableChannelsPtr& amd,
206  bool includeMetaChannels,
207  const Ice::Current&) override;
208 
209 
210  public:
211  /**
212  * Retrieve list of available condition checks
213  * @param c ice context
214  *
215  * @return list of available condition checks
216  */
217  StringConditionCheckMap getAvailableChecks();
218  void getAvailableChecks_async(const AMD_ObserverInterface_getAvailableChecksPtr& amd,
219  const Ice::Current&) override;
220 
221 
222  public:
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;
227 
228  public:
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;
235 
236 
237  public:
238  /**
239  * @brief This function creates a new datafield with new filter on the given datafield.
240  * @param filter Configured filter object compatible with the datafieldRef (see \ref DatafieldFilter::getSupportedTypes())
241  * @param datafieldRef Datafield for which a filtered datafield should be created
242  * @return Returns a DatafieldRef to the new, filtered datafield.
243  * @see \ref removeFilteredDatafield()
244  */
245  DatafieldRefBasePtr createFilteredDatafield(const DatafieldFilterBasePtr& filter,
246  const DatafieldRefBasePtr& datafieldRef);
247  void
248  createFilteredDatafield_async(const AMD_ObserverInterface_createFilteredDatafieldPtr& amd,
249  const DatafieldFilterBasePtr& filter,
250  const DatafieldRefBasePtr& datafieldRef,
251  const Ice::Current&) override;
252 
253  public:
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;
263 
264  public:
265  /**
266  * @brief Removes a previously installed filter.
267  * @param datafieldRef Datafield that was returned by createFilteredDatafield()
268  * @see \ref createFilteredDatafield()
269  */
270  void removeFilteredDatafield(const DatafieldRefBasePtr& datafieldRef);
271  void
272  removeFilteredDatafield_async(const AMD_ObserverInterface_removeFilteredDatafieldPtr& amd,
273  const DatafieldRefBasePtr& datafieldRef,
274  const Ice::Current&) override;
275 
276  public:
277  ChannelHistory getChannelHistory(const std::string& channelName,
278  Ice::Float timestepMs,
279  const Ice::Current& c) const;
280  void getChannelHistory_async(const AMD_ObserverInterface_getChannelHistoryPtr& amd,
281  const std::string& channelName,
282  Ice::Float timestepMs,
283  const Ice::Current& c) const override;
284 
285  public:
286  ChannelHistory getPartialChannelHistory(const std::string& channelName,
287  Ice::Long startTimestamp,
288  Ice::Long endTimestamp,
289  Ice::Float timestepMs,
290  const Ice::Current& c) const;
291  void
292  getPartialChannelHistory_async(const AMD_ObserverInterface_getPartialChannelHistoryPtr& amd,
293  const std::string& channelName,
294  Ice::Long startTimestamp,
295  Ice::Long endTimestamp,
296  Ice::Float timestepMs,
297  const Ice::Current& c) const override;
298 
299  public:
300  TimedVariantBaseList getDatafieldHistory(const std::string& channelName,
301  const std::string& datafieldName,
302  Ice::Float timestepMs,
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,
307  Ice::Float timestepMs,
308  const Ice::Current& c) const override;
309 
310  public:
311  TimedVariantBaseList getPartialDatafieldHistory(const std::string& channelName,
312  const std::string& datafieldName,
313  Ice::Long startTimestamp,
314  Ice::Long endTimestamp,
315  Ice::Float timestepMs,
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,
321  Ice::Long startTimestamp,
322  Ice::Long endTimestamp,
323  Ice::Float timestepMs,
324  const Ice::Current& c) const override;
325 
326  // ////////////////////////////////////////////////////////////////// //
327  //internal functions
328  protected:
329  /**
330  * Offer a channel. Use this in an observer specialization.
331  *
332  * The channel is not initialized until updateChannel() was called once.
333  * @param channelName name of the channel
334  * @param description expressive description of the provided datafields
335  * @throw InvalidChannelException
336  * @see updateChannel()
337  */
338  void offerChannel(std::string channelName, std::string description);
339 
340  /**
341  * Offer a datafield with default value. Use this in an observer specialization.
342  *
343  * @param channelName name of the channel
344  * @param datafieldName name of the datafield
345  * @param defaultValue defines the default value and the datatype for the field
346  * @param description expressive description of the datafield
347  * @throw InvalidChannelException
348  * @throw InvalidDataFieldException
349  */
350  void offerDataFieldWithDefault(std::string channelName,
351  std::string datafieldName,
352  const Variant& defaultValue,
353  std::string description);
354 
355  /**
356  * Offer a datafield without default value. Use this in an observer specialization.
357  *
358  * @param channelName name of the channel
359  * @param datafieldName name of the datafield
360  * @param defaultValue defines the default value and the datatype for the field
361  * @param description expressive description of the datafield
362  * @throw InvalidChannelException
363  * @throw InvalidDataFieldException
364  */
365  void offerDataField(std::string channelName,
366  std::string datafieldName,
367  VariantTypeId type,
368  std::string description);
369  bool offerOrUpdateDataField(std::string channelName,
370  std::string datafieldName,
371  const Variant& value,
372  const std::string& description);
373 
374  void offerOrUpdateDataFieldsFlatCopy(const std::string& channelName,
375  const StringVariantBaseMap& valueMap);
376 
377  /**
378  * Offer a condition check. Use this in an observer specialization.
379  *
380  * @param checkName name of the check
381  * @param conditionCheck check to register under checkName
382  * @throw InvalidCheckException
383  */
384  void offerConditionCheck(std::string checkName, ConditionCheck* conditionCheck);
385 
386  /**
387  * set datafield with datafieldName and in channel channelName
388  *
389  * @param channelName name of the channel
390  * @param datafieldName name of the datafield within channel
391  * @param value value for datafield
392  * @throw InvalidChannelException
393  * @throw InvalidDataFieldException
394  * @return reference to Variant associated with the dataField
395  */
396  void setDataField(const std::string& channelName,
397  const std::string& datafieldName,
398  const Variant& value,
399  bool triggerFilterUpdate = true);
400  void setDataFieldFlatCopy(const std::string& channelName,
401  const std::string& datafieldName,
402  const VariantPtr& value,
403  bool triggerFilterUpdate = true);
404  void setDataFieldsFlatCopy(const std::string& channelName,
405  const StringVariantBaseMap& datafieldValues,
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,
417  const StringVariantBaseMap& datafieldValues,
418  bool triggerFilterUpdate = true);
419 
420  /**
421  * Update all conditions for a channel. Call this from the sensorActorUnit listener implementation if new data is posted.
422  *
423  * @param channelName name of the channel to update
424  * @param updatedDatafields List of datafields that were updated. If empty, all datafields are checked. Leave empty if you would give all datafields anyway (better performance).
425  * @throw InvalidChannelException
426  */
427  void
428  updateChannel(const std::string& channelName,
429  const std::set<std::string>& updatedDatafields = std::set<std::string>());
430 
431  /**
432  * Remove a channel. Use this in an observer specialization.
433  *
434  * @param channelName name of the channel
435  */
436  void removeChannel(std::string channelName);
437 
438  void removeDatafield(DataFieldIdentifierBasePtr id);
439 
440  std::set<std::string> updateDatafieldFilter(const std::string& channelName,
441  const std::string& datafieldName,
442  const VariantBasePtr& value);
443 
444  void scheduleDatafieldFilterUpdate(const std::string& channelName,
445  const std::string& datafieldName,
446  const VariantBasePtr& value);
447 
448 
449  /**
450  * Framework hook. Called once on initialization of the Observer.
451  */
452  virtual void onInitObserver() = 0;
453 
454  /**
455  * Framework hook. Called on first run, after ice setup.
456  */
457  virtual void onConnectObserver() = 0;
458 
459  /**
460  * Framework hook. Called on first run, after ice setup.
461  */
462  virtual void
464  {
465  }
466 
467  void metaUpdateTask();
468 
469  // utility methods
470  int generateId();
471 
472  private:
473  void setDataFieldFlatCopy(const DataFieldRegistry::iterator& dataFieldIter,
474  const VariantPtr& value);
475 
476 
477  // check handling
478  ConditionCheckPtr createCheck(const CheckConfiguration& configuration) const;
479  CheckIdentifier registerCheck(const ConditionCheckPtr& check);
480  void evaluateCheck(const ConditionCheckPtr& check,
481  const ChannelRegistryEntry& channel) const;
482 
483  // inherited from Component
484  std::string
485  getDefaultName() const override
486  {
487  return "Observer";
488  }
489 
490  PropertyDefinitionsPtr createPropertyDefinitions() override;
491 
492  void onInitComponent() override;
493  void postOnConnectComponent() override;
494  void onConnectComponent() override;
495  void preOnDisconnectComponent() override;
496  void onExitComponent() override;
497 
498  void updateRefreshRateChannel(const std::string& channelName);
499 
500  void channelUpdateFunction();
501  void doChannelUpdate(const std::string& channelName,
502  const std::set<std::string>& updatedDatafields);
503 
504  void updateFilters();
505 
506  void addToChannelHistory(const std::pair<IceUtil::Time, ChannelRegistryEntry>& historyEntry,
507  const std::string& channelName);
508 
509  protected:
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);
512 
513  void
514  callAndPassExceptionToAMD(auto& amd, auto f) const
515  {
516  try
517  {
518  f();
519  }
520  catch (std::exception& e)
521  {
523  amd->ice_exception(e);
524  }
525  catch (...)
526  {
527  auto s = GetHandledExceptionString();
528  ARMARX_ERROR << s;
529  amd->ice_exception(std::runtime_error{std::move(s)});
530  }
531  }
532 
533  private:
534  template <class... Params>
535  void
536  internalAddWorkerJob(const std::string& name,
537  auto* derivedPtr,
538  const auto& amd,
539  auto fnc,
540  const Params&... ps) const
541  {
542  ARMARX_CHECK_EXPRESSION(derivedPtr);
543  addWorkerJob(name,
544  [this, derivedPtr, amd, fnc, params = std::make_tuple(ps...)]
545  {
546  callAndPassExceptionToAMD(
547  amd,
548  [&]
549  {
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>)
554  {
555 
556  std::apply(lambda, params);
557  amd->ice_response();
558  }
559  else
560  {
561  amd->ice_response(std::apply(lambda, params));
562  }
563  });
564  });
565  }
566 
567  protected:
568  template <class AMDPtr, class FReturn, class FOwner, class... FParams, class... Params>
569  void
570  addWorkerJob(const std::string& name,
571  const AMDPtr& amd,
572  FReturn (FOwner::*fnc)(FParams...) const,
573  const Params&... ps) const
574  {
575  static_assert(std::is_base_of_v<Observer, FOwner>);
576  internalAddWorkerJob(name, dynamic_cast<const FOwner*>(this), amd, fnc, ps...);
577  }
578 
579  template <class AMDPtr, class FReturn, class FOwner, class... FParams, class... Params>
580  void
581  addWorkerJob(const std::string& name,
582  const AMDPtr& amd,
583  FReturn (FOwner::*fnc)(FParams...),
584  const Params&... ps)
585  {
586  static_assert(std::is_base_of_v<Observer, FOwner>);
587  internalAddWorkerJob(name, dynamic_cast<FOwner*>(this), amd, fnc, ps...);
588  }
589 
590  virtual void preWorkerJobs();
591  virtual void postWorkerJobs();
592  using ClockT = std::chrono::high_resolution_clock;
593  using TimepointT = typename ClockT::time_point;
594  static TimepointT Now();
595  static float TimeDeltaInMs(TimepointT t0);
596 
597  void runWorker();
598 
599  // This mutex is used by derived classes ...
600  mutable std::recursive_mutex channelsMutex;
601 
602  struct Impl;
603  std::unique_ptr<Impl> impl;
604  };
605 } // namespace armarx
armarx::Variant
The Variant class is described here: Variants.
Definition: Variant.h:223
armarx::Observer::Impl
Definition: Observer.cpp:47
armarx::VariantType::Float
const VariantTypeId Float
Definition: Variant.h:919
armarx::StringVariantBaseMap
std::map< std::string, VariantBasePtr > StringVariantBaseMap
Definition: ManagedIceObject.h:110
armarx::Observer
Baseclass for all ArmarX Observers.
Definition: Observer.h:84
armarx::Observer::ClockT
std::chrono::high_resolution_clock ClockT
Definition: Observer.h:592
armarx::PropertyDefinitionContainer::prefix
std::string prefix
Prefix of the properties such as namespace, domain, component name, etc.
Definition: PropertyDefinitionContainer.h:345
PeriodicTask.h
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:46
RunningTask.h
armarx::Observer::addWorkerJob
void addWorkerJob(const std::string &name, const AMDPtr &amd, FReturn(FOwner::*fnc)(FParams...), const Params &... ps)
Definition: Observer.h:581
IceInternal::Handle< DatafieldRef >
armarx::GetHandledExceptionString
std::string GetHandledExceptionString()
Definition: Exception.cpp:165
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:855
armarx::Observer::TimepointT
typename ClockT::time_point TimepointT
Definition: Observer.h:593
armarx::VariantType::Long
const VariantTypeId Long
Definition: Variant.h:918
armarx::Observer::addWorkerJob
void addWorkerJob(const std::string &name, const AMDPtr &amd, FReturn(FOwner::*fnc)(FParams...) const, const Params &... ps) const
Definition: Observer.h:570
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:196
armarx::VariantTypeId
Ice::Int VariantTypeId
Definition: Variant.h:43
armarx::ObserverPropertyDefinitions::ObserverPropertyDefinitions
ObserverPropertyDefinitions(std::string prefix)
Definition: Observer.h:52
Component.h
armarx::Component
Baseclass for all ArmarX ManagedIceObjects requiring properties.
Definition: Component.h:91
armarx::Observer::impl
std::unique_ptr< Impl > impl
Definition: Observer.h:602
armarx::ConditionCheck
Definition: ConditionCheck.h:54
armarx::VariantType::DatafieldRef
const VariantTypeId DatafieldRef
Definition: DatafieldRef.h:197
armarx::Observer::channelsMutex
std::recursive_mutex channelsMutex
Definition: Observer.h:600
ARMARX_CHECK_EXPRESSION
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
Definition: ExpressionException.h:73
armarx::ComponentPropertyDefinitions
Default component property definition container.
Definition: Component.h:69
ImportExport.h
armarx::Observer::onExitObserver
virtual void onExitObserver()
Framework hook.
Definition: Observer.h:463
ConditionCheck.h
ARMARXCORE_IMPORT_EXPORT
#define ARMARXCORE_IMPORT_EXPORT
Definition: ImportExport.h:38
armarx::DataFieldIdentifierBaseList
::std::vector<::armarx::DataFieldIdentifierBasePtr > DataFieldIdentifierBaseList
Definition: StatechartContextInterface.h:43
armarx::PropertyDefinitionsPtr
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
Definition: forward_declarations.h:35
armarx::ObserverPropertyDefinitions
Definition: Observer.h:49
armarx::ctrlutil::s
double s(double t, double s0, double v0, double a0, double j)
Definition: CtrlUtil.h:33
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
identifiers
const std::list< std::string > identifiers
Definition: linux_networkload.cpp:22
armarx::Observer::callAndPassExceptionToAMD
void callAndPassExceptionToAMD(auto &amd, auto f) const
Definition: Observer.h:514