F´ Flight Software - C/C++ Documentation devel
A framework for building embedded system applications to NASA flight quality standards.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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
14namespace Utils {
15
16 RateLimiter ::
17 RateLimiter (
18 U32 counterCycle,
19 U32 timeCycle
20 ) :
21 m_counterCycle(counterCycle),
22 m_timeCycle(timeCycle)
23 {
24 this->reset();
25 }
26
27 RateLimiter ::
28 RateLimiter () :
29 m_counterCycle(0),
30 m_timeCycle(0)
31 {
32 this->reset();
33 }
34
35 void RateLimiter ::
36 setCounterCycle(
37 U32 counterCycle
38 )
39 {
40 this->m_counterCycle = counterCycle;
41 }
42
43 void RateLimiter ::
44 setTimeCycle(
45 U32 timeCycle
46 )
47 {
48 this->m_timeCycle = timeCycle;
49 }
50
51 void RateLimiter ::
52 reset()
53 {
54 this->resetCounter();
55 this->resetTime();
56 }
57
58 void RateLimiter ::
59 resetCounter()
60 {
61 this->m_counter = 0;
62 }
63
64 void RateLimiter ::
65 resetTime()
66 {
67 this->m_time = Fw::Time();
68 this->m_timeAtNegativeInfinity = true;
69 }
70
71 void RateLimiter ::
72 setCounter(
73 U32 counter
74 )
75 {
76 this->m_counter = counter;
77 }
78
79 void RateLimiter ::
80 setTime(
81 Fw::Time time
82 )
83 {
84 this->m_time = time;
85 this->m_timeAtNegativeInfinity = false;
86 }
87
88 bool RateLimiter ::
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
127 bool RateLimiter ::
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
static Time add(const Time &a, const Time &b)
Definition Time.cpp:193
static Time zero(TimeBase timeBase=TB_NONE)
Definition Time.cpp:152