27 this->analysisMode = analysisMode;
28 this->thresholdCrossingMode = thresholdCrossingMode;
29 this->detectionTimeoutMode = detectionTimeoutMode;
30 this->searchWindowSize = searchWindowSize;
31 this->searchTimeoutDuration = searchTimeoutDuration;
32 this->offsetFilterSize = offsetFilterSize;
33 this->lowerThreshold = lowerThreshold;
34 this->upperThreshold = upperThreshold;
35 this->hysteresisThreshold = hysteresisThreshold;
38 thresholdCrossingDetected =
false;
40 searchWindowIndex = 0;
41 currentSearchState = SEARCHING_FOR_FIRST_THRESHOLD_CROSSING;
47 this->analysisValue = rhs.analysisValue;
48 this->lowerThreshold = rhs.lowerThreshold;
49 this->upperThreshold = rhs.upperThreshold;
50 this->hysteresisThreshold = rhs.hysteresisThreshold;
51 this->enableSearch = rhs.enableSearch;
52 this->thresholdCrossingDetected = rhs.thresholdCrossingDetected;
53 this->analysisMode = rhs.analysisMode;
54 this->thresholdCrossingMode = rhs.thresholdCrossingMode;
55 this->searchTimeoutCounter = rhs.searchTimeoutCounter;
56 this->searchTimeoutDuration = rhs.searchTimeoutDuration;
57 this->searchWindowSize = rhs.searchWindowSize;
58 this->searchWindowIndex = rhs.searchWindowIndex;
59 this->offsetFilterSize = rhs.offsetFilterSize;
60 this->currentSearchState = rhs.currentSearchState;
61 this->movingAverageFilter = rhs.movingAverageFilter;
62 this->derivative = rhs.derivative;
71 this->analysisValue = rhs.analysisValue;
72 this->lowerThreshold = rhs.lowerThreshold;
73 this->upperThreshold = rhs.upperThreshold;
74 this->hysteresisThreshold = rhs.hysteresisThreshold;
75 this->enableSearch = rhs.enableSearch;
76 this->thresholdCrossingDetected = rhs.thresholdCrossingDetected;
77 this->analysisMode = rhs.analysisMode;
78 this->thresholdCrossingMode = rhs.thresholdCrossingMode;
79 this->searchTimeoutCounter = rhs.searchTimeoutCounter;
80 this->searchTimeoutDuration = rhs.searchTimeoutDuration;
81 this->searchWindowSize = rhs.searchWindowSize;
82 this->searchWindowIndex = rhs.searchWindowIndex;
83 this->offsetFilterSize = rhs.offsetFilterSize;
84 this->currentSearchState = rhs.currentSearchState;
85 this->movingAverageFilter = rhs.movingAverageFilter;
86 this->derivative = rhs.derivative;
93 thresholdCrossingDetected =
false;
96 Float offset = movingAverageFilter.
filter( x );
99 if( !enableSearch ){
return thresholdCrossingDetected; }
103 bool upperThresholdCrossingFound =
false;
104 bool lowerThresholdCrossingFound =
false;
106 switch( analysisMode ){
107 case RAW_DATA_ANALYSIS_MODE:
110 case MOVING_OFFSET_ANALYSIS_MODE:
111 analysisValue = x - offset;
113 case DERIVATIVE_ANALYSIS_MODE:
114 analysisValue = deriv;
119 if( currentSearchState == NO_SEARCH_GATE_TIME_OUT ){
121 switch( detectionTimeoutMode ){
122 case TIMEOUT_COUNTER:
124 if (searchTimeoutCounter.
getMilliSeconds() >= (
signed long)searchTimeoutDuration){
125 currentSearchState = SEARCHING_FOR_FIRST_THRESHOLD_CROSSING;
126 searchTimeoutCounter.
stop();
129 case HYSTERESIS_THRESHOLD:
130 switch ( thresholdCrossingMode ) {
131 case UPPER_THRESHOLD_CROSSING:
132 if( analysisValue <= hysteresisThreshold ){
133 currentSearchState = SEARCHING_FOR_FIRST_THRESHOLD_CROSSING;
136 case LOWER_THRESHOLD_CROSSING:
137 if( analysisValue >= hysteresisThreshold ){
138 currentSearchState = SEARCHING_FOR_FIRST_THRESHOLD_CROSSING;
150 if( thresholdCrossingMode == UPPER_THRESHOLD_CROSSING || thresholdCrossingMode == LOWER_THRESHOLD_CROSSING || thresholdCrossingMode == UPPER_OR_LOWER_THRESHOLD_CROSSING ){
152 switch ( thresholdCrossingMode ) {
153 case UPPER_THRESHOLD_CROSSING:
154 if( analysisValue >= upperThreshold ){
155 upperThresholdCrossingFound =
true;
156 thresholdCrossingDetected =
true;
157 currentSearchState = NO_SEARCH_GATE_TIME_OUT;
158 searchTimeoutCounter.
start();
161 case LOWER_THRESHOLD_CROSSING:
162 if( analysisValue <= lowerThreshold ){
163 lowerThresholdCrossingFound =
true;
164 thresholdCrossingDetected =
true;
165 currentSearchState = NO_SEARCH_GATE_TIME_OUT;
166 searchTimeoutCounter.
start();
169 case UPPER_OR_LOWER_THRESHOLD_CROSSING:
170 if( analysisValue >= upperThreshold ){
171 upperThresholdCrossingFound =
true;
172 thresholdCrossingDetected =
true;
173 currentSearchState = NO_SEARCH_GATE_TIME_OUT;
174 searchTimeoutCounter.
start();
175 }
else if( analysisValue <= lowerThreshold ){
176 lowerThresholdCrossingFound =
true;
177 thresholdCrossingDetected =
true;
178 currentSearchState = NO_SEARCH_GATE_TIME_OUT;
179 searchTimeoutCounter.
start();
185 return thresholdCrossingDetected ?
true :
false;
189 if( currentSearchState == SEARCHING_FOR_SECOND_THRESHOLD_CROSSING ){
190 if( ++searchWindowIndex == searchWindowSize ){
191 currentSearchState = SEARCHING_FOR_FIRST_THRESHOLD_CROSSING;
192 searchWindowIndex = 0;
197 if( currentSearchState == NO_SEARCH_GATE_TIME_OUT ){
199 if (searchTimeoutCounter.
getMilliSeconds() >= (
signed long)searchTimeoutDuration){
200 currentSearchState = SEARCHING_FOR_FIRST_THRESHOLD_CROSSING;
201 searchTimeoutCounter.
stop();
206 if( analysisValue >= upperThreshold ){ upperThresholdCrossingFound =
true; }
207 if( analysisValue <= lowerThreshold ){ lowerThresholdCrossingFound =
true; }
208 if( !upperThresholdCrossingFound && !lowerThresholdCrossingFound &&
209 currentSearchState != NO_SEARCH_GATE_TIME_OUT ){
return false; }
211 switch ( currentSearchState ) {
212 case SEARCHING_FOR_FIRST_THRESHOLD_CROSSING:
213 if( thresholdCrossingMode == UPPER_THEN_LOWER_THRESHOLD_CROSSING && upperThresholdCrossingFound ){
214 searchWindowIndex = 0;
215 currentSearchState = SEARCHING_FOR_SECOND_THRESHOLD_CROSSING;
218 if( thresholdCrossingMode == LOWER_THEN_UPPER_THRESHOLD_CROSSING && lowerThresholdCrossingFound ){
219 searchWindowIndex = 0;
220 currentSearchState = SEARCHING_FOR_SECOND_THRESHOLD_CROSSING;
224 case SEARCHING_FOR_SECOND_THRESHOLD_CROSSING:
225 if( thresholdCrossingMode == UPPER_THEN_LOWER_THRESHOLD_CROSSING && lowerThresholdCrossingFound ){
226 currentSearchState = NO_SEARCH_GATE_TIME_OUT;
227 searchWindowIndex = 0;
228 searchTimeoutCounter.
start();
229 thresholdCrossingDetected =
true;
232 if( thresholdCrossingMode == LOWER_THEN_UPPER_THRESHOLD_CROSSING && upperThresholdCrossingFound ){
233 currentSearchState = NO_SEARCH_GATE_TIME_OUT;
234 searchWindowIndex = 0;
235 searchTimeoutCounter.
start();
236 thresholdCrossingDetected =
true;
245 return thresholdCrossingDetected ?
true :
false;
251 derivative.
init(Derivative::FIRST_DERIVATIVE, 1, 1,
true, 5);
253 movingAverageFilter.
init(offsetFilterSize, 1);
256 currentSearchState = NO_SEARCH_GATE_TIME_OUT;
260 thresholdCrossingDetected =
false;
262 searchWindowIndex = 0;
263 searchTimeoutCounter.
stop();
269 currentSearchState = NO_SEARCH_GATE_TIME_OUT;
270 searchTimeoutCounter.
start();
275 return thresholdCrossingDetected;
287 return thresholdCrossingMode;
291 return searchWindowSize;
295 return offsetFilterSize;
299 return searchWindowIndex;
307 return searchTimeoutDuration;
311 return analysisValue;
315 return upperThreshold;
319 return lowerThreshold;
323 return hysteresisThreshold;
327 this->enableSearch = enableSearch;
332 this->analysisMode = analysisMode;
337 this->thresholdCrossingMode = thresholdCrossingMode;
342 this->detectionTimeoutMode = detectionTimeoutMode;
347 this->searchWindowSize = searchWindowSize;
352 this->offsetFilterSize = offsetFilterSize;
357 this->searchTimeoutDuration = searchTimeoutDuration;
362 this->lowerThreshold = lowerThreshold;
367 this->upperThreshold = upperThreshold;
372 this->hysteresisThreshold = hysteresisThreshold;
UINT getThresholdCrossingMode() const
bool triggerSearchTimeout()
bool setUpperThreshold(const Float upperThreshold)
bool update(const Float x)
bool init(UINT filterSize, UINT numDimensions)
Float getAnalysisValue() const
bool setOffsetFilterSize(const UINT offsetFilterSize)
bool setSearchWindowSize(const UINT searchWindowSize)
bool init(UINT derivativeOrder, Float delta, UINT numDimensions, bool filterData, UINT filterSize)
bool setDetectionTimeoutMode(const UINT detectionTimeoutMode)
bool getThresholdCrossingDetected() const
This class implements a threshold crossing detector.
bool setHysteresisThreshold(const Float hysteresisThreshold)
signed long getMilliSeconds()
Float computeDerivative(const Float x)
bool getEnableSearch() const
UINT getSearchWindowIndex() const
UINT getOffsetFilterSize() const
UINT getSearchTimeoutDuration() const
bool setAnalysisMode(const UINT analysisMode)
UINT getSearchWindowSize() const
~ThresholdCrossingDetector()
bool setLowerThreshold(const Float lowerThreshold)
Float filter(const Float x)
ThresholdCrossingDetector & operator=(const ThresholdCrossingDetector &rhs)
bool setEnableSearch(const bool enableSearch)
bool setThresholdCrossingMode(const UINT thresholdCrossingMode)
Float getHysteresisThreshold() const
UINT getAnalysisMode() const
bool setSearchTimeoutDuration(const UINT searchTimeoutDuration)
ThresholdCrossingDetector(UINT analysisMode=RAW_DATA_ANALYSIS_MODE, UINT thresholdCrossingMode=UPPER_THRESHOLD_CROSSING, UINT detectionTimeoutMode=TIMEOUT_COUNTER, Float lowerThreshold=-1, Float upperThreshold=1, Float hysteresisThreshold=0, UINT searchWindowSize=20, UINT searchTimeoutDuration=1000, UINT offsetFilterSize=10)
UINT getSearchTimeoutCounter()
Float getLowerThreshold() const
Float getUpperThreshold() const