Mercurial > public > ostc4
changeset 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 | 75eedde05ff6 |
children | ef1b8579166c |
files | Discovery/Inc/motion.h Discovery/Inc/text_multilanguage.h Discovery/Src/base.c Discovery/Src/motion.c Discovery/Src/tMenuEditSystem.c Discovery/Src/text_multilanguage.c |
diffstat | 6 files changed, 210 insertions(+), 22 deletions(-) [+] |
line wrap: on
line diff
--- a/Discovery/Inc/motion.h Mon Aug 19 17:50:55 2019 +0200 +++ b/Discovery/Inc/motion.h Sun Sep 08 13:45:17 2019 +0200 @@ -10,13 +10,15 @@ /* exported data types */ -#define CUSTOMER_DEFINED_VIEWS (100u) /* value will cause the function to detect the numer of selected views */ +#define CUSTOMER_DEFINED_VIEWS (100u) /* value will cause the function to detect the number of selected views */ +#define CUSTOMER_KEEP_LAST_SECTORS (200u) /* do not update number of sectors, just define the new center position */ typedef enum { MOTION_DETECT_OFF = 0, MOTION_DETECT_SECTOR, - MOTION_DETECT_MOVE + MOTION_DETECT_MOVE, + MOTION_DETECT_SCROLL } MotionDetectMethod_t; typedef enum @@ -43,5 +45,6 @@ void DefinePitchSectors(float centerAngle, uint8_t numOfSectors); detectionState_t detectPitch(float currentPitch); detectionState_t detectSectorButtonEvent(float curPitch); +detectionState_t detectScrollButtonEvent(float curPitch); #endif /* INC_MOTION_H_ */
--- a/Discovery/Inc/text_multilanguage.h Mon Aug 19 17:50:55 2019 +0200 +++ b/Discovery/Inc/text_multilanguage.h Sun Sep 08 13:45:17 2019 +0200 @@ -278,6 +278,7 @@ TXT2BYTE_MoCtrlNone, TXT2BYTE_MoCtrlPitch, TXT2BYTE_MoCtrlSector, + TXT2BYTE_MoCtrlScroll, /* */ TXT2BYTE_DecoDataLost, TXT2BYTE_Info,
--- a/Discovery/Src/base.c Mon Aug 19 17:50:55 2019 +0200 +++ b/Discovery/Src/base.c Sun Sep 08 13:45:17 2019 +0200 @@ -494,6 +494,8 @@ break; case MOTION_DETECT_SECTOR: pitchstate = detectSectorButtonEvent(stateRealGetPointer()->lifeData.compass_pitch); break; + case MOTION_DETECT_SCROLL: pitchstate = detectScrollButtonEvent(stateRealGetPointer()->lifeData.compass_pitch); + break; default: pitchstate = DETECT_NOTHING; break; @@ -902,9 +904,9 @@ if ((status.page == PageDive) && (status.line == 0)) { tHome_change_customview_button_pressed(action); - if((settingsGetPointer()->MotionDetection == MOTION_DETECT_SECTOR) && (action == ACTION_BUTTON_ENTER)) /* Button pressed while sector detection is active => calibrate to current pitch value */ + if((settingsGetPointer()->MotionDetection != MOTION_DETECT_OFF) && (action == ACTION_BUTTON_ENTER)) /* Button pressed while motion detection is active => calibrate to current pitch value */ { - DefinePitchSectors(stateRealGetPointer()->lifeData.compass_pitch,CUSTOMER_DEFINED_VIEWS); + DefinePitchSectors(stateRealGetPointer()->lifeData.compass_pitch,CUSTOMER_KEEP_LAST_SECTORS); } } else if (status.page == PageSurface)
--- 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; }
--- a/Discovery/Src/tMenuEditSystem.c Mon Aug 19 17:50:55 2019 +0200 +++ b/Discovery/Src/tMenuEditSystem.c Sun Sep 08 13:45:17 2019 +0200 @@ -155,6 +155,7 @@ pSettings->cv_configuration ^= 1 << (cv_changelist[line-1]); WriteSettings = 1; + InitMotionDetection(); /* consider new view setup for view selection by motion */ exitMenuEdit_to_Menu_with_Menu_Update(); } @@ -925,6 +926,9 @@ case MOTION_DETECT_SECTOR: text[5] = TXT2BYTE_MoCtrlSector; break; + case MOTION_DETECT_SCROLL: + text[5] = TXT2BYTE_MoCtrlScroll; + break; default: snprintf(&text[4],2,"%u",settingsGetPointer()->MotionDetection); break; @@ -1075,20 +1079,24 @@ uint8_t newValue; switch(settingsGetPointer()->MotionDetection) { - case 0: - newValue = 1; + case MOTION_DETECT_OFF: + newValue = MOTION_DETECT_MOVE; break; - case 1: - newValue = 2; + case MOTION_DETECT_MOVE: + newValue = MOTION_DETECT_SECTOR; break; - case 2: - newValue = 0; + case MOTION_DETECT_SECTOR: + newValue = MOTION_DETECT_SCROLL; break; + case MOTION_DETECT_SCROLL: + newValue = MOTION_DETECT_OFF; + break; default: - newValue = 0; + newValue = MOTION_DETECT_OFF; break; } settingsGetPointer()->MotionDetection = newValue; + InitMotionDetection(); return UNSPECIFIC_RETURN; }
--- a/Discovery/Src/text_multilanguage.c Mon Aug 19 17:50:55 2019 +0200 +++ b/Discovery/Src/text_multilanguage.c Sun Sep 08 13:45:17 2019 +0200 @@ -1287,6 +1287,11 @@ static uint8_t text_IT_MoCtrlSector[] = "Sector"; static uint8_t text_ES_MoCtrlSector[] = "Sector"; +static uint8_t text_EN_MoCtrlScroll[] = "Scroll"; +static uint8_t text_DE_MoCtrlScroll[] = "Karussell"; +static uint8_t text_FR_MoCtrlScroll[] = "Scroll"; +static uint8_t text_IT_MoCtrlScroll[] = "Scroll"; +static uint8_t text_ES_MoCtrlScroll[] = "Scroll"; // Menu SYS2 Reset RTE and Firmware Update During Bluetooth Connection static uint8_t text_EN_DecoDataLost[] = "Decompression data will be lost"; @@ -1746,6 +1751,7 @@ {(uint8_t)TXT2BYTE_MoCtrlNone, {text_EN_MoCtrlNone, text_DE_MoCtrlNone, text_FR_MoCtrlNone, text_IT_MoCtrlNone, text_ES_MoCtrlNone}}, {(uint8_t)TXT2BYTE_MoCtrlPitch, {text_EN_MoCtrlPitch, text_DE_MoCtrlPitch, text_FR_MoCtrlPitch, text_IT_MoCtrlPitch, text_ES_MoCtrlPitch}}, {(uint8_t)TXT2BYTE_MoCtrlSector, {text_EN_MoCtrlSector, text_DE_MoCtrlSector, text_FR_MoCtrlSector, text_IT_MoCtrlSector, text_ES_MoCtrlSector}}, + {(uint8_t)TXT2BYTE_MoCtrlScroll, {text_EN_MoCtrlScroll, text_DE_MoCtrlScroll, text_FR_MoCtrlScroll, text_IT_MoCtrlScroll, text_ES_MoCtrlScroll}}, {(uint8_t)TXT2BYTE_DecoDataLost, {text_EN_DecoDataLost, text_DE_DecoDataLost, text_FR_DecoDataLost, text_IT_DecoDataLost, text_ES_DecoDataLost}}, {(uint8_t)TXT2BYTE_Info, {text_EN_Info, text_DE_Info, text_FR_Info, text_IT_Info, text_ES_Info}}, {(uint8_t)TXT2BYTE_Korrekturwerte, {text_EN_Korrekturwerte, text_DE_Korrekturwerte, text_FR_Korrekturwerte, text_IT_Korrekturwerte, text_ES_Korrekturwerte}},