21 #define GRT_DLL_EXPORTS 26 PeakDetection::PeakDetection(
const UINT lowPassFilterSize,
const UINT searchWindowSize){
28 this->lowPassFilterSize = lowPassFilterSize;
29 this->searchWindowSize = searchWindowSize;
31 inputTimeoutCounter = 0;
34 inputTimeoutLimit = 10;
35 searchHistorySize = 10;
36 deadZoneThreshold = 0.01;
40 setSearchWindowSize( searchWindowSize );
45 this->lowPassFilterSize = rhs.lowPassFilterSize;
46 this->searchWindowSize = rhs.searchWindowSize;
47 this->lowPassFilter = rhs.lowPassFilter;
50 PeakDetection::~PeakDetection(){
56 this->lowPassFilterSize = rhs.lowPassFilterSize;
57 this->searchWindowSize = rhs.searchWindowSize;
58 this->lowPassFilter = rhs.lowPassFilter;
63 bool PeakDetection::update(
const Float x){
66 if( ++inputTimeoutCounter >= inputTimeoutLimit ){
67 inputTimeoutCounter = inputTimeoutLimit;
69 }
else enableSearch =
false;
75 Float filteredValue = lowPassFilter.
filter(x);
78 Float firstDeriv = filteredValue - filteredDataBuffer.
getBack();
81 Float secondDeriv = firstDeriv - firstDerivBuffer.
getBack();
84 secondDeriv = deadZoneFilter.
filter( secondDeriv );
87 filteredDataBuffer.
push_back( filteredValue );
89 secondDerivBuffer.
push_back( secondDeriv );
92 unsigned int peakType = NO_PEAK_FOUND;
95 globalMaximaPeakInfo.peakType = NO_PEAK_FOUND;
96 globalMinimaPeakInfo.peakType = NO_PEAK_FOUND;
99 if( ++maximaCounter >= searchHistorySize ){
101 globalMaximaPeakInfo.peakValue = DEFAULT_GLOBAL_MAXIMA_VALUE;
105 if( ++minimaCounter >= searchHistorySize ){
107 globalMinimaPeakInfo.peakValue = DEFAULT_GLOBAL_MINIMA_VALUE;
111 for(
unsigned int i=1; i<searchWindowSize-1; i++){
112 peakType = NO_PEAK_FOUND;
113 if( (secondDerivBuffer[i-1] <= 0 && secondDerivBuffer[i] > 0) || (secondDerivBuffer[i-1] <= 0 && secondDerivBuffer[i+1] > 0) ){
116 peakType = LOCAL_MAXIMA_FOUND;
119 if( filteredDataBuffer[i] > globalMaximaPeakInfo.peakValue ){
121 globalMaximaPeakInfo.peakType = GLOBAL_MAXIMA_FOUND;
122 globalMaximaPeakInfo.peakIndex = i;
123 globalMaximaPeakInfo.peakValue = filteredDataBuffer[i];
126 peakInfo.push_back(
PeakInfo(peakType,i,filteredDataBuffer[i]) );
131 if( (secondDerivBuffer[i-1] >= 0 && secondDerivBuffer[i] < 0) || (secondDerivBuffer[i-1] >= 0 && secondDerivBuffer[i+1] < 0) ){
134 peakType = LOCAL_MINIMA_FOUND;
136 if( filteredDataBuffer[i] < globalMinimaPeakInfo.peakValue ){
138 globalMinimaPeakInfo.peakType = GLOBAL_MINIMA_FOUND;
139 globalMinimaPeakInfo.peakIndex = i;
140 globalMinimaPeakInfo.peakValue = filteredDataBuffer[i];
143 peakInfo.push_back(
PeakInfo(peakType,i,filteredDataBuffer[i]) );
151 return peakDetected ?
true :
false;
154 bool PeakDetection::reset(){
156 lowPassFilter.
init(lowPassFilterSize,1);
159 deadZoneFilter.
init(-deadZoneThreshold,deadZoneThreshold,1);
162 filteredDataBuffer.
clear();
163 firstDerivBuffer.
clear();
164 secondDerivBuffer.
clear();
165 peakTypesBuffer.
clear();
167 filteredDataBuffer.
resize( searchWindowSize, 0 );
168 firstDerivBuffer.
resize( searchWindowSize, 0 );
169 secondDerivBuffer.
resize( searchWindowSize, 0 );
170 peakTypesBuffer.
resize( searchWindowSize, NO_PEAK_FOUND );
173 peakDetected =
false;
174 inputTimeoutCounter = 0;
178 globalMaximaPeakInfo.peakType = NO_PEAK_FOUND;
179 globalMaximaPeakInfo.peakIndex = 0;
180 globalMaximaPeakInfo.peakValue = DEFAULT_GLOBAL_MAXIMA_VALUE;
181 globalMinimaPeakInfo.peakType = NO_PEAK_FOUND;
182 globalMinimaPeakInfo.peakIndex = 0;
183 globalMinimaPeakInfo.peakValue = DEFAULT_GLOBAL_MINIMA_VALUE;
188 bool PeakDetection::setSearchWindowSize(
const UINT searchWindowSize){
189 this->searchWindowSize = searchWindowSize;
bool push_back(const T &value)
Float filter(const Float x)
Float filter(const Float x)
bool init(UINT filterSize, UINT numDimensions)
bool init(Float lowerLimit, Float upperLimit, UINT numDimensions)
bool resize(const unsigned int newBufferSize)