Sweep a servo according to Proximity sensor measure

Dependencies:   Servo X_NUCLEO_6180XA1 mbed

Fork of HelloWorld_6180XA1 by ST

Revision:
14:946e62f44f4f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Middlewares/ST/STM32_HMI_HandGesture/HmiBBGesture.cpp	Tue Oct 27 15:54:05 2015 +0000
@@ -0,0 +1,296 @@
+/* ----------------------------------------------------------------------
+ * Copyright (C) 2014 STMicroelectronics. All rights reserved.
+ *
+ * Project: BB gesture recognition
+ * Title:   HmiBBGesture
+ *
+ * Description: Gesture recognition - left, right, tap
+ *
+ * 20/10/14
+ * Changed from proximity to range
+ * Ultra simplified version
+ *
+ * -------------------------------------------------------------------- */
+
+//#define PRINT_DEBUG_
+#define USE_MICRO_
+
+#include "HmiBBGesture.h"
+#include "stm32f4xx_hal.h"
+#include <stdint.h>
+#include <stdio.h>
+
+#ifdef USE_MICRO_
+//#include "vl6180x_shield.h"
+//#include "platform.h"
+//#define GET_TIME_STAMP() ((int)timer_get_clock_time_msecs())  // for Mbed
+#define GET_TIME_STAMP()  (int32_t)HAL_GetTick()   // for Cube
+#else
+/* PC config */
+#include <windows.h>
+#define GET_TIME_STAMP() ((int)timeGetTime())
+#endif
+
+#ifdef PRINT_DEBUG_
+#ifdef USE_MICRO_
+static char str[80];
+//extern void serial_print(const char *str);
+#define serial_print(str)  printf(str)
+#endif
+#endif
+
+#define HMI_SIGNAL_CODE_DROP_DOWN 1
+#define HMI_SIGNAL_CODE_RAISE_UP 2
+#define HMI_SIGNAL_CODE_DOWN_STATE 3
+#define HMI_SIGNAL_CODE_UP_STATE 4
+#define HMI_SIGNAL_CODE_NULL -1
+
+#define HMI_TAP_CODE_SINGLE 0
+#define HMI_TAP_CODE_DOUBLE 1
+#define HMI_TAP_CODE_HOLD 2
+#define HMI_TAP_CODE_NULL -1
+
+
+
+
+/**********************************************************************************
+ *
+ *
+ *  Gesture recognition class
+ *
+ *
+ **********************************************************************************/
+
+
+void HmiBBGesture::Init(int threshold_mm, int tap_threshold_mm, int min_hold_duration_ms, int min_swipe_duration_ms, int max_gesture_duration_ms )
+{
+    m_motion_r.Init( threshold_mm );
+    m_motion_l.Init( threshold_mm );
+    m_tap_det.Init( tap_threshold_mm, 150, min_hold_duration_ms, false, 0 );
+    m_fsm_state = 0;
+    m_timestamp = GET_TIME_STAMP();
+    m_min_swipe_ms   = min_swipe_duration_ms;
+    m_max_gesture_ms = max_gesture_duration_ms;
+    m_gesture_starts_from_right = false;
+}
+
+int HmiBBGesture::Update(int range_r, int range_l, int *gesture_duration_ms)
+{
+    int r_code, r_ms;
+    int l_code, l_ms;
+    int duration;
+    int gesture_code = HMI_BB_GESTURE_CODE_NULL;
+    *gesture_duration_ms = 0;
+
+    r_code = m_motion_r.Update( range_r , &r_ms );
+    l_code = m_motion_l.Update( range_l , &l_ms );
+//        printf ("r_ms: %d l_ms: %d\n\r",r_ms, l_ms);
+    switch( m_fsm_state )
+    {
+    case 1: // gesture ends
+
+        duration = GET_TIME_STAMP() - m_timestamp;
+        if(duration > m_max_gesture_ms)  // gesture is too long - discard it
+        {
+            m_fsm_state = 0;
+#ifdef PRINT_DEBUG_
+
+#ifdef USE_MICRO_
+sprintf(str, "FSM 1 - Discarded %d %d %d mts %d\n",r_code,l_code,duration, m_timestamp);
+serial_print(str);
+#else
+printf("FSM 1 - Discarded %d %d %d \n",r_code,l_code,duration);
+#endif
+
+#endif
+        }
+        else if( (m_gesture_starts_from_right && l_code == HMI_SIGNAL_CODE_RAISE_UP ) ||
+                 (m_gesture_starts_from_right==false && r_code == HMI_SIGNAL_CODE_RAISE_UP) )
+        {
+            m_fsm_state = 0;
+            if( duration > (m_min_swipe_ms/2) )
+            {
+                gesture_code = ( m_gesture_starts_from_right ) ? HMI_BB_GESTURE_CODE_RIGHT : HMI_BB_GESTURE_CODE_LEFT;
+                *gesture_duration_ms = duration;
+#ifdef PRINT_DEBUG_
+
+#ifdef USE_MICRO_
+sprintf(str,"FSM 2 - Recognized %d\n",gesture_code);
+serial_print(str);
+#else
+printf("FSM 2 - Recognized %d\n",gesture_code);
+#endif
+
+#endif
+            }
+#ifdef PRINT_DEBUG_
+            else
+            {
+#ifdef USE_MICRO_
+sprintf(str,"FSM 1 - Discarded %d %d %d \n",r_code,l_code,duration);
+serial_print(str);
+#else
+printf("FSM 1 - Discarded %d %d %d \n",r_code,l_code,duration);
+#endif
+            }
+#endif
+        }
+
+        break;
+
+    case 0: // gesture starts
+        if( l_code == HMI_SIGNAL_CODE_DOWN_STATE && r_code == HMI_SIGNAL_CODE_RAISE_UP && r_ms > m_min_swipe_ms )
+        {
+            m_gesture_starts_from_right = true;
+            m_fsm_state = 1;
+            m_timestamp = GET_TIME_STAMP();
+            m_var_max_gesture_ms = r_ms;
+#ifdef PRINT_DEBUG_
+
+#ifdef USE_MICRO_
+sprintf(str,"FSM 0 - Right started %d\n",r_ms);
+serial_print(str);
+#else
+printf("FSM 0 - Right started %d\n",r_ms);
+#endif
+
+#endif
+        }
+        else if( l_code == HMI_SIGNAL_CODE_RAISE_UP && r_code == HMI_SIGNAL_CODE_DOWN_STATE && l_ms > m_min_swipe_ms )
+        {
+            m_gesture_starts_from_right = false;
+            m_fsm_state = 1;
+            m_timestamp = GET_TIME_STAMP();
+            m_var_max_gesture_ms = l_ms;
+#ifdef PRINT_DEBUG_
+
+#ifdef USE_MICRO_
+sprintf(str,"FSM 0 - Left started %d\n",l_ms);
+serial_print(str);
+#else
+printf("FSM 0 - Left started %d\n",l_ms);
+#endif
+
+#endif
+        }
+        break;
+
+    default:
+        break;
+    };
+
+    if( m_tap_det.Update((range_r+range_l)/2,&duration) == HMI_TAP_CODE_HOLD )
+    {
+        gesture_code = HMI_BB_GESTURE_CODE_TAP;
+        *gesture_duration_ms = duration;
+        m_fsm_state = 0;
+    }
+
+    return gesture_code;
+}
+
+
+/**********************************************************************************
+ *
+ *
+ *  MotionDetector class
+ *
+ *
+ **********************************************************************************/
+
+void MotionDetector::Init(int threshold)
+{
+    m_threshold = threshold;
+    m_runonce = true;
+}
+
+
+int MotionDetector::Update(int sample,int *duration)
+{
+    int return_code;
+    bool belowCurrent, isContinuous;
+
+
+    // run once
+    if( m_runonce )
+    {
+        m_runonce = false;
+        m_timestamp = GET_TIME_STAMP();
+        m_prev_sample = sample;
+        belowCurrent  = (sample < m_threshold);
+        isContinuous  = true;
+        return_code = ( belowCurrent ) ? HMI_SIGNAL_CODE_DOWN_STATE : HMI_SIGNAL_CODE_UP_STATE;
+        *duration = 1;
+        return return_code;
+    }
+
+    *duration = 0;
+    return_code = HMI_SIGNAL_CODE_NULL;
+    belowCurrent  = (sample < m_threshold);
+    isContinuous  = ( belowCurrent ==  (m_prev_sample < m_threshold));
+    m_prev_sample = sample;
+
+    // update
+    *duration = GET_TIME_STAMP() - m_timestamp;
+    if( isContinuous )
+    {
+        return_code = ( belowCurrent ) ? HMI_SIGNAL_CODE_DOWN_STATE : HMI_SIGNAL_CODE_UP_STATE;
+    }
+    else
+    {
+        return_code = ( belowCurrent ) ? HMI_SIGNAL_CODE_DROP_DOWN : HMI_SIGNAL_CODE_RAISE_UP;
+        m_timestamp = GET_TIME_STAMP();
+    }
+
+    return return_code;
+}
+
+
+
+/**********************************************************************************
+ *
+ *
+ *  TapDetector
+ *
+ *
+ **********************************************************************************/
+void TapDetector::Init( int threshold, int min_down_duration_ms, int min_hold_duration_ms, bool enable_double_tap, int double_tap_min_duration_ms)
+{
+    m_threshold = threshold;
+    m_motion.Init( threshold );
+    m_min_down_duration_ms = min_down_duration_ms;
+    m_min_hold_duration_ms = min_hold_duration_ms;
+    m_min_dtap_duration_ms = double_tap_min_duration_ms;
+    m_notify_hold = true;
+    m_notify_dtap = enable_double_tap;
+    m_timestamp = GET_TIME_STAMP();
+}
+
+int TapDetector::Update( int sample, int *duration )
+{
+    int return_code;
+    int motion_code,motion_duration;
+
+    return_code = HMI_TAP_CODE_NULL;
+    *duration = 0;
+    motion_code = m_motion.Update(sample, &motion_duration);
+
+    // hold condition - down_duration > hold_time
+    if( motion_code == HMI_SIGNAL_CODE_DOWN_STATE && motion_duration > m_min_hold_duration_ms )
+    {
+        if( m_notify_hold )
+        {
+            return_code = HMI_TAP_CODE_HOLD;
+            m_notify_hold = false; // to avoid continue notification ( anti flood )
+            *duration = motion_duration;
+        }
+    }
+    else if( motion_code == HMI_SIGNAL_CODE_RAISE_UP )
+    {
+        m_notify_hold = true;
+        /* TODO add TAP single/double code */
+    }
+
+    return return_code;
+}
+