SystemObserver.cpp
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 _at_ kit _dot_ edu)
20 * @date 2012
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txtg
22 * GNU General Public License
23 */
24 
25 #include "SystemObserver.h"
36 #include <IceUtil/Time.h>
37 
38 namespace armarx
39 {
40  // ********************************************************************
41  // observer framework hooks
42  // ********************************************************************
44  {
45  maxTimerId = 0;
46 
47  // register all checks
48  offerConditionCheck(checks::SystemObserver::updated->getCheckStr(), new ConditionCheckUpdated());
49  offerConditionCheck(checks::SystemObserver::valid->getCheckStr(), new ConditionCheckValid());
50  offerConditionCheck(checks::SystemObserver::equals->getCheckStr(), new ConditionCheckEquals());
51  offerConditionCheck(checks::SystemObserver::inrange->getCheckStr(), new ConditionCheckInRange());
52  offerConditionCheck(checks::SystemObserver::larger->getCheckStr(), new ConditionCheckLarger());
53  offerConditionCheck(checks::SystemObserver::smaller->getCheckStr(), new ConditionCheckSmaller());
54  }
55 
57  {
59  std::unique_lock lock(timersMutex);
60  SystemObserverTimerMap::iterator iter = timers.begin();
61 
62  while (iter != timers.end())
63  {
64  try
65  {
66  // update the timer
67  updateTimer(iter->second);
68 
69  // update data field and channel
70  setDataField(iter->second.timerName, "elapsedMs", int(iter->second.elapsedMs));
71  updateChannel(iter->second.timerName);
72  }
73  catch (armarx::LocalException& e)
74  {
75  ARMARX_FATAL << e.what();
76  }
77  catch (armarx::UserException& e)
78  {
79  ARMARX_FATAL << e.reason;
80  }
81  iter++;
82  }
83  }
84 
85  // ********************************************************************
86  // timers interface implementation
87  // ********************************************************************
89  const AMD_SystemObserverInterface_startTimerPtr& amd,
90  const std::string& timerBaseName,
91  const Ice::Current& c)
92  {
93  addWorkerJob("SystemObserver::startTimer", [this, amd, timerBaseName]
94  {
95  std::stringstream temp;
96  temp << ++maxTimerId << "_" << timerBaseName;
97  std::string timerName = temp.str();
98 
99  std::unique_lock lock(timersMutex);
100 
101  if (timers.find(timerName) != timers.end())
102  {
103  std::string reason = "Timer " + timerName + " already exists";
104  amd->ice_exception(InvalidTimerException(reason.c_str()));
105  }
106 
107  // create new timer
108  SystemObserverTimer timer;
109  timer.timerName = timerName;
110  resetTimer(timer);
111 
112  std::pair<std::string, SystemObserverTimer> entry;
113  entry.first = timerName;
114  entry.second = timer;
115 
116  timers.insert(entry);
117 
118  std::unique_lock registryLock(channelsMutex);
119 
120  // add channel and datafield
121  offerChannel(timerName, "Timer " + timerName);
122  offerDataFieldWithDefault(timerName, "elapsedMs", int(0), "Elapsed milliseconds of Timer " + timerName);
123  updateChannel(timerName);
124 
125  // return datafield identifier for easy condition installation
126  amd->ice_response(new ChannelRef(this, timerName));
127  });
128  }
129 
131  const AMD_SystemObserverInterface_resetTimerPtr& amd,
132  const ChannelRefBasePtr& timer,
133  const Ice::Current& c)
134  {
135  addWorkerJob("SystemObserver::resetTimer", [this, amd, timer]
136  {
137  std::unique_lock lock(timersMutex);
138  std::string timerName = ChannelRefPtr::dynamicCast(timer)->getChannelName();
139 
140  SystemObserverTimerMap::iterator iter = timers.find(timerName);
141 
142  if (iter != timers.end())
143  {
144  resetTimer(iter->second);
145  }
146  else
147  {
148  std::string reason = "Timer " + timerName + " unknown";
149  amd->ice_exception(InvalidTimerException(reason.c_str()));
150  }
151  amd->ice_response();
152  });
153  }
154 
156  const AMD_SystemObserverInterface_pauseTimerPtr& amd,
157  const ChannelRefBasePtr& timer,
158  const Ice::Current& c)
159  {
160  addWorkerJob("SystemObserver::pauseTimer", [this, amd, timer]
161  {
162  std::unique_lock lock(timersMutex);
163  std::string timerName = ChannelRefPtr::dynamicCast(timer)->getChannelName();
164 
165  SystemObserverTimerMap::iterator iter = timers.find(timerName);
166 
167  if (iter != timers.end())
168  {
169  iter->second.paused = true;
170  }
171  else
172  {
173  std::string reason = "Timer " + timerName + " unknown";
174  amd->ice_exception(InvalidTimerException(reason.c_str()));
175  }
176  amd->ice_response();
177  });
178  }
179 
181  const AMD_SystemObserverInterface_unpauseTimerPtr& amd,
182  const ChannelRefBasePtr& timer,
183  const Ice::Current& c)
184  {
185  addWorkerJob("SystemObserver::unpauseTimer", [this, amd, timer]
186  {
187  std::unique_lock lock(timersMutex);
188  std::string timerName = ChannelRefPtr::dynamicCast(timer)->getChannelName();
189 
190  SystemObserverTimerMap::iterator iter = timers.find(timerName);
191 
192  if (iter != timers.end())
193  {
194  iter->second.paused = false;
195  iter->second.startTimeMs += getElapsedTimeMs(iter->second.startTimeMs + iter->second.elapsedMs);
196  }
197  else
198  {
199  std::string reason = "Timer " + timerName + " unknown";
200  amd->ice_exception(InvalidTimerException(reason.c_str()));
201  }
202  amd->ice_response();
203  });
204  }
205 
207  const AMD_SystemObserverInterface_removeTimerPtr& amd,
208  const ChannelRefBasePtr& timer,
209  const Ice::Current& c)
210  {
211  addWorkerJob("SystemObserver::removeTimer", [this, amd, timer]
212  {
213  std::unique_lock lock(timersMutex);
214  std::string timerName = ChannelRefPtr::dynamicCast(timer)->getChannelName();
215 
216  SystemObserverTimerMap::iterator iter = timers.find(timerName);
217 
218  if (iter != timers.end())
219  {
220  removeChannel(timerName);
221  timers.erase(iter);
222  }
223  amd->ice_response();
224  });
225  }
226 
227 
228 
229  // ********************************************************************
230  // counters implementation
231  // ********************************************************************
233  const AMD_SystemObserverInterface_startCounterPtr& amd,
234  int initialValue,
235  const std::string& counterBaseName,
236  const Ice::Current& c)
237  {
238  addWorkerJob("SystemObserver::startCounter", [this, amd, initialValue, counterBaseName]
239  {
240  std::stringstream temp;
241  temp << ++maxCounterId << "_" << counterBaseName;
242  std::string counterName = temp.str();
243 
244  std::unique_lock lock(countersMutex);
245 
246  if (counters.find(counterName) != counters.end())
247  {
248  std::string reason = "Counter " + counterName + " already exists";
249  amd->ice_exception(InvalidCounterException(reason.c_str()));
250  }
251 
252 
253 
254  // create new counter
255  SystemObserverCounter counter;
256  counter.counterName = counterName;
257  counter.value = initialValue;
258 
259  std::pair<std::string, SystemObserverCounter> entry;
260  entry.first = counterName;
261  entry.second = counter;
262 
263 
264  SystemObserverCounterMap::iterator iter;
265  iter = (counters.insert(entry)).first;
266 
267 
268  // add channel and datafield
269  offerChannel(counterName, "Counter " + counterName);
270  offerDataField(counterName, "value", VariantType::Int, "Current value of counter " + counterName);
271 
272  updateCounter(iter);
273 
274  // return datafield identifier for easy condition installation
275  amd->ice_response(new ChannelRef(this, counterName));
276 
277  });
278  }
279 
281  const AMD_SystemObserverInterface_incrementCounterPtr& amd,
282  const ChannelRefBasePtr& counter,
283  const Ice::Current& c)
284  {
285  addWorkerJob("SystemObserver::incrementCounter", [this, amd, counter]
286  {
287  std::unique_lock lock(countersMutex);
288  std::string counterName = ChannelRefPtr::dynamicCast(counter)->getChannelName();
289 
290  SystemObserverCounterMap::iterator iter = counters.find(counterName);
291 
292  if (iter != counters.end())
293  {
294  iter->second.value++;
295  }
296  else
297  {
298  std::string reason = "Counter " + counterName + " unknown";
299  amd->ice_exception(InvalidCounterException(reason.c_str()));
300  }
301 
302  updateCounter(iter);
303  amd->ice_response(iter->second.value);
304  });
305  }
306 
308  const AMD_SystemObserverInterface_decrementCounterPtr& amd,
309  const ChannelRefBasePtr& counter,
310  const Ice::Current& c)
311  {
312  addWorkerJob("SystemObserver::decrementCounter", [this, amd, counter]
313  {
314  std::unique_lock lock(countersMutex);
315  std::string counterName = ChannelRefPtr::dynamicCast(counter)->getChannelName();
316 
317  SystemObserverCounterMap::iterator iter = counters.find(counterName);
318 
319  if (iter != counters.end())
320  {
321  iter->second.value--;
322  }
323  else
324  {
325  std::string reason = "Counter " + counterName + " unknown";
326  amd->ice_exception(InvalidCounterException(reason.c_str()));
327  }
328 
329  updateCounter(iter);
330  amd->ice_response(iter->second.value);
331  });
332  }
333 
335  const AMD_SystemObserverInterface_resetCounterPtr& amd,
336  const ChannelRefBasePtr& counter,
337  const Ice::Current& c)
338  {
339  addWorkerJob("SystemObserver::resetCounter", [this, amd, counter]
340  {
341  std::unique_lock lock(countersMutex);
342  std::string counterName = ChannelRefPtr::dynamicCast(counter)->getChannelName();
343 
344  SystemObserverCounterMap::iterator iter = counters.find(counterName);
345 
346  if (iter != counters.end())
347  {
348  iter->second.value = 0;
349  }
350  else
351  {
352  std::string reason = "Counter " + counterName + " unknown";
353  amd->ice_exception(InvalidCounterException(reason.c_str()));
354  }
355 
356  updateCounter(iter);
357  amd->ice_response();
358  });
359  }
360 
362  const AMD_SystemObserverInterface_setCounterPtr& amd,
363  const ChannelRefBasePtr& counter,
364  int counterValue,
365  const Ice::Current& c)
366  {
367  addWorkerJob("SystemObserver::setCounter", [this, amd, counter, counterValue]
368  {
369  std::unique_lock lock(countersMutex);
370  std::string counterName = ChannelRefPtr::dynamicCast(counter)->getChannelName();
371 
372  SystemObserverCounterMap::iterator iter = counters.find(counterName);
373 
374  if (iter != counters.end())
375  {
376  iter->second.value = counterValue;
377  }
378  else
379  {
380  std::string reason = "Counter " + counterName + " unknown";
381  amd->ice_exception(InvalidCounterException(reason.c_str()));
382  }
383 
384  updateCounter(iter);
385  amd->ice_response();
386  });
387  }
388 
390  const AMD_SystemObserverInterface_removeCounterPtr& amd,
391  const ChannelRefBasePtr& counter,
392  const Ice::Current& c)
393  {
394  addWorkerJob("SystemObserver::removeCounter", [this, amd, counter]
395  {
396  std::unique_lock lock(countersMutex);
397  std::string counterName = ChannelRefPtr::dynamicCast(counter)->getChannelName();
398 
399  SystemObserverCounterMap::iterator iter = counters.find(counterName);
400 
401  if (iter != counters.end())
402  {
403  removeChannel(counterName);
404  counters.erase(iter);
405  }
406  amd->ice_response();
407  });
408  }
409 
410 
411 
412 
413  // ********************************************************************
414  // private methods
415  // ********************************************************************
416  void SystemObserver::resetTimer(SystemObserverTimer& timer)
417  {
418  timer.startTimeMs = getCurrentTimeMs();
419  timer.elapsedMs = getElapsedTimeMs(timer.startTimeMs);
420  timer.paused = false;
421  }
422 
423  void SystemObserver::updateTimer(SystemObserverTimer& timer)
424  {
425  if (!timer.paused)
426  {
427  timer.elapsedMs = getElapsedTimeMs(timer.startTimeMs);
428  }
429  }
430 
431  int SystemObserver::getCurrentTimeMs()
432  {
433  IceUtil::Time current = TimeUtil::GetTime();
434 
435  return current.toMilliSeconds();
436  }
437 
438  int SystemObserver::getElapsedTimeMs(int referenceTimeMs)
439  {
440  IceUtil::Time current = TimeUtil::GetTime();
441  IceUtil::Time reference = IceUtil::Time::milliSeconds(referenceTimeMs);
442  IceUtil::Time interval = current - reference;
443 
444  return interval.toMilliSeconds();
445  }
446 
447 
448  void SystemObserver::updateCounter(SystemObserverCounterMap::iterator& iterCounter)
449  {
450  // update data field and channel
451  setDataField(iterCounter->second.counterName, "value", iterCounter->second.value);
452  updateChannel(iterCounter->second.counterName);
453  }
454 }
armarx::Observer::updateChannel
void updateChannel(const std::string &channelName, const std::set< std::string > &updatedDatafields=std::set< std::string >())
Update all conditions for a channel.
Definition: Observer.cpp:715
armarx::SystemObserver::resetCounter_async
void resetCounter_async(const AMD_SystemObserverInterface_resetCounterPtr &amd, const ChannelRefBasePtr &counter, const Ice::Current &c=Ice::emptyCurrent) override
Definition: SystemObserver.cpp:334
armarx::SystemObserver::setCounter_async
void setCounter_async(const AMD_SystemObserverInterface_setCounterPtr &amd, const ChannelRefBasePtr &counter, int counterValue, const Ice::Current &c=Ice::emptyCurrent) override
Definition: SystemObserver.cpp:361
SystemObserver.h
armarx::SystemObserver::startCounter_async
void startCounter_async(const AMD_SystemObserverInterface_startCounterPtr &amd, int initialValue, const std::string &counterBaseName, const Ice::Current &c=Ice::emptyCurrent) override
Creates a new counter and starts it.
Definition: SystemObserver.cpp:232
armarx::SystemObserverCounter::value
int value
Definition: SystemObserver.h:71
ConditionCheckEquals.h
armarx::Observer::removeChannel
void removeChannel(std::string channelName)
Remove a channel.
Definition: Observer.cpp:289
armarx::SystemObserverTimer::timerName
std::string timerName
Definition: SystemObserver.h:57
ConditionCheckInRange.h
armarx::SystemObserver::resetTimer_async
void resetTimer_async(const AMD_SystemObserverInterface_resetTimerPtr &amd, const ChannelRefBasePtr &timer, const Ice::Current &c=Ice::emptyCurrent) override
resetTimer sets the start time of timer to Time.Now() and start the timer
Definition: SystemObserver.cpp:130
armarx::SystemObserver::startTimer_async
void startTimer_async(const AMD_SystemObserverInterface_startTimerPtr &amd, const std::string &timerBaseName, const Ice::Current &c=Ice::emptyCurrent) override
Creates a new timer with name timerBaseName and starts it.
Definition: SystemObserver.cpp:88
armarx::SystemObserverCounter::counterName
std::string counterName
Definition: SystemObserver.h:70
armarx::SystemObserverTimer::startTimeMs
int startTimeMs
Definition: SystemObserver.h:58
armarx::SystemObserver::removeTimer_async
void removeTimer_async(const AMD_SystemObserverInterface_removeTimerPtr &amd, const ChannelRefBasePtr &timer, const Ice::Current &c=Ice::emptyCurrent) override
removeTimer stops timer and removes it from the SystemObserver.
Definition: SystemObserver.cpp:206
armarx::SystemObserver::pauseTimer_async
void pauseTimer_async(const AMD_SystemObserverInterface_pauseTimerPtr &amd, const ChannelRefBasePtr &timer, const Ice::Current &c=Ice::emptyCurrent) override
pauseTimer pauses the advance of time in timer.
Definition: SystemObserver.cpp:155
armarx::ConditionCheckSmaller
Definition: ConditionCheckSmaller.h:40
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
ARMARX_FATAL
#define ARMARX_FATAL
Definition: Logging.h:192
armarx::SystemObserver::removeCounter_async
void removeCounter_async(const AMD_SystemObserverInterface_removeCounterPtr &amd, const ChannelRefBasePtr &counter, const Ice::Current &c=Ice::emptyCurrent) override
Definition: SystemObserver.cpp:389
ObserverObjectFactories.h
armarx::SystemObserver::onInitObserver
void onInitObserver() override
Framework hook.
Definition: SystemObserver.cpp:43
armarx::SystemObserverTimer
Definition: SystemObserver.h:55
armarx::ConditionCheckUpdated
Definition: ConditionCheckUpdated.h:41
armarx::SystemObserver::unpauseTimer_async
void unpauseTimer_async(const AMD_SystemObserverInterface_unpauseTimerPtr &amd, const ChannelRefBasePtr &timer, const Ice::Current &c=Ice::emptyCurrent) override
unpauseTimer resumes the advancing in time of timer.
Definition: SystemObserver.cpp:180
armarx::interval
Interval< T > interval(T lo, T hi)
Definition: OccupancyGrid.h:26
armarx::VariantType::ChannelRef
const VariantTypeId ChannelRef
Definition: ChannelRef.h:162
armarx::Observer::setDataField
void setDataField(const std::string &channelName, const std::string &datafieldName, const Variant &value, bool triggerFilterUpdate=true)
set datafield with datafieldName and in channel channelName
Definition: Observer.cpp:465
armarx::SystemObserverTimer::elapsedMs
int elapsedMs
Definition: SystemObserver.h:59
armarx::SystemObserverCounter
Definition: SystemObserver.h:68
armarx::armem::Time
armarx::core::time::DateTime Time
Definition: forward_declarations.h:13
armarx::SystemObserverTimer::paused
bool paused
Definition: SystemObserver.h:60
armarx::TimeUtil::GetTime
static IceUtil::Time GetTime(TimeMode timeMode=TimeMode::VirtualTime)
Get the current time.
Definition: TimeUtil.cpp:42
armarx::ConditionCheckInRange
Definition: ConditionCheckInRange.h:41
armarx::Observer::channelsMutex
std::recursive_mutex channelsMutex
Definition: Observer.h:586
armarx::SystemObserver::postWorkerJobs
void postWorkerJobs() override
Definition: SystemObserver.cpp:56
TimeUtil.h
armarx::SystemObserver::decrementCounter_async
void decrementCounter_async(const AMD_SystemObserverInterface_decrementCounterPtr &amd, const ChannelRefBasePtr &counter, const Ice::Current &c=Ice::emptyCurrent) override
Definition: SystemObserver.cpp:307
ConditionCheckSmaller.h
armarx::VariantType::Int
const VariantTypeId Int
Definition: Variant.h:916
armarx::ConditionCheckEquals
Definition: ConditionCheckEquals.h:46
armarx::SystemObserver::incrementCounter_async
void incrementCounter_async(const AMD_SystemObserverInterface_incrementCounterPtr &amd, const ChannelRefBasePtr &counter, const Ice::Current &c=Ice::emptyCurrent) override
Definition: SystemObserver.cpp:280
armarx::Observer::offerConditionCheck
void offerConditionCheck(std::string checkName, ConditionCheck *conditionCheck)
Offer a condition check.
Definition: Observer.cpp:273
ConditionCheckLarger.h
armarx::ConditionCheckLarger
Definition: ConditionCheckLarger.h:40
armarx::Observer::offerDataFieldWithDefault
void offerDataFieldWithDefault(std::string channelName, std::string datafieldName, const Variant &defaultValue, std::string description)
Offer a datafield with default value.
Definition: Observer.cpp:152
armarx::Observer::addWorkerJob
void addWorkerJob(const std::string &name, std::function< void(void)> &&f) const
Definition: Observer.cpp:1099
armarx::Observer::offerDataField
void offerDataField(std::string channelName, std::string datafieldName, VariantTypeId type, std::string description)
Offer a datafield without default value.
Definition: Observer.cpp:187
ConditionCheckValid.h
armarx::ConditionCheckValid
Definition: ConditionCheckValid.h:40
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
Exception.h
ChannelRef.h
armarx::Observer::postWorkerJobs
virtual void postWorkerJobs()
Definition: Observer.cpp:1112
ConditionCheckUpdated.h
armarx::Observer::offerChannel
void offerChannel(std::string channelName, std::string description)
Offer a channel.
Definition: Observer.cpp:126