Mercurial > public > ostc4
comparison Discovery/Src/motion.c @ 574:01ee21dd311f
Improved focus detection:
In previous version th calibration window was turned into the current one. At all two translations were used causing a jitter. Now the current view is translated into the calibration windows by one step increasing the quality of the prediction.
Reworked detection of pitch/sector/scroll events:
Sector and scroll uses pitch angles to calculate the view to show. Movment detection uses movment, which may also be out of focus for a short time. To improve all detections these two use cases are now handled individual. Sector and scroll have increased action angle in case yaw and roll stay stable.
author | Ideenmodellierer |
---|---|
date | Wed, 25 Nov 2020 20:26:01 +0100 |
parents | e3237f580ae9 |
children | beb4d47542f1 |
comparison
equal
deleted
inserted
replaced
573:f9c6ef098275 | 574:01ee21dd311f |
---|---|
31 #define MOTION_DELTA_JITTER 1 | 31 #define MOTION_DELTA_JITTER 1 |
32 #define MOTION_DELTA_RAISE 2 | 32 #define MOTION_DELTA_RAISE 2 |
33 #define MOTION_DELTA_FALL 3 | 33 #define MOTION_DELTA_FALL 3 |
34 | 34 |
35 #define MOTION_DELTA_JITTER_LEVEL 3.0 /* lower values are considered as stable */ | 35 #define MOTION_DELTA_JITTER_LEVEL 3.0 /* lower values are considered as stable */ |
36 #define MOTION_DELTA_RAISE_LEVEL 6.0 /* Movement causing a significant change detected */ | 36 #define MOTION_DELTA_RAISE_LEVEL 6.0 /* Movement causing a significant change detected */ |
37 #define MOTION_DELTA_FALL_LEVEL -6.0 /* Movement causing a significant change detected */ | 37 #define MOTION_DELTA_FALL_LEVEL -6.0 /* Movement causing a significant change detected */ |
38 | 38 |
39 #define MOTION_DELTA_HISTORY_SIZE 20 /* Number of history data sets */ | 39 #define MOTION_DELTA_HISTORY_SIZE 20 /* Number of history data sets */ |
40 | 40 |
41 detectionState_t detectionState = DETECT_NOTHING; | 41 detectionState_t detectionState = DETECT_NOTHING; |
269 { | 269 { |
270 newSector = GetSectorForPitch(stateRealGetPointer()->lifeData.compass_pitch); | 270 newSector = GetSectorForPitch(stateRealGetPointer()->lifeData.compass_pitch); |
271 /* for scroll detection the motion window is split into 6 sectors => set event accoring to the sector number*/ | 271 /* for scroll detection the motion window is split into 6 sectors => set event accoring to the sector number*/ |
272 switch(newSector) | 272 switch(newSector) |
273 { | 273 { |
274 case 0: | 274 case 0: PitchEvent = DETECT_POS_PITCH; |
275 case 1: PitchEvent = DETECT_POS_PITCH; | |
276 break; | 275 break; |
277 case 5: | |
278 case 6: PitchEvent = DETECT_NEG_PITCH; | 276 case 6: PitchEvent = DETECT_NEG_PITCH; |
279 break; | 277 break; |
280 default: | 278 default: |
281 break; | 279 break; |
282 } | 280 } |
283 if(PitchEvent != DETECT_NOTHING) | 281 if(PitchEvent != DETECT_NOTHING) |
284 { | 282 { |
285 delayscroll = 5; | 283 delayscroll = 7; |
286 } | 284 } |
287 } | 285 } |
288 else | 286 else |
289 { | 287 { |
290 delayscroll--; | 288 delayscroll--; |
297 /* This is done by feeding the past movements value per value into a state machine */ | 295 /* This is done by feeding the past movements value per value into a state machine */ |
298 detectionState_t detectPitch(float currentPitch) | 296 detectionState_t detectPitch(float currentPitch) |
299 { | 297 { |
300 uint8_t exit = 0; | 298 uint8_t exit = 0; |
301 uint8_t step = 0; | 299 uint8_t step = 0; |
300 uint8_t duration = 0; | |
302 SDeltaHistory test; | 301 SDeltaHistory test; |
303 | 302 |
304 detectionState = DETECT_NOTHING; | 303 detectionState = DETECT_NOTHING; |
305 while((step != MOTION_DELTA_HISTORY_SIZE) && (!exit)) /* start backward evalution of pitch changes*/ | 304 while((step != MOTION_DELTA_HISTORY_SIZE) && (!exit)) /* start backward evalution of pitch changes*/ |
306 { | 305 { |
307 test = GetDeltaHistory(step); | 306 test = GetDeltaHistory(step); |
308 step++; | 307 step++; |
308 duration++; | |
309 switch (detectionState) | 309 switch (detectionState) |
310 { | 310 { |
311 case DETECT_NOTHING: if(test.pitch > MOTION_DELTA_STABLE) | 311 case DETECT_NOTHING: if(test.pitch > MOTION_DELTA_STABLE) |
312 { | 312 { |
313 exit = 1; | 313 exit = 1; |
323 } | 323 } |
324 if(test.pitch == MOTION_DELTA_FALL) | 324 if(test.pitch == MOTION_DELTA_FALL) |
325 { | 325 { |
326 detectionState = DETECT_NEG_MOVE; | 326 detectionState = DETECT_NEG_MOVE; |
327 } | 327 } |
328 duration = 0; | |
328 break; | 329 break; |
329 case DETECT_NEG_MOVE: | 330 case DETECT_NEG_MOVE: |
330 case DETECT_POS_MOVE: if(test.pitch <= MOTION_DELTA_JITTER) | 331 case DETECT_POS_MOVE: if(test.pitch <= MOTION_DELTA_JITTER) |
331 { | 332 { |
332 detectionState++; | 333 detectionState++; |
343 } | 344 } |
344 break; | 345 break; |
345 case DETECT_RISEBACK: | 346 case DETECT_RISEBACK: |
346 case DETECT_FALLBACK: if(test.pitch == MOTION_DELTA_STABLE) | 347 case DETECT_FALLBACK: if(test.pitch == MOTION_DELTA_STABLE) |
347 { | 348 { |
348 detectionState++; | 349 if(duration > 5) /* avoid detection triggered by short moves */ |
349 exit = 1; | 350 { |
351 detectionState++; | |
352 exit = 1; | |
353 } | |
354 else | |
355 { | |
356 detectionState = DETECT_NOTHING; | |
357 } | |
350 } | 358 } |
351 break; | 359 break; |
352 default: | 360 default: |
353 detectionState = DETECT_NOTHING; | 361 detectionState = DETECT_NOTHING; |
354 exit = 1; | 362 exit = 1; |
443 } | 451 } |
444 | 452 |
445 | 453 |
446 float checkViewport(float roll, float pitch, float yaw) | 454 float checkViewport(float roll, float pitch, float yaw) |
447 { | 455 { |
456 static float freezeRoll = 0; | |
457 static float freezeYaw = 0; | |
458 | |
448 uint8_t retval = 0; | 459 uint8_t retval = 0; |
449 float angleYaw; | 460 float angleYaw; |
450 float anglePitch; | 461 float anglePitch; |
451 float angleRoll; | 462 float angleRoll; |
452 float distance = 0; | 463 float distance = 0; |
457 SCoord refVec; | 468 SCoord refVec; |
458 SCoord axis_1; | 469 SCoord axis_1; |
459 SCoord axis_2; | 470 SCoord axis_2; |
460 SCoord curVec; | 471 SCoord curVec; |
461 SCoord resultVec; | 472 SCoord resultVec; |
473 SDeltaHistory test; | |
462 | 474 |
463 SSettings* pSettings = settingsGetPointer(); | 475 SSettings* pSettings = settingsGetPointer(); |
464 | 476 |
465 /* calculate base vector taking calibration delta into account yaw (heading) */ | 477 /* calculate base vector taking calibration delta into account yaw (heading) */ |
466 float compYaw = yaw + pSettings->viewYaw; | 478 float compYaw = yaw + pSettings->viewYaw; |
479 | |
480 compYaw = 360.0 - yaw; /* turn to 0° */ | |
481 compYaw += pSettings->viewYaw; /* consider calib yaw value */ | |
482 compYaw += yaw; | |
483 | |
467 if (compYaw < 0.0) | 484 if (compYaw < 0.0) |
468 { | 485 { |
469 compYaw = 360.0 + compYaw; | 486 compYaw = 360.0 + compYaw; |
470 } | 487 } |
471 | 488 |
472 if (compYaw > 360.0) | 489 if (compYaw > 360.0) |
473 { | 490 { |
474 compYaw = compYaw - 360.0;; | 491 compYaw = compYaw - 360.0; |
475 } | 492 } |
476 | 493 if (compYaw > 360.0) |
477 angleYaw = compYaw * M_PI / 180.0; | 494 { |
495 compYaw = compYaw - 360.0; | |
496 } | |
497 angleYaw = pSettings->viewYaw * M_PI / 180.0; | |
478 anglePitch = pSettings->viewPitch * M_PI / 180.0; | 498 anglePitch = pSettings->viewPitch * M_PI / 180.0; |
479 angleRoll = pSettings->viewRoll * M_PI / 180.0; | 499 angleRoll = pSettings->viewRoll * M_PI / 180.0; |
480 | 500 |
481 refVec.x = 0; | 501 refVec.x = 0; |
482 refVec.y = 0; | 502 refVec.y = 0; |
507 { | 527 { |
508 retval = 2; | 528 retval = 2; |
509 } | 529 } |
510 else | 530 else |
511 { | 531 { |
512 angleYaw = yaw * M_PI / 180.0; | 532 angleYaw = compYaw * M_PI / 180.0; |
513 anglePitch = pitch * M_PI / 180.0; | 533 anglePitch = pitch * M_PI / 180.0; |
514 angleRoll = roll * M_PI / 180.0; | 534 angleRoll = roll * M_PI / 180.0; |
515 curVec.x = 0; | 535 curVec.x = 0; |
516 curVec.y = 0; | 536 curVec.y = 0; |
517 curVec.z = 1.0; | 537 curVec.z = 1.0; |
564 { | 584 { |
565 resetMotionDeltaHistory(); | 585 resetMotionDeltaHistory(); |
566 } | 586 } |
567 focusCnt++; | 587 focusCnt++; |
568 } | 588 } |
569 if(focusCnt == 10) | 589 if((focusCnt == 10) && (inFocus == 0)) |
570 { | 590 { |
571 inFocus = 1; | 591 inFocus = 1; |
592 freezeRoll = roll; | |
593 freezeYaw = yaw; | |
572 } | 594 } |
573 } | 595 } |
574 else | 596 else |
575 { | 597 { |
576 if(focusCnt) | 598 if(focusCnt >= 5) /* Reset focus faster then setting focus */ |
577 { | 599 { |
600 if(pSettings->MotionDetection != MOTION_DETECT_MOVE) /* only apply extended focus for methods using absolute pitch values */ | |
601 { | |
602 test = GetDeltaHistory(0); | |
603 if((test.yaw == MOTION_DELTA_STABLE) && (test.roll == MOTION_DELTA_STABLE)) | |
604 { | |
605 if((fabsf(freezeRoll - roll) < MOTION_DELTA_JITTER_LEVEL) && (fabsf(freezeYaw - yaw) < MOTION_DELTA_JITTER_LEVEL)) | |
606 { | |
607 focusCnt++; | |
608 } | |
609 } | |
610 else | |
611 { | |
612 if(freezeRoll != 0.0) | |
613 { | |
614 focusCnt = 1; | |
615 } | |
616 } | |
617 } | |
578 focusCnt--; | 618 focusCnt--; |
579 } | 619 } |
580 else | 620 else |
581 { | 621 { |
622 focusCnt = 0; | |
582 inFocus = 0; | 623 inFocus = 0; |
624 freezeRoll = 0; | |
625 freezeYaw = 0; | |
583 } | 626 } |
584 } | 627 } |
585 return distance; | 628 return distance; |
586 } | 629 } |
587 uint8_t viewInFocus(void) | 630 uint8_t viewInFocus(void) |