F´ Flight Software - C/C++ Documentation
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 
16 RateLimiter ::RateLimiter(U32 counterCycle, U32 timeCycle) : m_counterCycle(counterCycle), m_timeCycle(timeCycle) {
17  this->reset();
18 }
19 
20 RateLimiter ::RateLimiter() : m_counterCycle(0), m_timeCycle(0) {
21  this->reset();
22 }
23 
24 void RateLimiter ::setCounterCycle(U32 counterCycle) {
25  this->m_counterCycle = counterCycle;
26 }
27 
28 void RateLimiter ::setTimeCycle(U32 timeCycle) {
29  this->m_timeCycle = timeCycle;
30 }
31 
33  this->resetCounter();
34  this->resetTime();
35 }
36 
38  this->m_counter = 0;
39 }
40 
42  this->m_time = Fw::Time();
43  this->m_timeAtNegativeInfinity = true;
44 }
45 
46 void RateLimiter ::setCounter(U32 counter) {
47  this->m_counter = counter;
48 }
49 
51  this->m_time = time;
52  this->m_timeAtNegativeInfinity = false;
53 }
54 
56  // NB: this implements a 4-bit decision, logically equivalent to this pseudo-code
57  //
58  // A = HAS_COUNTER, B = HAS_TIME, C = COUNTER_TRIGGER, D = TIME_TRIGGER
59  //
60  // if (!A && !B) => true
61  // if (A && B) => C || D
62  // if (A) => C
63  // if (B) => D
64  // false
65  //
66  if (this->m_counterCycle == 0 && this->m_timeCycle == 0) {
67  return true;
68  }
69 
70  // evaluate trigger criteria
71  bool shouldTrigger = false;
72  if (this->m_counterCycle > 0) {
73  shouldTrigger = shouldTrigger || this->shouldCounterTrigger();
74  }
75  if (this->m_timeCycle > 0) {
76  shouldTrigger = shouldTrigger || this->shouldTimeTrigger(time);
77  }
78 
79  // update states
80  if (this->m_counterCycle > 0) {
81  this->updateCounter(shouldTrigger);
82  }
83  if (this->m_timeCycle > 0) {
84  this->updateTime(shouldTrigger, time);
85  }
86 
87  return shouldTrigger;
88 }
89 
91  FW_ASSERT(this->m_timeCycle == 0);
92  return trigger(Fw::Time::zero());
93 }
94 
95 bool RateLimiter ::shouldCounterTrigger() {
96  FW_ASSERT(this->m_counterCycle > 0);
97 
98  // trigger at 0
99  bool shouldTrigger = (this->m_counter == 0);
100 
101  return shouldTrigger;
102 }
103 
104 bool RateLimiter ::shouldTimeTrigger(Fw::Time time) {
105  FW_ASSERT(this->m_timeCycle > 0);
106 
107  // trigger at prev trigger time + time cycle seconds OR when time is at negative infinity
108  Fw::Time timeCycle = Fw::Time(this->m_timeCycle, 0);
109  Fw::Time nextTrigger = Fw::Time::add(this->m_time, timeCycle);
110  bool shouldTrigger = (time >= nextTrigger) || this->m_timeAtNegativeInfinity;
111 
112  return shouldTrigger;
113 }
114 
115 void RateLimiter ::updateCounter(bool triggered) {
116  FW_ASSERT(this->m_counterCycle > 0);
117 
118  if (triggered) {
119  // triggered, set to next state
120  this->m_counter = 1;
121 
122  } else {
123  // otherwise, just increment and maybe wrap
124  if (++this->m_counter >= this->m_counterCycle) {
125  this->m_counter = 0;
126  }
127  }
128 }
129 
130 void RateLimiter ::updateTime(bool triggered, Fw::Time time) {
131  FW_ASSERT(this->m_timeCycle > 0);
132 
133  if (triggered) {
134  // mark time of trigger
135  this->m_time = time;
136  }
137  this->m_timeAtNegativeInfinity = false;
138 }
139 
140 } // end namespace Utils
void setCounter(U32)
Definition: RateLimiter.cpp:46
void setTime(Fw::Time time)
Definition: RateLimiter.cpp:50
static Time zero(TimeBase timeBase=TimeBase::TB_NONE)
Definition: Time.cpp:104
void setCounterCycle(U32 counterCycle)
Definition: RateLimiter.cpp:24
static Time add(const Time &a, const Time &b)
Definition: Time.cpp:134
void setTimeCycle(U32 timeCycle)
Definition: RateLimiter.cpp:28
#define FW_ASSERT(...)
Definition: Assert.hpp:14