I don't know whether this works on the robot, but this is how we plan to implement it on our driver's station this year. We may add an interrupt timer that will re-process a new image if the old image hasn't been processed, but we also don't expect the driver's station laptop to bog down enough that it can't keep up. This method doesn't depend on a sleep() or a timer, it simply processes images as they chronologically come in (even if they're asynchronous due to network lag).
The big issue with doing threading like this comes when you go to fold the results back into whatever other robot logic you have. You MUST make sure your data is thread-safe (i.e. use synchronized blocks on critical path items OR make sure that only one single thread can access/modify a specific set of critical data). With gui's, it's easy: SwingUtilities.invokeLater() will update data on a GUI using the EventDispatchThread. For your own internal robot stuff though, it isn't quite as clear-cut.
Code:
/**
* IUpdate<T> is just a type-safe interface that I commonly use
* for event-driven items that only need 1 input parameter.
*
public interface IUpdate<T>
{
public void update(T pObject);
}
*
*/
public abstract class ImageProcessor implements IUpdate<BufferedImage>
{
private final Executor mExecutor = Executors.newSingleThreadExecutor();
public ImageProcessor(IImageProvider pProvider)
{
pProvider.addListener(this);
}
@Override public void update(final BufferedImage pObject)
{
mExecutor.execute(new Runnable()
{
@Override public void run()
{
processImpl(pObject);
}
});
}
protected abstract void processImpl(BufferedImage pImage);
}