iCub-main
embot_tools.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 iCub Facility - Istituto Italiano di Tecnologia
3  * Author: Marco Accame, Valentina Gaggero
4  * email: marco.accame@iit.it, Valentina.gaggero@iit.it
5  * website: www.robotcub.org
6  * Permission is granted to copy, distribute, and/or modify this program
7  * under the terms of the GNU General Public License, version 2 or any
8  * later version published by the Free Software Foundation.
9  *
10  * A copy of the license can be found at
11  * http://www.robotcub.org/icub/license/gpl.txt
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16  * Public License for more details
17 */
18 
19 
20 // --------------------------------------------------------------------------------------------------------------------
21 // - public interface
22 // --------------------------------------------------------------------------------------------------------------------
23 
24 #include "embot_tools.h"
25 
26 
27 
28 
29 // --------------------------------------------------------------------------------------------------------------------
30 // - external dependencies
31 // --------------------------------------------------------------------------------------------------------------------
32 
33 
34 
35 // --------------------------------------------------------------------------------------------------------------------
36 // - pimpl: private implementation (see scott meyers: item 22 of effective modern c++, item 31 of effective c++
37 // --------------------------------------------------------------------------------------------------------------------
38 
40 {
41 
42  struct Status
43  {
45  std::uint32_t numofbins;
48  };
49 
51 
52  Impl()
53  {
54 
55  }
56 
57  bool init(const Config &config)
58  {
59  if(false == config.isvalid())
60  {
61  return false;
62  }
63 
64  status.config = config;
65 
67 
69  status.values.inside.resize(status.config.nsteps(), 0);
70 
72 
73  return true;
74  }
75 
76 
77 
78  bool add(std::uint64_t val)
79  {
80  if(false == status.config.isvalid())
81  { // not yet initted
82  return false;
83  }
84 
85  if(val < status.config.min)
86  {
87  status.values.below ++;
88  status.values.total ++;
89  }
90  else if(val < status.config.max)
91  {
92  std::uint64_t index = (val - status.config.min) / status.config.step;
93  if(index < status.numofbins)
94  {
95  status.values.inside[index] ++;
96  status.values.total ++;
97  }
98  else
99  {
100  return false;
101  }
102  }
103  else //if(val >= status.config.max)
104  {
105  status.values.beyond ++;
106  status.values.total ++;
107  }
108 
109  return true;
110  }
111 
112 
113  bool reset()
114  {
115  std::fill(status.values.inside.begin(), status.values.inside.end(), 0);
117  return true;
118  }
119 
120 };
121 
122 
123 
124 
125 
127 {
128  std::uint64_t previous;
129  std::uint64_t delta;
130  std::uint64_t prevreport;
133  bool usehisto;
134 
136 
138 
139 
141  {
142  previous = 0;
143  delta = 0;
144  prevreport = 0;
145  enabledReport = false;
146  enabledAlert = false;
147 
148  usehisto = false;
149  }
150 
151  bool init(const Config &config)
152  {
153  if(false == config.isvalid())
154  {
155  return false;
156  }
157 
158  configuration = config;
159 
160  // ok, now i load the
161 
162  if(true == configuration.histoconfig.isvalid())
163  {
164  usehisto = true;
166  }
167 
168  return true;
169  }
170 
171 
172 
173  bool tick(std::uint64_t currtime_usec, std::uint64_t &deltatime_usec)
174  {
175  if(0 == previous)
176  {
177  previous = currtime_usec;
178  delta = 0;
179  prevreport = currtime_usec;
180  deltatime_usec = delta;
181  return true;
182  }
183  else if(currtime_usec < previous)
184  {
185  return false;
186  }
187 
188  delta = currtime_usec - previous;
189  previous = currtime_usec;
190 
191  if(true == usehisto)
192  {
193  histo.add(delta);
194  }
195 
196  enabledAlert = false;
197  enabledReport = false;
198 
199  // now i check ... should i alert?
201  {
202  enabledAlert = true;
203  }
204 
205 
206  if((true == usehisto) && ((currtime_usec - prevreport) > configuration.reportinterval))
207  {
208  prevreport = currtime_usec;
209  enabledReport = (configuration.reportinterval > 0) ? true : false;
210  }
211 
212  deltatime_usec = delta;
213  return true;
214  }
215 
216 
217  bool reset()
218  {
219  previous = 0;
220  delta = 0;
221  prevreport = 0;
222  enabledReport = false;
223  enabledAlert = false;
224 
225  histo.reset();
226 
227  return true;
228  }
229 
230 
231  bool alert(std::uint64_t &deltatime_usec) const
232  {
233  deltatime_usec = delta;
234  return enabledAlert;
235  }
236 
237 
238  bool report() const
239  {
240  return enabledReport;
241  }
242 
243 };
244 
245 
246 
248 {
249  std::uint64_t previous;
250  std::uint64_t delta;
251  std::uint64_t prevreport;
254  bool usehisto;
255  bool inited;
256 
258 
260 
261 
263  {
264  previous = 0;
265  delta = 0;
266  prevreport = 0;
267  enabledReport = false;
268  enabledAlert = false;
269  inited = false;
270 
271  usehisto = false;
272  }
273 
274  bool init(const Config &config)
275  {
276  if(false == config.isvalid())
277  {
278  return false;
279  }
280 
281  configuration = config;
282 
283  // ok, now i load the
284 
285  if(true == configuration.histoconfig.isvalid())
286  {
287  usehisto = true;
289  }
290  inited=true;
291  return true;
292  }
293 
294 
295 
296  bool tick(std::uint64_t deltatime_usec, std::uint64_t timestamp)
297  {
298  if(0 == previous)
299  {
300  prevreport=timestamp;
301  previous = timestamp;
302  return true;
303  }
304  else if(deltatime_usec <= 0)
305  {
306  return false;
307  }
308 
309 
310  if(true == usehisto)
311  {
312  histo.add(deltatime_usec);
313  }
314 
315  enabledAlert = false;
316  enabledReport = false;
317 
318  // now i check ... should i alert?
319  if(deltatime_usec >= configuration.alertvalue)
320  {
321  enabledAlert = true;
322  }
323 
324 
325  if((true == usehisto) && ((timestamp - prevreport) > configuration.reportinterval))
326  {
327  prevreport = timestamp;
328  enabledReport = (configuration.reportinterval > 0) ? true : false;
329  }
330  return true;
331  }
332 
333 
334  bool reset()
335  {
336  previous = 0;
337  delta = 0;
338  prevreport = 0;
339  enabledReport = false;
340  enabledAlert = false;
341 
342  histo.reset();
343 
344  return true;
345  }
346 
347 
348  bool alert(std::uint64_t &deltatime_usec) const
349  {
350  deltatime_usec = delta;
351  return enabledAlert;
352  }
353 
354 
355  bool report() const
356  {
357  return enabledReport;
358  }
359 
360  bool isInited() const
361  {
362  return inited;
363  }
364 
365 };
366 
367 // --------------------------------------------------------------------------------------------------------------------
368 // - all the rest
369 // --------------------------------------------------------------------------------------------------------------------
370 
371 
372 
374 : pImpl(new Impl)
375 {
376 
377 }
378 
380 {
381  delete pImpl;
382 }
383 
384 
386 {
387  return pImpl->init(config);
388 }
389 
390 
392 {
393  return pImpl->reset();
394 }
395 
396 
397 bool embot::tools::Histogram::add(std::uint64_t value)
398 {
399  return pImpl->add(value);
400 }
401 
403 {
404  return &pImpl->status.config;
405 }
406 
408 {
409  return &pImpl->status.values;
410 }
411 
412 //bool embot::tools::Histogram::probabilitydensityfunction(std::vector<std::uint32_t> &values, const std::uint32_t scale, const bool underflowisONE) const
413 //{
414 // if(0 == pImpl->status.values.total)
415 // {
416 // values.clear();
417 // return false;
418 // }
419 //
420 // values.resize(pImpl->status.values.inside.size() + 2);
421 //
422 // std::uint32_t *ref = &values[0];
423 // std::uint64_t v64 = pImpl->status.values.below;
424 //
425 // if(0 == v64)
426 // {
427 // *ref = 0;
428 // }
429 // else
430 // {
431 // *ref = static_cast<std::uint32_t>(scale * v64 / pImpl->status.values.total);
432 // if((0 == *ref) && (true == underflowisONE))
433 // {
434 // *ref = 1;
435 // }
436 // }
437 //
438 // for(int i=0; i<pImpl->status.values.inside.size(); i++)
439 // {
440 // ref = &values[i+1];
441 // v64 = pImpl->status.values.inside[i];
442 // if(0 == v64)
443 // {
444 // *ref = 0;
445 // }
446 // else
447 // {
448 // *ref = static_cast<std::uint32_t>(scale * v64 / pImpl->status.values.total);
449 // if((0 == *ref) && (true == underflowisONE))
450 // {
451 // *ref = 1;
452 // }
453 // }
454 // }
455 //
456 // ref = &values[values.size()-1];
457 // v64 = pImpl->status.values.beyond;
458 //
459 // if(0 == v64)
460 // {
461 // *ref = 0;
462 // }
463 // else
464 // {
465 // *ref = static_cast<std::uint32_t>(scale * v64 / pImpl->status.values.total);
466 // if((0 == *ref) && (true == underflowisONE))
467 // {
468 // *ref = 1;
469 // }
470 // }
471 //
472 // return true;
473 //
474 //}
475 
476 bool embot::tools::Histogram::probabilitydensityfunction(std::vector<double> &values) const
477 {
478  if(0 == pImpl->status.values.total)
479  {
480  values.clear();
481  return false;
482  }
483 
484  values.resize(pImpl->status.values.inside.size() + 2);
485 
486  values[0] = static_cast<double>(pImpl->status.values.below) / static_cast<double>(pImpl->status.values.total);
487 
488  for(int i=0; i<pImpl->status.values.inside.size(); i++)
489  {
490  values[i+1] = static_cast<double>(pImpl->status.values.inside[i]) / static_cast<double>(pImpl->status.values.total);
491  }
492 
493  values[values.size()-1] = static_cast<double>(pImpl->status.values.beyond) / static_cast<double>(pImpl->status.values.total);
494 
495  return true;
496 }
497 
498 bool embot::tools::Histogram::probabilitydensityfunction(std::vector<std::uint32_t> &values, const std::uint32_t scale) const
499 {
500  if(0 == pImpl->status.values.total)
501  {
502  values.clear();
503  return false;
504  }
505 
506  values.resize(pImpl->status.values.inside.size() + 2);
507 
508  values[0] = static_cast<std::uint32_t>(scale * pImpl->status.values.below / pImpl->status.values.total);
509 
510  for(int i=0; i<pImpl->status.values.inside.size(); i++)
511  {
512  values[i+1] = static_cast<std::uint32_t>(scale * pImpl->status.values.inside[i] / pImpl->status.values.total);
513  }
514 
515  values[values.size()-1] = static_cast<std::uint32_t>(scale * pImpl->status.values.beyond / pImpl->status.values.total);
516 
517  return true;
518 }
519 
520 
522 : pImpl(new Impl)
523 {
524 
525 }
526 
528 {
529  delete pImpl;
530 }
531 
532 
534 {
535  return pImpl->init(config);
536 }
537 
538 
539 bool embot::tools::PeriodValidator::tick(std::uint64_t currtime_usec, std::uint64_t &deltatime_usec)
540 {
541  return pImpl->tick(currtime_usec, deltatime_usec);
542 }
543 
544 
546 {
547  return pImpl->reset();
548 }
549 
550 
551 bool embot::tools::PeriodValidator::alert(std::uint64_t &deltatime_usec) const
552 {
553  return pImpl->alert(deltatime_usec);
554 }
555 
557 {
558  return pImpl->report();
559 }
560 
561 
563 {
564  return &pImpl->histo;
565 }
566 
567 
568 
569 
570 
572 : pImpl(new Impl)
573 {
574 
575 }
576 
578 {
579  delete pImpl;
580 }
581 
582 
584 {
585  return pImpl->init(config);
586 }
587 
588 
589 bool embot::tools::RoundTripValidator::tick(std::uint64_t deltatime_usec, std::uint64_t timestamp)
590 {
591  return pImpl->tick(deltatime_usec, timestamp);
592 }
593 
594 
596 {
597  return pImpl->reset();
598 }
599 
600 
601 bool embot::tools::RoundTripValidator::alert(std::uint64_t &deltatime_usec) const
602 {
603  return pImpl->alert(deltatime_usec);
604 }
605 
607 {
608  return pImpl->report();
609 }
610 
611 
613 {
614  return &pImpl->histo;
615 }
616 
617 
619 {
620  return pImpl->isInited();
621 }
622 
623 
624 
625 // - end-of-file (leave a blank line after)----------------------------------------------------------------------------
const embot::tools::Histogram::Values * getvalues() const
const embot::tools::Histogram::Config * getconfig() const
bool init(const Config &config)
bool add(std::uint64_t value)
bool probabilitydensityfunction(std::vector< std::uint32_t > &values, const std::uint32_t scale) const
bool alert(std::uint64_t &deltatime_usec) const
bool init(const Config &config)
const embot::tools::Histogram * histogram() const
bool tick(std::uint64_t currtime_usec, std::uint64_t &deltatime_usec)
bool init(const Config &config)
const embot::tools::Histogram * histogram() const
bool alert(std::uint64_t &deltatime_usec) const
bool tick(std::uint64_t deltatime_usec, std::uint64_t timestamp)
std::uint32_t nsteps() const
Definition: embot_tools.h:49
bool add(std::uint64_t val)
Definition: embot_tools.cpp:78
bool init(const Config &config)
Definition: embot_tools.cpp:57
std::vector< std::uint64_t > inside
Definition: embot_tools.h:58
embot::tools::Histogram::Config histoconfig
Definition: embot_tools.h:103
bool init(const Config &config)
bool alert(std::uint64_t &deltatime_usec) const
bool tick(std::uint64_t currtime_usec, std::uint64_t &deltatime_usec)
embot::tools::Histogram histo
embot::tools::Histogram::Config histoconfig
Definition: embot_tools.h:177
bool alert(std::uint64_t &deltatime_usec) const
bool init(const Config &config)
bool tick(std::uint64_t deltatime_usec, std::uint64_t timestamp)