1

I wrote a test code to see if my tap gestures are accepted from leap motion. After running the code I noticed that I have to tap really aggressively and even then, I only get a tap received once in every few taps. How can I change my code to prevent this ?

(Please notice, I am very new to coding so plz be elaborate, thanks)

FILE #1

    package com.leaptoarduino;
    import com.leapmotion.leap.Controller;
    import com.leapmotion.leap.Gesture;
    public class Leapd
    {
        //Main
        public static final void main(String args[])
        {
            //Initialize serial communications
            RS232Protocol serial = new RS232Protocol();
            serial.connect("COM3");
            //Initialize the Leapd listener
            LeapdListener leap = new LeapdListener(serial);
            Controller controller = new Controller();
            controller.addListener(leap);
            controller.enableGesture(Gesture.Type.TYPE_KEY_TAP);
            //Set up controller for gestures
            controller.config().setFloat("Gesture.KeyTap.MinDownVelocity", 5.0f);
            controller.config().setFloat("Gesture.KeyTap.HistorySeconds", .8f);
            controller.config().setFloat("Gesture.KeyTap.MinDistance", 20.0f);
            controller.config().save();     
        }

     }

FILE #2

    package com.leaptoarduino;
    import com.leapmotion.leap.*;
    import com.leapmotion.leap.Gesture.Type;
    import com.leapmotion.leap.KeyTapGesture;
    public class LeapdListener extends Listener
    {
    //Serial port that will be used to communicate with the Arduino
    private RS232Protocol serial;
    //Constructor
    public LeapdListener(RS232Protocol serial)
    {
        this.serial = serial;
    } 
    //Member function: onInit
    public void onInit(Controller controller)
    {
        System.out.println("Initialized");
    }
    //Member function: onConncect
    public void onConnect(Controller controller)
    {
       System.out.println("Connected");
    } 
    //Member Function: onDisconnect
    public void onDisconnect(Controller controller)
    {
       System.out.println("Disconnected");
    } 
    //Member Function: onExit
    public void onExit(Controller controller)
    {
       System.out.println("Exited");
    } 
    //Member Function: onFrame
    public void onFrame(Controller controller)
    {

        //Get the most recent frame
        Frame frame = controller.frame();
        //Verify a hand is in view
        if (frame.hands().count() > 0)
        {
            GestureList gestures = frame.gestures();
            for (Gesture gesture: gestures)
            {
                if (gesture.type() == Type.TYPE_KEY_TAP)
                {
                    KeyTapGesture keytap = new KeyTapGesture (gesture);
                    System.out.println("KEYTAPPED");
                }
            }

            //Send the tap data to the Arduino
            // TBD
            //Give the Arduino some time to process our data
            try { Thread.sleep(30); }
            catch (InterruptedException e) { e.printStackTrace(); }
        }
    }
}
NewbieJav
  • 13
  • 4
  • Without knowing leap-motion, did you try to set `Gesture.KeyTap.MinDownVelocity` to a lower value? – Uwe Allner Jul 29 '15 at 07:40
  • Yes I did.Only for a very low value it worked. – NewbieJav Jul 29 '15 at 07:44
  • The problem with the low vale that it caused detection of my hand slightly moving, even without tapping... I also tried different values for distance and history, with the same effect - low values worked, but detected very small movements of the hand without really tapping. – NewbieJav Jul 29 '15 at 07:46

1 Answers1

1

When you sleep the thread in the OnFrame handler, you are going to miss frames from the Leap Motion service. Part of your problem is probably that the tap gestures are recognized in those missed frames. Frame.gestures() takes a "sinceFrame" parameter to avoid this problem: frame.gestures(sinceFrame) gives you all the gestures that occurred between sinceFrame and the current frame and thus you don't miss any when frames are dropped or skipped. What you do is save the current frame to a lastFrameProcessed variable every time your onFrame handler runs. You pass this lastFrameProcessed variable to gestures() to get the complete gesture list. Something like:

Frame lastFrameProcessed = Frame.invalid();
public void onFrame(Controller controller)
{

    //Get the most recent frame
    Frame frame = controller.frame();
    //Verify a hand is in view
    if (frame.hands().count() > 0)
    {
        GestureList gestures = frame.gestures(lastFrameProcessed);
        for (Gesture gesture: gestures)
        {
            if (gesture.type() == Type.TYPE_KEY_TAP)
            {
                KeyTapGesture keytap = new KeyTapGesture (gesture);
                System.out.println("KEYTAPPED");
            }
        }

        //Send the tap data to the Arduino
        // TBD
        //Give the Arduino some time to process our data
        try { Thread.sleep(30); }
        catch (InterruptedException e) { e.printStackTrace(); }
    }
    lastFrameProcessed = frame;
} 
Charles Ward
  • 1,388
  • 1
  • 8
  • 13
  • Thanks a !ot. I will try that. – NewbieJav Jul 30 '15 at 21:42
  • 1
    Tried it. Still loosing taps. Weirder yet, I always get the STOP_STATE for the tap and seem to never get the beginning of it. – NewbieJav Aug 07 '15 at 16:15
  • 1
    Taps only have one gesture object per physical tap. Only circle and swipes will have more than one gesture update across multiple frames. Try it without sleeping the Thread and see if that makes a difference (temporarily stop calling the Arduino function, if necessary). – Charles Ward Aug 07 '15 at 17:36