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 
31 #include <ArmarXCore/interface/observers/VariantBase.h>
32 
33 #include <ArmarXCore/interface/observers/ObserverInterface.h>
35 
36 #include <unordered_map>
37 #include <functional>
38 #include <mutex>
39 
40 namespace armarx
41 {
42 
43  class DatafieldRef;
45 
46  /**
47  * \class DebugObserverPropertyDefinitions
48  * \brief
49  */
52  {
53  public:
56  {
57  defineOptionalProperty<int>("MaxHistorySize", 5000, "Maximum number of entries in the Observer history");
58  defineOptionalProperty<float>("MaxHistoryRecordFrequency", 50.f, "The Observer history is written with this maximum frequency. Everything faster is being skipped.");
59  defineOptionalProperty<bool>("CreateUpdateFrequenciesChannel", false, "If true, an additional channel is created that shows the update frequency of every other channel in that observer.");
60 
61  }
62  };
63 
64  /**
65  @class Observer
66  @brief Baseclass for all ArmarX Observers
67  @ingroup ObserversGrp
68 
69  A subclass of the observer should implement the two framework hooks onInitObserver and onConnectObserver.
70  The onInitObserver method should register all channels, datafields, and available condition checks
71  (see offerChannel, offerDattField, offerCheck).
72  Further, a subclass should implement a SensorActorUnitListener Ice interface.
73  Each interface method should correspond to one channel.
74  The observer should map the actual sensor values to the observer superclass
75  using the dataField method.
76  Finally, after all values have been updated, the updateChannel method needs
77  to be called in order to verify all currently active conditions and
78  generate associated events.
79  */
81  virtual public ObserverInterface,
82  virtual public Component
83  {
84  // ////////////////////////////////////////////////////////////////// //
85  // ice interface + local ice doubles
86  public:
87  Observer();
88 
89  ~Observer();
90 
91  std::string getObserverName() const;
92  void getObserverName_async(
93  const AMD_ObserverInterface_getObserverNamePtr& amd,
94  const Ice::Current&) const override;
95 
96  public:
97  /**
98  * Installs a condition check with the observer
99  *
100  * @param configuration configuration of the check
101  * @param listener literal of the conditional expression that is associated with this check
102  * @param c ice context
103  * @throw InvalidConditionException
104  * @return identifier of installed condition as required for removal (see removeCondition)
105  */
106  CheckIdentifier installCheck(const CheckConfiguration& configuration);
107  void installCheck_async(
108  const AMD_ObserverInterface_installCheckPtr& amd,
109  const CheckConfiguration& configuration,
110  const Ice::Current&) override;
111 
112  public:
113  /**
114  * Removes a condition check from the observer. If the condition has already been removed, the function immidiately returns.
115  *
116  * @param id identifier of installed condition
117  * @param c ice context
118  */
119  void removeCheck(const CheckIdentifier& id);
120  void removeCheck_async(
121  const AMD_ObserverInterface_removeCheckPtr& amd,
122  const CheckIdentifier& id,
123  const Ice::Current&) override;
124 
125  public:
126  /**
127  * Retrieve data field from observer
128  * @param identifier Identifier of datafield
129  * @param c ice context
130  *
131  * @return timestamped variant corresponding to the data field
132  */
133  TimedVariantBasePtr getDataField(
134  const DataFieldIdentifierBasePtr& identifier,
135  const Ice::Current& c = Ice::emptyCurrent) const;
136  void getDataField_async(
137  const AMD_ObserverInterface_getDataFieldPtr& amd,
138  const DataFieldIdentifierBasePtr& identifier,
139  const Ice::Current& c) const override;
140 
141  public:
142  TimedVariantBasePtr getDatafieldByName(
143  const std::string& channelName,
144  const std::string& datafieldName) const;
145  void getDatafieldByName_async(
146  const AMD_ObserverInterface_getDatafieldByNamePtr& amd,
147  const std::string& channelName,
148  const std::string& datafieldName,
149  const Ice::Current&) const override;
150 
151  public:
152  DatafieldRefBasePtr getDataFieldRef(
153  const DataFieldIdentifierBasePtr& identifier) const;
154  void getDataFieldRef_async(
155  const AMD_ObserverInterface_getDataFieldRefPtr& amd,
156  const DataFieldIdentifierBasePtr& identifier,
157  const Ice::Current&) const override;
158 
159  public:
160  DatafieldRefBasePtr getDatafieldRefByName(
161  const std::string& channelName,
162  const std::string& datafieldName) const;
163  void getDatafieldRefByName_async(
164  const AMD_ObserverInterface_getDatafieldRefByNamePtr& amd,
165  const std::string& channelName,
166  const std::string& datafieldName,
167  const Ice::Current&) const override;
168 
169  public:
170  /**
171  * Retrieve list of data field from observer
172  * @param identifier list of identifiers of datafield
173  * @param c ice context
174  *
175  * @return list of timestamped variants corresponding to the data fields given
176  */
177  TimedVariantBaseList getDataFields(
179  const Ice::Current& c);
180  void getDataFields_async(
181  const AMD_ObserverInterface_getDataFieldsPtr& amd,
183  const Ice::Current& c) override;
184 
185  public:
186  StringTimedVariantBaseMap getDatafieldsOfChannel(
187  const std::string& channelName) const;
188  void getDatafieldsOfChannel_async(
189  const AMD_ObserverInterface_getDatafieldsOfChannelPtr& amd,
190  const std::string& channelName,
191  const Ice::Current&) const override;
192 
193 
194 
195  public:
196  /**
197  * Retrieve information on all sensory data channels available from the observer.
198  * @param c ice context
199  *
200  * @return the ChannelRegistry contains information on each channel including its datafields and associated types and current values.
201  */
202  ChannelRegistryEntry getChannel(
203  const std::string& channelName) const;
204  void getChannel_async(
205  const AMD_ObserverInterface_getChannelPtr& amd,
206  const std::string& channelName,
207  const Ice::Current&) const override;
208 
209 
210  public:
211  /**
212  * Retrieve information on all sensory data channels available from the observer.
213  * @param c ice context
214  *
215  * @return the ChannelRegistry contains information on each channel including its datafields and associated types and current values.
216  */
217  ChannelRegistry getAvailableChannels(
218  bool includeMetaChannels);
219  void getAvailableChannels_async(
220  const AMD_ObserverInterface_getAvailableChannelsPtr& amd,
221  bool includeMetaChannels,
222  const Ice::Current&) override;
223 
224 
225  public:
226  /**
227  * Retrieve list of available condition checks
228  * @param c ice context
229  *
230  * @return list of available condition checks
231  */
232  StringConditionCheckMap getAvailableChecks();
233  void getAvailableChecks_async(
234  const AMD_ObserverInterface_getAvailableChecksPtr& amd,
235  const Ice::Current&) override;
236 
237 
238  public:
239  bool existsChannel(
240  const std::string& channelName) const;
241  void existsChannel_async(
242  const AMD_ObserverInterface_existsChannelPtr& amd,
243  const std::string& channelName,
244  const Ice::Current&) const override;
245 
246  public:
247  bool existsDataField(
248  const std::string& channelName,
249  const std::string& datafieldName) const;
250  void existsDataField_async(
251  const AMD_ObserverInterface_existsDataFieldPtr& amd,
252  const std::string& channelName,
253  const std::string& datafieldName,
254  const Ice::Current&) const override;
255 
256 
257  public:
258  /**
259  * @brief This function creates a new datafield with new filter on the given datafield.
260  * @param filter Configured filter object compatible with the datafieldRef (see \ref DatafieldFilter::getSupportedTypes())
261  * @param datafieldRef Datafield for which a filtered datafield should be created
262  * @return Returns a DatafieldRef to the new, filtered datafield.
263  * @see \ref removeFilteredDatafield()
264  */
265  DatafieldRefBasePtr createFilteredDatafield(
266  const DatafieldFilterBasePtr& filter,
267  const DatafieldRefBasePtr& datafieldRef);
268  void createFilteredDatafield_async(
269  const AMD_ObserverInterface_createFilteredDatafieldPtr& amd,
270  const DatafieldFilterBasePtr& filter,
271  const DatafieldRefBasePtr& datafieldRef,
272  const Ice::Current&) override;
273 
274  public:
275  DatafieldRefBasePtr createNamedFilteredDatafield(
276  const std::string& filterDatafieldName,
277  const DatafieldFilterBasePtr& filter,
278  const DatafieldRefBasePtr& datafieldRef);
279  void createNamedFilteredDatafield_async(
280  const AMD_ObserverInterface_createNamedFilteredDatafieldPtr& amd,
281  const std::string& filterDatafieldName,
282  const DatafieldFilterBasePtr& filter,
283  const DatafieldRefBasePtr& datafieldRef,
284  const Ice::Current&) override;
285 
286  public:
287  /**
288  * @brief Removes a previously installed filter.
289  * @param datafieldRef Datafield that was returned by createFilteredDatafield()
290  * @see \ref createFilteredDatafield()
291  */
292  void removeFilteredDatafield(
293  const DatafieldRefBasePtr& datafieldRef);
294  void removeFilteredDatafield_async(
295  const AMD_ObserverInterface_removeFilteredDatafieldPtr& amd,
296  const DatafieldRefBasePtr& datafieldRef,
297  const Ice::Current&) override;
298 
299  public:
300  ChannelHistory getChannelHistory(
301  const std::string& channelName,
302  Ice::Float timestepMs,
303  const Ice::Current& c) const;
304  void getChannelHistory_async(
305  const AMD_ObserverInterface_getChannelHistoryPtr& amd,
306  const std::string& channelName,
307  Ice::Float timestepMs,
308  const Ice::Current& c) const override;
309 
310  public:
311  ChannelHistory getPartialChannelHistory(
312  const std::string& channelName,
313  Ice::Long startTimestamp,
314  Ice::Long endTimestamp,
315  Ice::Float timestepMs,
316  const Ice::Current& c) const;
317  void getPartialChannelHistory_async(
318  const AMD_ObserverInterface_getPartialChannelHistoryPtr& amd,
319  const std::string& channelName,
320  Ice::Long startTimestamp,
321  Ice::Long endTimestamp,
322  Ice::Float timestepMs,
323  const Ice::Current& c) const override;
324 
325  public:
326  TimedVariantBaseList getDatafieldHistory(
327  const std::string& channelName,
328  const std::string& datafieldName,
329  Ice::Float timestepMs,
330  const Ice::Current& c) const;
331  void getDatafieldHistory_async(
332  const AMD_ObserverInterface_getDatafieldHistoryPtr& amd,
333  const std::string& channelName,
334  const std::string& datafieldName,
335  Ice::Float timestepMs,
336  const Ice::Current& c) const override;
337 
338  public:
339  TimedVariantBaseList getPartialDatafieldHistory(
340  const std::string& channelName,
341  const std::string& datafieldName,
342  Ice::Long startTimestamp,
343  Ice::Long endTimestamp,
344  Ice::Float timestepMs,
345  const Ice::Current& c) const;
346  void getPartialDatafieldHistory_async(
347  const AMD_ObserverInterface_getPartialDatafieldHistoryPtr& amd,
348  const std::string& channelName,
349  const std::string& datafieldName,
350  Ice::Long startTimestamp,
351  Ice::Long endTimestamp,
352  Ice::Float timestepMs,
353  const Ice::Current& c) const override;
354 
355  // ////////////////////////////////////////////////////////////////// //
356  //internal functions
357  protected:
358  /**
359  * Offer a channel. Use this in an observer specialization.
360  *
361  * The channel is not initialized until updateChannel() was called once.
362  * @param channelName name of the channel
363  * @param description expressive description of the provided datafields
364  * @throw InvalidChannelException
365  * @see updateChannel()
366  */
367  void offerChannel(std::string channelName, std::string description);
368 
369  /**
370  * Offer a datafield with default value. Use this in an observer specialization.
371  *
372  * @param channelName name of the channel
373  * @param datafieldName name of the datafield
374  * @param defaultValue defines the default value and the datatype for the field
375  * @param description expressive description of the datafield
376  * @throw InvalidChannelException
377  * @throw InvalidDataFieldException
378  */
379  void offerDataFieldWithDefault(std::string channelName, std::string datafieldName, const Variant& defaultValue, std::string description);
380 
381  /**
382  * Offer a datafield without default value. Use this in an observer specialization.
383  *
384  * @param channelName name of the channel
385  * @param datafieldName name of the datafield
386  * @param defaultValue defines the default value and the datatype for the field
387  * @param description expressive description of the datafield
388  * @throw InvalidChannelException
389  * @throw InvalidDataFieldException
390  */
391  void offerDataField(std::string channelName, std::string datafieldName, VariantTypeId type, std::string description);
392  bool offerOrUpdateDataField(std::string channelName, std::string datafieldName, const Variant& value, const std::string& description);
393 
394  void offerOrUpdateDataFieldsFlatCopy(const std::string& channelName, const StringVariantBaseMap& valueMap);
395 
396  /**
397  * Offer a condition check. Use this in an observer specialization.
398  *
399  * @param checkName name of the check
400  * @param conditionCheck check to register under checkName
401  * @throw InvalidCheckException
402  */
403  void offerConditionCheck(std::string checkName, ConditionCheck* conditionCheck);
404 
405  /**
406  * set datafield with datafieldName and in channel channelName
407  *
408  * @param channelName name of the channel
409  * @param datafieldName name of the datafield within channel
410  * @param value value for datafield
411  * @throw InvalidChannelException
412  * @throw InvalidDataFieldException
413  * @return reference to Variant associated with the dataField
414  */
415  void setDataField(const std::string& channelName, const std::string& datafieldName, const Variant& value, bool triggerFilterUpdate = true);
416  void setDataFieldFlatCopy(const std::string& channelName, const std::string& datafieldName, const VariantPtr& value, bool triggerFilterUpdate = true);
417  void setDataFieldsFlatCopy(const std::string& channelName, const StringVariantBaseMap& datafieldValues, bool triggerFilterUpdate = true);
418  void setDataFieldsFlatCopy(const std::string& channelName, const std::unordered_map< ::std::string, ::armarx::VariantBasePtr>& datafieldValues, bool triggerFilterUpdate = true);
419  void updateDatafieldTimestamps(const std::string& channelName, const std::unordered_map<std::string, Ice::Long>& datafieldValues);
420  void updateDatafieldTimestamps(const std::string& channelName, Ice::Long timestamp);
421  void maybeOfferChannelAndSetDataFieldsFlatCopy(
422  const std::string& channelName,
423  const std::string& description,
424  const StringVariantBaseMap& datafieldValues,
425  bool triggerFilterUpdate = true);
426 
427  /**
428  * Update all conditions for a channel. Call this from the sensorActorUnit listener implementation if new data is posted.
429  *
430  * @param channelName name of the channel to update
431  * @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).
432  * @throw InvalidChannelException
433  */
434  void updateChannel(const std::string& channelName, const std::set<std::string>& updatedDatafields = std::set<std::string>());
435 
436  /**
437  * Remove a channel. Use this in an observer specialization.
438  *
439  * @param channelName name of the channel
440  */
441  void removeChannel(std::string channelName);
442 
443  void removeDatafield(DataFieldIdentifierBasePtr id);
444 
445  std::set<std::string> updateDatafieldFilter(const std::string& channelName, const std::string& datafieldName, const VariantBasePtr& value);
446 
447  void scheduleDatafieldFilterUpdate(const std::string& channelName, const std::string& datafieldName, const VariantBasePtr& value);
448 
449 
450 
451  /**
452  * Framework hook. Called once on initialization of the Observer.
453  */
454  virtual void onInitObserver() = 0;
455 
456  /**
457  * Framework hook. Called on first run, after ice setup.
458  */
459  virtual void onConnectObserver() = 0;
460 
461  /**
462  * Framework hook. Called on first run, after ice setup.
463  */
464  virtual void onExitObserver() {}
465 
466  void metaUpdateTask();
467 
468  // utility methods
469  int generateId();
470 
471  private:
472  void setDataFieldFlatCopy(const DataFieldRegistry::iterator& dataFieldIter, const VariantPtr& value);
473 
474 
475  // check handling
476  ConditionCheckPtr createCheck(const CheckConfiguration& configuration) const;
477  CheckIdentifier registerCheck(const ConditionCheckPtr& check);
478  void evaluateCheck(const ConditionCheckPtr& check, const ChannelRegistryEntry& channel) const;
479 
480  // inherited from Component
481  std::string getDefaultName() const override
482  {
483  return "Observer";
484  }
485 
486  PropertyDefinitionsPtr createPropertyDefinitions() override;
487 
488  void onInitComponent() override;
489  void postOnConnectComponent() override;
490  void onConnectComponent() override;
491  void preOnDisconnectComponent() override;
492  void onExitComponent() override;
493 
494  void updateRefreshRateChannel(const std::string& channelName);
495 
496  void channelUpdateFunction();
497  void doChannelUpdate(const std::string& channelName, const std::set<std::string>& updatedDatafields);
498 
499  void updateFilters();
500 
501  void addToChannelHistory(const std::pair<IceUtil::Time, ChannelRegistryEntry>& historyEntry, const std::string& channelName);
502 
503  protected:
504  void addWorkerJob(const std::string& name, std::function<void(void)>&& f) const;
505  void addWorkerJob(const std::string& name, std::function<void(void)>&& f);
506  void callAndPassExceptionToAMD(auto& amd, auto f) const
507  {
508  try
509  {
510  f();
511  }
512  catch (std::exception& e)
513  {
515  amd->ice_exception(e);
516  }
517  catch (...)
518  {
519  auto s = GetHandledExceptionString();
520  ARMARX_ERROR << s;
521  amd->ice_exception(std::runtime_error{std::move(s)});
522  }
523  }
524  private:
525  template<class...Params>
526  void internalAddWorkerJob(const std::string& name,
527  auto* derivedPtr,
528  const auto& amd,
529  auto fnc,
530  const Params& ...ps) const
531  {
532  ARMARX_CHECK_EXPRESSION(derivedPtr);
533  addWorkerJob(name, [this, derivedPtr, amd, fnc, params = std::make_tuple(ps...)]
534  {
535  callAndPassExceptionToAMD(amd, [&]
536  {
537  auto lambda = [&](auto&& ...ps2)
538  {
539  return (derivedPtr->*fnc)(std::move(ps2)...);
540  };
541  using return_t = decltype(std::apply(lambda, params));
542  if constexpr(std::is_same_v<void, return_t>)
543  {
544 
545  std::apply(lambda, params);
546  amd->ice_response();
547  }
548  else
549  {
550  amd->ice_response(std::apply(lambda, params));
551  }
552  });
553  });
554  }
555 
556  protected:
557  template<class AMDPtr, class FReturn, class FOwner, class...FParams, class...Params>
558  void addWorkerJob(const std::string& name,
559  const AMDPtr& amd,
560  FReturn(FOwner::*fnc)(FParams...) const,
561  const Params& ...ps) const
562  {
563  static_assert(std::is_base_of_v<Observer, FOwner>);
564  internalAddWorkerJob(name, dynamic_cast<const FOwner*>(this), amd, fnc, ps...);
565  }
566  template<class AMDPtr, class FReturn, class FOwner, class...FParams, class...Params>
567  void addWorkerJob(const std::string& name,
568  const AMDPtr& amd,
569  FReturn(FOwner::*fnc)(FParams...),
570  const Params& ...ps)
571  {
572  static_assert(std::is_base_of_v<Observer, FOwner>);
573  internalAddWorkerJob(name, dynamic_cast<FOwner*>(this), amd, fnc, ps...);
574  }
575 
576  virtual void preWorkerJobs();
577  virtual void postWorkerJobs();
578  using ClockT = std::chrono::high_resolution_clock;
579  using TimepointT = typename ClockT::time_point;
580  static TimepointT Now();
581  static float TimeDeltaInMs(TimepointT t0);
582 
583  void runWorker();
584 
585  // This mutex is used by derived classes ...
586  mutable std::recursive_mutex channelsMutex;
587 
588  struct Impl;
589  std::unique_ptr<Impl> impl;
590  };
591 }
592 
armarx::Variant
The Variant class is described here: Variants.
Definition: Variant.h:224
armarx::DataFieldIdentifierBaseList
::std::vector< ::armarx::DataFieldIdentifierBasePtr > DataFieldIdentifierBaseList
Definition: StatechartContextInterface.h:43
armarx::Observer::Impl
Definition: Observer.cpp:48
armarx::VariantType::Float
const VariantTypeId Float
Definition: Variant.h:918
armarx::StringVariantBaseMap
std::map< std::string, VariantBasePtr > StringVariantBaseMap
Definition: ManagedIceObject.h:111
armarx::Observer
Baseclass for all ArmarX Observers.
Definition: Observer.h:80
armarx::Observer::ClockT
std::chrono::high_resolution_clock ClockT
Definition: Observer.h:578
armarx::PropertyDefinitionContainer::prefix
std::string prefix
Prefix of the properties such as namespace, domain, component name, etc.
Definition: PropertyDefinitionContainer.h:333
PeriodicTask.h
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
armarx::Observer::addWorkerJob
void addWorkerJob(const std::string &name, const AMDPtr &amd, FReturn(FOwner::*fnc)(FParams...), const Params &...ps)
Definition: Observer.h:567
RunningTask.h
armarx::Observer::addWorkerJob
void addWorkerJob(const std::string &name, const AMDPtr &amd, FReturn(FOwner::*fnc)(FParams...) const, const Params &...ps) const
Definition: Observer.h:558
IceInternal::Handle< DatafieldRef >
armarx::GetHandledExceptionString
std::string GetHandledExceptionString()
Definition: Exception.cpp:147
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:926
armarx::Observer::TimepointT
typename ClockT::time_point TimepointT
Definition: Observer.h:579
armarx::VariantType::Long
const VariantTypeId Long
Definition: Variant.h:917
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:189
armarx::VariantTypeId
Ice::Int VariantTypeId
Definition: Variant.h:44
armarx::ObserverPropertyDefinitions::ObserverPropertyDefinitions
ObserverPropertyDefinitions(std::string prefix)
Definition: Observer.h:54
Component.h
armarx::Component
Baseclass for all ArmarX ManagedIceObjects requiring properties.
Definition: Component.h:95
armarx::Observer::impl
std::unique_ptr< Impl > impl
Definition: Observer.h:588
armarx::ConditionCheck
Definition: ConditionCheck.h:56
armarx::VariantType::DatafieldRef
const VariantTypeId DatafieldRef
Definition: DatafieldRef.h:169
armarx::Observer::channelsMutex
std::recursive_mutex channelsMutex
Definition: Observer.h:586
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:70
ImportExport.h
armarx::Observer::onExitObserver
virtual void onExitObserver()
Framework hook.
Definition: Observer.h:464
ConditionCheck.h
ARMARXCORE_IMPORT_EXPORT
#define ARMARXCORE_IMPORT_EXPORT
Definition: ImportExport.h:38
armarx::PropertyDefinitionsPtr
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
Definition: forward_declarations.h:34
armarx::ObserverPropertyDefinitions
Definition: Observer.h:50
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:28
identifiers
const std::list< std::string > identifiers
Definition: linux_networkload.cpp:21
armarx::Observer::callAndPassExceptionToAMD
void callAndPassExceptionToAMD(auto &amd, auto f) const
Definition: Observer.h:506