问题
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(); }
}
}
}
回答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;
}
来源:https://stackoverflow.com/questions/31693994/missed-tap-gestures-from-leap-motion-in-java