F´ Flight Software - C/C++ Documentation  devel
A framework for building embedded system applications to NASA flight quality standards.
RateLimiter.cpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title RateLimiter.cpp
3 // \author vwong
4 // \brief cpp file for a rate limiter utility class
5 //
6 // \copyright
7 // Copyright (C) 2009-2020 California Institute of Technology.
8 // ALL RIGHTS RESERVED. United States Government Sponsorship
9 // acknowledged.
10 // ======================================================================
11 
12 #include <Utils/RateLimiter.hpp>
13 
14 namespace Utils {
15 
18  U32 counterCycle,
19  U32 timeCycle
20  ) :
21  m_counterCycle(counterCycle),
22  m_timeCycle(timeCycle)
23  {
24  this->reset();
25  }
26 
28  RateLimiter () :
29  m_counterCycle(0),
30  m_timeCycle(0)
31  {
32  this->reset();
33  }
34 
37  U32 counterCycle
38  )
39  {
40  this->m_counterCycle = counterCycle;
41  }
42 
45  U32 timeCycle
46  )
47  {
48  this->m_timeCycle = timeCycle;
49  }
50 
52  reset()
53  {
54  this->resetCounter();
55  this->resetTime();
56  }
57 
60  {
61  this->m_counter = 0;
62  }
63 
65  resetTime()
66  {
67  this->m_time = Fw::Time();
68  this->m_timeAtNegativeInfinity = true;
69  }
70 
73  U32 counter
74  )
75  {
76  this->m_counter = counter;
77  }
78 
80  setTime(
81  Fw::Time time
82  )
83  {
84  this->m_time = time;
85  this->m_timeAtNegativeInfinity = false;
86  }
87 
89  trigger(
90  Fw::Time time
91  )
92  {
93  // NB: this implements a 4-bit decision, logically equivalent to this pseudo-code
94  //
95  // A = HAS_COUNTER, B = HAS_TIME, C = COUNTER_TRIGGER, D = TIME_TRIGGER
96  //
97  // if (!A && !B) => true
98  // if (A && B) => C || D
99  // if (A) => C
100  // if (B) => D
101  // false
102  //
103  if (this->m_counterCycle == 0 && this->m_timeCycle == 0) {
104  return true;
105  }
106 
107  // evaluate trigger criteria
108  bool shouldTrigger = false;
109  if (this->m_counterCycle > 0) {
110  shouldTrigger = shouldTrigger || this->shouldCounterTrigger();
111  }
112  if (this->m_timeCycle > 0) {
113  shouldTrigger = shouldTrigger || this->shouldTimeTrigger(time);
114  }
115 
116  // update states
117  if (this->m_counterCycle > 0) {
118  this->updateCounter(shouldTrigger);
119  }
120  if (this->m_timeCycle > 0) {
121  this->updateTime(shouldTrigger, time);
122  }
123 
124  return shouldTrigger;
125  }
126 
128  trigger()
129  {
130  FW_ASSERT(this->m_timeCycle == 0);
131  return trigger(Fw::Time::zero());
132  }
133 
134  bool RateLimiter ::
135  shouldCounterTrigger()
136  {
137  FW_ASSERT(this->m_counterCycle > 0);
138 
139  // trigger at 0
140  bool shouldTrigger = (this->m_counter == 0);
141 
142  return shouldTrigger;
143  }
144 
145  bool RateLimiter ::
146  shouldTimeTrigger(Fw::Time time)
147  {
148  FW_ASSERT(this->m_timeCycle > 0);
149 
150  // trigger at prev trigger time + time cycle seconds OR when time is at negative infinity
151  Fw::Time timeCycle = Fw::Time(this->m_timeCycle, 0);
152  Fw::Time nextTrigger = Fw::Time::add(this->m_time, timeCycle);
153  bool shouldTrigger = (time >= nextTrigger) || this->m_timeAtNegativeInfinity;
154 
155  return shouldTrigger;
156  }
157 
158  void RateLimiter ::
159  updateCounter(bool triggered)
160  {
161  FW_ASSERT(this->m_counterCycle > 0);
162 
163  if (triggered) {
164  // triggered, set to next state
165  this->m_counter = 1;
166 
167  } else {
168  // otherwise, just increment and maybe wrap
169  if (++this->m_counter >= this->m_counterCycle) {
170  this->m_counter = 0;
171  }
172  }
173  }
174 
175  void RateLimiter ::
176  updateTime(bool triggered, Fw::Time time)
177  {
178  FW_ASSERT(this->m_timeCycle > 0);
179 
180  if (triggered) {
181  // mark time of trigger
182  this->m_time = time;
183  }
184  this->m_timeAtNegativeInfinity = false;
185  }
186 
187 } // end namespace Utils
#define FW_ASSERT(...)
Definition: Assert.hpp:14
Definition: Time.hpp:9
static Time add(const Time &a, const Time &b)
Definition: Time.cpp:193
static Time zero(TimeBase timeBase=TB_NONE)
Definition: Time.cpp:152
void setTime(Fw::Time time)
Definition: RateLimiter.cpp:80
void setTimeCycle(U32 timeCycle)
Definition: RateLimiter.cpp:44
void setCounter(U32)
Definition: RateLimiter.cpp:72
void setCounterCycle(U32 counterCycle)
Definition: RateLimiter.cpp:36