Mercurial > public > ostc4
diff Discovery/Src/motion.c @ 363:bdf978d2a5d4 MotionDetection
Reworked detection function
The first implementation was not stable enough during underwater tests => redesign taking speed deltas into account
author | ideenmodellierer |
---|---|
date | Mon, 17 Jun 2019 19:46:18 +0200 |
parents | 7b8c87a39c0e |
children | 77cdfbdaca8c |
line wrap: on
line diff
--- a/Discovery/Src/motion.c Tue Jun 11 05:31:07 2019 +0200 +++ b/Discovery/Src/motion.c Mon Jun 17 19:46:18 2019 +0200 @@ -10,250 +10,123 @@ #include <math.h> #include "motion.h" -#define PITCH_HISTORY_ENTRIES 20 /* number of pitch value stored in buffer */ #define STABLE_STATE_COUNT 2 /* number of count to declare a state as stable (at the moment based on 100ms) */ -#define MOVE_DELTA_COUNT 10 /* Delta count needed to identify a valid movement */ -#define SHAKE_DELTA_COUNT 30 /* Delta count needed to identify a valid minima / maxima */ - - -typedef enum -{ - RELATIVE_MOVE_STATIC = 0, - RELATIVE_MOVE_INCREASE, - RELATIVE_MOVE_DECREASE, - RELATIVE_MOVE_INVALID -} relativeMove_t; - - - - +#define STABLE_STATE_TIMEOUT 5 /* Detection shall be aborted if a movement state is stable for more than 500ms */ +#define MOVE_DELTA_SPEED 4 /* Delta speed needed to identify a valid movement */ +#define SHAKE_DELTA_COUNT 10 /* Delta count needed to identify a valid minima / maxima */ +#define SHAKE_DELTA_END 10 /* Delta allowed between start and end position */ -float pitchHistory[PITCH_HISTORY_ENTRIES]; /* Ringbuffer of last read pich values */ -static uint8_t pitchWriteIdx; /* Index of current write slot */ - -/* Init data structures */ -void InitMotion() -{ - uint8_t tmp; - - for(tmp = 0; tmp < PITCH_HISTORY_ENTRIES; tmp++) - { - pitchHistory[tmp] = 0; - } - pitchWriteIdx = 0; - -} - -detectionState_t detectionState = DETECT_NOTHING; +static detectionState_t detectionState = DETECT_NOTHING; /* Detect if user is generating an pitch including return to starting position (shake) */ /* This is done by feeding the past movements value per value into a state machine */ detectionState_t detectShake(float currentPitch) { - static uint8_t runningIdx = 0; static uint8_t stableCnt = 0; static float lastPitch = 0.0; static float startPitch = 0.0; - - relativeMove_t relativeMove = RELATIVE_MOVE_INVALID; - - - pitchHistory[pitchWriteIdx] = currentPitch; - runningIdx = pitchWriteIdx; -#if 0 - runningIdx = pitchWriteIdx + 1; - - if(runningIdx == PITCH_HISTORY_ENTRIES) - { - runningIdx = 0; - } -#endif + static float minmax = 0.0; + float curSpeed; if((detectionState == DETECT_NEG_SHAKE) || (detectionState == DETECT_POS_SHAKE)) /* discard last detection */ { detectionState = DETECT_NOTHING; } -// do -// { -// lastPitch = pitchHistory[runningIdx]; -#if 0 - runningIdx++; - if(runningIdx == PITCH_HISTORY_ENTRIES) - { - runningIdx = 0; - } -#endif - /* define relative movement compared to last position */ - if(fabsf(lastPitch - pitchHistory[runningIdx]) < MOVE_DELTA_COUNT ) /* more or less no movement */ - { - relativeMove = RELATIVE_MOVE_STATIC; - stableCnt++; - } - else - { - if(lastPitch > pitchHistory[runningIdx]) /* decreasing */ - { - relativeMove = RELATIVE_MOVE_DECREASE; - } - else - { - relativeMove = RELATIVE_MOVE_INCREASE; /* increasing */ - } - } + + curSpeed = currentPitch - lastPitch; - /* feed value into statemachine */ - switch (detectionState) - { - case DETECT_NOTHING: if(relativeMove == RELATIVE_MOVE_STATIC) + /* feed value into state machine */ + switch (detectionState) + { + case DETECT_NOTHING: if(fabsf(curSpeed) < MOVE_DELTA_SPEED) /* detect a stable condition before evaluating for the next move */ { - if(stableCnt > 4) - { - detectionState = DETECT_START; - startPitch = lastPitch; - } + stableCnt++; + } + if(stableCnt > STABLE_STATE_COUNT) + { + detectionState = DETECT_START; + stableCnt = 0; } break; - case DETECT_START: switch(relativeMove) + case DETECT_START: if(fabsf(curSpeed) > MOVE_DELTA_SPEED) { - case RELATIVE_MOVE_INCREASE: detectionState = DETECT_POS_MOVE; - break; - case RELATIVE_MOVE_DECREASE: detectionState = DETECT_NEG_MOVE; - break; - default: - break; + if(curSpeed > 0) + { + detectionState = DETECT_POS_MOVE; + } + else + { + detectionState = DETECT_NEG_MOVE; + } + stableCnt = 0; + startPitch = lastPitch; } break; - case DETECT_POS_MOVE: switch(relativeMove) - { - case RELATIVE_MOVE_INCREASE: detectionState = DETECT_POS_MOVE; - break; - case RELATIVE_MOVE_STATIC: if(fabsf(startPitch - lastPitch) > SHAKE_DELTA_COUNT) - { - detectionState = DETECT_MAXIMA; - } - else - { - detectionState = DETECT_NOTHING; - } - break; - default: - detectionState = DETECT_NOTHING; - break; - } - break; - case DETECT_NEG_MOVE: switch(relativeMove) + case DETECT_NEG_MOVE: + case DETECT_POS_MOVE: if(fabsf(curSpeed) > MOVE_DELTA_SPEED ) { - case RELATIVE_MOVE_DECREASE: detectionState = DETECT_NEG_MOVE; - break; - case RELATIVE_MOVE_STATIC: if(fabsf(startPitch - lastPitch) > SHAKE_DELTA_COUNT) /* significant movment */ - { - detectionState = DETECT_MINIMA; - } - else - { - detectionState = DETECT_NOTHING; - } - break; - default: - detectionState = DETECT_NOTHING; - break; - } - break; - case DETECT_MAXIMA: if((relativeMove != RELATIVE_MOVE_STATIC) && (stableCnt < STABLE_STATE_COUNT )) - { - detectionState = DETECT_NOTHING; + stableCnt++; } else { - if(relativeMove == RELATIVE_MOVE_DECREASE) + if(stableCnt >= STABLE_STATE_COUNT) /* debounce movement */ { - detectionState = DETECT_FALLBACK; + if(fabsf(startPitch - currentPitch) > SHAKE_DELTA_COUNT) + { + detectionState++; + minmax = lastPitch; + } + else + { + detectionState = DETECT_NOTHING; + } } - if(relativeMove == RELATIVE_MOVE_INCREASE) + else { - detectionState = DETECT_POS_MOVE; + detectionState = DETECT_NOTHING; } + stableCnt = 0; } break; - case DETECT_MINIMA: if((relativeMove != RELATIVE_MOVE_STATIC) && (stableCnt < STABLE_STATE_COUNT )) + case DETECT_MINIMA: + case DETECT_MAXIMA: if(fabsf(currentPitch - minmax ) < SHAKE_DELTA_COUNT) /* stay at maximum for short time to add a pattern for user interaction */ { - detectionState = DETECT_NOTHING; + stableCnt++; } else { - if(relativeMove == RELATIVE_MOVE_DECREASE) + if(stableCnt > 0) { - detectionState = DETECT_NEG_MOVE; - } - if(relativeMove == RELATIVE_MOVE_INCREASE) - { - detectionState = DETECT_RISEBACK; + detectionState++; } - } - break; - - case DETECT_FALLBACK: switch(relativeMove) - { - case RELATIVE_MOVE_DECREASE: detectionState = DETECT_FALLBACK; - break; - case RELATIVE_MOVE_STATIC: if( stableCnt >= STABLE_STATE_COUNT) - { - if(fabsf(startPitch - lastPitch) < MOVE_DELTA_COUNT) /* are we where started, again? */ - { - detectionState = DETECT_POS_SHAKE; - memset(pitchHistory, 0, sizeof(pitchHistory)); - } - else - { - detectionState = DETECT_START; /* start new detection */ - startPitch = lastPitch; - } - } - break; - default: + else + { detectionState = DETECT_NOTHING; - break; + } + stableCnt = 0; } break; - case DETECT_RISEBACK: switch(relativeMove) + case DETECT_RISEBACK: + case DETECT_FALLBACK: if(fabsf(curSpeed) < MOVE_DELTA_SPEED) { - case RELATIVE_MOVE_INCREASE: detectionState = DETECT_RISEBACK; - break; - case RELATIVE_MOVE_STATIC: if(stableCnt >= STABLE_STATE_COUNT) - { - if(fabsf(startPitch - lastPitch) < MOVE_DELTA_COUNT) - { - detectionState = DETECT_NEG_SHAKE; - memset(pitchHistory, 0, sizeof(pitchHistory)); - } - else - { - detectionState = DETECT_START; - startPitch = lastPitch; - } - } - break; - default: - detectionState = DETECT_NOTHING; - break; + if(fabsf(startPitch - currentPitch) < SHAKE_DELTA_END) + { + detectionState++; + } } + stableCnt++; + break; + default: + detectionState = DETECT_NOTHING; break; - default: - break; - - } - if(relativeMove != RELATIVE_MOVE_STATIC) /* reset counter for stable time detection */ - { - stableCnt = 0; - } -// } while ((runningIdx != pitchWriteIdx) && (detectionState != DETECT_NEG_SHAKE) && (detectionState != DETECT_POS_SHAKE)); + } + if(stableCnt > STABLE_STATE_TIMEOUT) + { + detectionState = DETECT_NOTHING; + stableCnt = 0; + } lastPitch = currentPitch; - pitchWriteIdx++; - if(pitchWriteIdx == PITCH_HISTORY_ENTRIES) - { - pitchWriteIdx = 0; - } return detectionState; }