Mercurial > public > ostc4
diff Discovery/Src/motion.c @ 373:7b981f8bdd41 MotionDetection
Add scroll event by pitch angle detection:
Add a function to scroll through the custom view in case the computer is not in the typical center position
Refine Pitch Detection:
Changed implementation to use sectors for detection. Increased detection window
author | ideenmodellierer |
---|---|
date | Sun, 08 Sep 2019 13:45:17 +0200 |
parents | fca370f847f8 |
children | 834e087505ec |
line wrap: on
line diff
--- a/Discovery/Src/motion.c Mon Aug 19 17:50:55 2019 +0200 +++ b/Discovery/Src/motion.c Sun Sep 08 13:45:17 2019 +0200 @@ -7,6 +7,7 @@ #include <stdint.h> #include <string.h> +#include <stdlib.h> #include <math.h> #include "motion.h" #include "data_central.h" @@ -20,21 +21,22 @@ #define PITCH_DELTA_END 10 /* Delta allowed between start and end position */ -#define SECTOR_WINDOW 40.0 /* Pitch window which is used for custom view projection */ +#define SECTOR_WINDOW 80.0 /* Pitch window which is used for custom view projection */ #define SECTOR_HYSTERY 3 /* Additional offset to avoid fast changing displays */ #define SECTOR_BORDER 400.0 /* Define a value which is out of limit to avoid not wanted key events */ #define SECTOR_FILTER 10 /* Define speed for calculated angle to follow real value */ -#define SECTOR_MAX 10 /* maximum number of sectors */ +#define SECTOR_MAX 20 /* maximum number of sectors */ +#define SECTOR_SCROLL 6 /* number of sectors used for scroll detection */ -static detectionState_t detectionState = DETECT_NOTHING; +detectionState_t detectionState = DETECT_NOTHING; -static uint8_t curSector; +uint8_t curSector; static uint8_t targetSector; static uint8_t sectorSize; static uint8_t sectorCount; -SSector PitchSector[10]; /* max number of enabled custom views */ +SSector PitchSector[SECTOR_MAX]; /* max number of enabled custom views */ uint8_t GetSectorForPitch(float pitch) @@ -70,12 +72,13 @@ if(numOfSectors == CUSTOMER_DEFINED_VIEWS) { sectorCount = t7_GetEnabled_customviews(); - if(sectorCount > 5) + if(sectorCount > 7) { - sectorCount = 5; /* more views are hard to manually control */ + sectorCount = 7; /* more views are hard to manually control */ } } else + if(numOfSectors != CUSTOMER_KEEP_LAST_SECTORS) { sectorCount = numOfSectors; } @@ -111,6 +114,8 @@ break; case MOTION_DETECT_MOVE: DefinePitchSectors(0,SECTOR_MAX); break; + case MOTION_DETECT_SCROLL: DefinePitchSectors(0,SECTOR_SCROLL); + break; default: break; } @@ -147,22 +152,184 @@ return PitchEvent; } +/* Check if pitch is not in center position and trigger a button action if needed */ +detectionState_t detectScrollButtonEvent(float curPitch) +{ + static uint8_t delayscroll = 0; /* slow dow the number of scroll events */ + uint8_t PitchEvent = DETECT_NOTHING; + uint8_t newSector; + + if(delayscroll == 0) + { + newSector = GetSectorForPitch(stateRealGetPointer()->lifeData.compass_pitch); + /* for scroll detection the motion windoe is split into 6 sectors => set event accoring to the sector number*/ + switch(newSector) + { + case 0: + case 1: PitchEvent = DETECT_POS_PITCH; + break; + case 4: + case 5: PitchEvent = DETECT_NEG_PITCH; + break; + default: + break; + } + if(PitchEvent != DETECT_NOTHING) + { + delayscroll = 5; + } + } + else + { + delayscroll--; + } + return PitchEvent; +} + + +uint8_t sectorhist[20]; +uint8_t sectorindex = 0; /* Detect if user is generating an pitch including return to starting position */ /* This is done by feeding the past movements value per value into a state machine */ detectionState_t detectPitch(float currentPitch) { + static uint8_t lastSector = 0; + static uint8_t startSector = 0; static uint8_t stableCnt = 0; - static float lastPitch = 0.0; - static float startPitch = 0.0; - float curSpeed; - if((detectionState == DETECT_NEG_PITCH) || (detectionState == DETECT_POS_PITCH)) /* discard last detection */ { detectionState = DETECT_NOTHING; } + curSector = GetSectorForPitch(stateRealGetPointer()->lifeData.compass_pitch); + + sectorhist[sectorindex++] = curSector; + if(sectorindex == 20) sectorindex=0; + + /* feed value into state machine */ + switch (detectionState) + { + case DETECT_NOTHING: if(curSector == lastSector) /* detect a stable condition before evaluating for the next move */ + { + stableCnt++; + } + else + { + stableCnt=0; + } + + if(stableCnt > STABLE_STATE_COUNT) + { + detectionState = DETECT_START; + stableCnt = 0; + startSector = lastSector; + } + break; + case DETECT_START: if(curSector != lastSector) + { + if(abs(curSector - startSector) > 1) + { + if(curSector > lastSector) + { + detectionState = DETECT_POS_MOVE; + } + else + { + detectionState = DETECT_NEG_MOVE; + } + stableCnt = 0; + startSector = lastSector; + } + else + { + stableCnt++; /* reset start sector in case of slow movement */ + } + // startPitch = lastPitch; + } + break; + case DETECT_NEG_MOVE: + case DETECT_POS_MOVE: if(curSector != lastSector) /* still moving? */ + { + stableCnt++; + } + else + { + // if(stableCnt >= 1) /* debounce movement */ + { + if(abs(startSector - curSector) > 2) + { + detectionState++; + stableCnt = 0; + } + else + { + // detectionState = DETECT_NOTHING; + stableCnt++; /* maybe on the boundary of a sector => handle as stable */ + } + } +#if 0 + else + { + // detectionState = DETECT_NOTHING; + stableCnt++; /* maybe on the boundary of a sector => handle as stable */ + } +#endif + } + break; + case DETECT_MINIMA: + case DETECT_MAXIMA: /* stay at maximum for short time to add a pattern for user interaction */ + if(curSector == lastSector) + { + stableCnt++; + } + else + { + if(stableCnt > 0) /* restart movement after a short break? */ + { + detectionState++; + stableCnt = 0; + } + else + { + // detectionState = DETECT_NOTHING; + stableCnt++; /* maybe on the boundary of a sector => handle as stable */ + } + } + break; + case DETECT_RISEBACK: + case DETECT_FALLBACK: if(curSector == lastSector) /* check if we are back at start position at end of movement */ + { + if(abs(startSector - curSector) <= 1) //(curSector == startSector) + { + detectionState++; + stableCnt = 0; + } + else + { + // detectionState = DETECT_NOTHING; + stableCnt++; /* maybe on the boundary of a sector => handle as stable */ + } + } + else + { + stableCnt++; + } + break; + default: + detectionState = DETECT_NOTHING; + break; + + } + lastSector = curSector; + if(stableCnt > STABLE_STATE_TIMEOUT) + { + detectionState = DETECT_NOTHING; + stableCnt = 0; + } + +#if 0 curSpeed = currentPitch - lastPitch; /* feed value into state machine */ @@ -263,5 +430,6 @@ } lastPitch = currentPitch; +#endif return detectionState; }