25 ThresholdCrossingDetector::ThresholdCrossingDetector(UINT analysisMode,UINT thresholdCrossingMode,UINT detectionTimeoutMode,
double lowerThreshold,
double upperThreshold,
double hysteresisThreshold,UINT searchWindowSize,UINT searchTimeoutDuration,UINT offsetFilterSize){
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 double 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;
bool setSearchTimeoutDuration(const UINT searchTimeoutDuration)
UINT getSearchTimeoutDuration() const
bool setThresholdCrossingMode(const UINT thresholdCrossingMode)
bool setDetectionTimeoutMode(const UINT detectionTimeoutMode)
bool getThresholdCrossingDetected() const
ThresholdCrossingDetector(UINT analysisMode=RAW_DATA_ANALYSIS_MODE, UINT thresholdCrossingMode=UPPER_THRESHOLD_CROSSING, UINT detectionTimeoutMode=TIMEOUT_COUNTER, double lowerThreshold=-1, double upperThreshold=1, double hysteresisThreshold=0, UINT searchWindowSize=20, UINT searchTimeoutDuration=1000, UINT offsetFilterSize=10)
UINT getSearchWindowSize() const
bool triggerSearchTimeout()
bool setOffsetFilterSize(const UINT offsetFilterSize)
double filter(const double x)
UINT getOffsetFilterSize() const
bool setAnalysisMode(const UINT analysisMode)
bool setLowerThreshold(const double lowerThreshold)
bool setEnableSearch(const bool enableSearch)
This class implements a threshold crossing detector.
double getLowerThreshold() const
bool update(const double x)
UINT getThresholdCrossingMode() const
bool init(UINT derivativeOrder, double delta, UINT numDimensions, bool filterData, UINT filterSize)
bool setUpperThreshold(const double upperThreshold)
signed long getMilliSeconds() const
~ThresholdCrossingDetector()
bool getEnableSearch() const
double getHysteresisThreshold() const
double getUpperThreshold() const
UINT getAnalysisMode() const
bool setHysteresisThreshold(const double hysteresisThreshold)
UINT getSearchTimeoutCounter() const
double getAnalysisValue() const
ThresholdCrossingDetector & operator=(const ThresholdCrossingDetector &rhs)
bool init(UINT filterSize, UINT numDimensions)
UINT getSearchWindowIndex() const
double computeDerivative(const double x)
bool setSearchWindowSize(const UINT searchWindowSize)