iCub-main
embot_tools.h
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 // - include guard ----------------------------------------------------------------------------------------------------
20 
21 
22 #ifndef _EMBOT_TOOLS_H_
23 #define _EMBOT_TOOLS_H_
24 
25 // - namespace embot::tools belongs to the embot (emBEDDED RObot) libray of C++11 classes and functions which are
26 // - designed to run in the icub/r1 robot's embedded environment.
27 // - the objects inside this namespace are tools used to validate behaviours in the microcontrollers inside the robot
28 // - but can also be used inside icub-main classes which runs on the PC104 platform
29 // - hence particular attention was put in avoiding any call to YARP or embot::sys (RTOS) or embot::hw (HW of the micro).
30 // - we also don't use in here any embot::common funtions or types to guarantee maximum portability.
31 
32 #include <cstdint>
33 #include <vector>
34 
35 namespace embot { namespace tools {
36 
37  class Histogram
38  {
39  public:
40 
41  struct Config
42  { // there are nsteps() intervals each containing .step values which fill the range [.min, ... , .max)
43  std::uint64_t min {0}; // the start value of first interval.
44  std::uint64_t max {0}; // the upper limit of all possible values (which is actually max-1).
45  std::uint32_t step {0}; // the width of the interval
46  Config() = default;
47  Config(std::uint64_t mi, std::uint64_t ma, std::uint32_t st) : min(mi), max(ma), step(st) {}
48  std::uint64_t range() const { return max - min; }
49  std::uint32_t nsteps() const { return ( (range() + step - 1) / step); }
50  bool isvalid() const { return ((0 == step) || (min >= max)) ? false : true; }
51  };
52 
53  struct Values
54  {
55  std::uint64_t total {0}; // cumulative number = below + sum(inside) + beyond
56  std::uint64_t below {0}; // number of occurrences in ( -INF, config.min )
57  std::uint64_t beyond {0}; // number of occurrenced in [ inside.size() * config.step, +INF )
58  std::vector<std::uint64_t> inside; // inside[i] contains the number of occurrences in [ config.min + i*config.step, config.min + (i+1)*config.step )
59  };
60 
61 
62  Histogram();
63  ~Histogram();
64 
65  bool init(const Config &config);
66 
67  bool add(std::uint64_t value);
68 
69  bool reset();
70 
73 
74  // it generates the pdf in a vector which is long Config::nsteps()+2 item.
75  // the first position contains probability that the value is < Config::min.
76  // the last position keeps probability that the value is >= Config::max.
77  // position i-th contain probability that value belongs inside [Config:min + i*Config::step, Config:min + (i+1)*Config::step).
78  bool probabilitydensityfunction(std::vector<std::uint32_t> &values, const std::uint32_t scale) const;
79  bool probabilitydensityfunction(std::vector<double> &values) const;
80 
81  private:
82  struct Impl;
83  Impl *pImpl;
84  };
85 
86 } } // namespace embot { namespace tools {
87 
88 
89 
90 
91 namespace embot { namespace tools {
92 
93  // the object validates a given period expressed in micro-seconds.
95  {
96  public:
97 
98  struct Config
99  {
100  std::uint64_t period {0}; // the period under test.
101  std::uint64_t alertvalue {0}; // it is the value beyond which we produce an alert string. it must be > period.
102  std::uint64_t reportinterval {0}; // if not zero, it keeps the value in usec between two reports
103  embot::tools::Histogram::Config histoconfig {}; // if is valid(), then we produce an histogram
104  Config() = default;
105  Config(std::uint64_t pe, std::uint64_t al, std::uint64_t ri, const embot::tools::Histogram::Config &hi)
106  : period(pe), alertvalue(al), reportinterval(ri), histoconfig(hi) {}
107  bool isvalid() const { return ((0 == period) || (period >= alertvalue)) ? false : true; }
108  };
109 
110 
111  PeriodValidator();
113 
114  bool init(const Config &config);
115 
116  // it must be regularly called every Config.period micro-seconds.
117  // it accepts the current time, returns delta time from previous call of tick(), it computes a histogram of deltas.
118  // currtime_usec is the absolute time in micro-seconds (e.g., as generated by embot::sys::now() or by static_cast<std::uint64_t>(1000000.0*yarp::os::Time::now()))
119  bool tick(std::uint64_t currtime_usec, std::uint64_t &deltatime_usec);
120 
121  // it removes all that was previously added with tick().
122  bool reset();
123 
124  // if true it is time for the regular report because more than Config.reportinterval micro-seconds have passed from previous report time.
125  bool report() const;
126 
127  // if true: there is an alert because the current delta is > Config.alertvalue
128  bool alert(std::uint64_t &deltatime_usec) const;
129 
130  // it returns the histogram
131  const embot::tools::Histogram * histogram() const;
132 
133  bool isInited() const;
134 
135  // example of usage: call it as regularly as possible
136  void how2use()
137  {
138  static bool initted = false;
139  if(!initted)
140  {
141  init({5000, 5000+50, 1000000, // period is 5ms, with tolerance of 50us (1%), with report period every 1 sec.
142  {4000, 6000, 100}}); // the histogram collects data in range [4ms, 6ms] with steps of 100 us, hence there are 20+2 entries
143 
144  initted = true;
145  }
146  uint64_t tnow = 0; // e.g., = embot::sys::now() OR = static_cast<std::uint64_t>(1000000.0*yarp::os::Time::now())
147  uint64_t delta = 0;
148  tick(tnow, delta);
149  if(true == report())
150  {
151  const embot::tools::Histogram * histo = histogram();
152  // now you can print histo and if you like you can reset it
153  reset();
154  }
155  }
156 
157  private:
158  struct Impl;
159  Impl *pImpl;
160  };
161 
162 } } // namespace embot { namespace tools {
163 
164 
165 namespace embot { namespace tools {
166 
167  // the object validates a given period expressed in micro-seconds.
169  {
170  public:
171 
172  struct Config
173  {
174  std::uint64_t period {0}; // the period under test.
175  std::uint64_t alertvalue {0}; // it is the value beyond which we produce an alert string. it must be > period.
176  std::uint64_t reportinterval {0}; // if not zero, it keeps the value in usec between two reports
177  embot::tools::Histogram::Config histoconfig {}; // if is valid(), then we produce an histogram
178  Config() = default;
179  Config(std::uint64_t pe, std::uint64_t al, std::uint64_t ri, const embot::tools::Histogram::Config &hi)
180  : period(pe), alertvalue(al), reportinterval(ri), histoconfig(hi) {}
181  bool isvalid() const { return ((0 == period) || (period >= alertvalue)) ? false : true; }
182  };
183 
184 
187 
188  bool init(const Config &config);
189 
190  // it must be regularly called every Config.period micro-seconds.
191  // it accepts the current time, returns delta time from previous call of tick(), it computes a histogram of deltas.
192  // currtime_usec is the absolute time in micro-seconds (e.g., as generated by embot::sys::now() or by static_cast<std::uint64_t>(1000000.0*yarp::os::Time::now()))
193  bool tick(std::uint64_t deltatime_usec, std::uint64_t timestamp);
194 
195  // it removes all that was previously added with tick().
196  bool reset();
197 
198  // if true it is time for the regular report because more than Config.reportinterval micro-seconds have passed from previous report time.
199  bool report() const;
200 
201  // if true: there is an alert because the current delta is > Config.alertvalue
202  bool alert(std::uint64_t &deltatime_usec) const;
203 
204  // it returns the histogram
205  const embot::tools::Histogram * histogram() const;
206 
207  bool isInited() const;
208 
209 
210 
211  private:
212  struct Impl;
213  Impl *pImpl;
214  };
215 
216 } } // namespace embot { namespace tools {
217 
218 
219 
220 
221 #endif // include-guard
222 
223 
224 // - end-of-file (leave a blank line after)----------------------------------------------------------------------------
225 
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::uint64_t range() const
Definition: embot_tools.h:48
Config(std::uint64_t mi, std::uint64_t ma, std::uint32_t st)
Definition: embot_tools.h:47
std::uint32_t nsteps() const
Definition: embot_tools.h:49
std::vector< std::uint64_t > inside
Definition: embot_tools.h:58
Config(std::uint64_t pe, std::uint64_t al, std::uint64_t ri, const embot::tools::Histogram::Config &hi)
Definition: embot_tools.h:105
embot::tools::Histogram::Config histoconfig
Definition: embot_tools.h:103
embot::tools::Histogram::Config histoconfig
Definition: embot_tools.h:177
Config(std::uint64_t pe, std::uint64_t al, std::uint64_t ri, const embot::tools::Histogram::Config &hi)
Definition: embot_tools.h:179