package puck;
import com.buglabs.application.IServiceProvider;
import com.buglabs.application.MainApplicationThread;
import java.awt.BorderLayout;
import java.awt.Frame;
import java.io.IOException;
import java.util.*;
import com.buglabs.bug.accelerometer.pub.AccelerometerConfiguration;
import com.buglabs.bug.accelerometer.pub.AccelerometerSample;
import com.buglabs.bug.accelerometer.pub.AccelerometerSampleStream;
import com.buglabs.bug.accelerometer.pub.IAccelerometerControl;
import com.buglabs.bug.accelerometer.pub.IAccelerometerSampleFeed;
import com.buglabs.bug.module.lcd.pub.IModuleDisplay;
public class PuckApp extends MainApplicationThread {
private IServiceProvider serviceProvider;
private boolean ran;
private PuckPanel puckPanel;
private Frame frame;
public PuckApp(IServiceProvider serviceProvider) {
this.serviceProvider = serviceProvider;
ran = false;
}
/**
* Informs the caller whether this thread ran.
n. */
public boolean getRan() {
return ran;
}
private void ran() {
ran = true;
}
public void run() {
createUI();
dumpAccelerometerConfig();
setupAccelerometer();
AccelerometerSampleStream is = createAccelerometerInputStream();
System.out.println("Got accelerometer sample stream: "+is);
dumpAccelerometerConfig();
// These values were obtained empirically, with the Bug
// sitting on my desk; ymmv.
// orientations are relative to the BUGview being in slot 1 (the top-right one)
//final float xMax = 0.70F; // left
//final float xMin = -1.29F; // right
final float xZero = -0.30F;
//final float yMax = 0.84F; // top
//final float yMin = -1.10F; // bottom
final float yZero = -0.17F;
final float xFix = xZero * -1;
final float yFix = yZero * -1;
/// arbitrary multiplier to make the puck move at a decent rate
final int speedMultiplier = 30;
// correction multipliers so that left tilt moves left and not right,
// and forward tilt moves up, not down. Again, orientations are
// from the BUGview in slot 1's perspective, not the perspective
// of the BUGbase (so tilting toward the top of the BUGview display is
// actually tilting to the left of the BUGbase).
final int xAxisMultiplier = 1;
final int yAxisMultiplier = 1;
try {
while (!isInterrupted() && !tearDownRequested) {
final AccelerometerSample sample = is.readSample();
if (sample != null) {
final int yMove = (int) ((sample.getAccelerationX() + xFix) * speedMultiplier) * xAxisMultiplier;
final int xMove = (int) ((sample.getAccelerationY() + yFix) * speedMultiplier) * yAxisMultiplier;
puckPanel.movePuck(xMove, yMove);
}
}
is.close();
}
catch (IOException e) {
e.printStackTrace();
} finally {
destroyUI();
ran();
System.out.println("Puck stopped; closing accelerometer sample stream");
}
}
private void setupAccelerometer() {
// THIS DOES NOT WORK IF cfg.setDelayMode((byte) 0); is set
// see http://bugcommunity.com/bugzilla/show_bug.cgi?id=288
IAccelerometerControl c = (IAccelerometerControl) serviceProvider.getService(IAccelerometerControl.class);
AccelerometerConfiguration cfg = c.getConfiguration();
// use a sample rate of ~1ms (actually 1.024ms)
// see http://bugcommunity.com/wiki/images/b/b3/AccelerometerAPI_v1_1.pdf
//cfg.setDelayMode((byte) 0);
cfg.setDelayResolution((byte) 3);
cfg.setDelay((short) 500);
cfg.setReadQueueSize(1);
cfg.setReadQueueThreshold(1);
c.setConfiguration(cfg);
}
private void dumpAccelerometerConfig() {
IAccelerometerControl c = (IAccelerometerControl) serviceProvider.getService(IAccelerometerControl.class);
AccelerometerConfiguration cfg = c.getConfiguration();
System.out.println("Config:");
System.out.println("read_queue_size="+cfg.getReadQueueSize());
System.out.println("read_queue_threshold="+cfg.getReadQueueThreshold());
System.out.println("delay="+cfg.getDelay());
System.out.println("delay_resolution="+cfg.getDelayResolution());
System.out.println("delay_mode="+cfg.getDelayMode());
System.out.println("run="+cfg.getRun());
System.out.println("sensitivity="+cfg.getSensitivity());
}
private AccelerometerSampleStream createAccelerometerInputStream() {
IAccelerometerSampleFeed isp = (IAccelerometerSampleFeed) serviceProvider.getService(IAccelerometerSampleFeed.class);
return isp.getSampleInputStream();
}
public List getServices() {
List services = new ArrayList();
services.add(IModuleDisplay.class.getName());
services.add(IAccelerometerSampleFeed.class.getName());
services.add(IAccelerometerControl.class.getName());
return services;
}
private IModuleDisplay getIModuleDisplay() {
return (IModuleDisplay) serviceProvider.getService(IModuleDisplay.class);
}
private void createUI(){
frame = getIModuleDisplay().getFrame();
frame.setTitle("Puck");
frame.setLayout(new BorderLayout());
puckPanel = new PuckPanel();
frame.add(puckPanel, BorderLayout.CENTER);
frame.show();
}
private void destroyUI(){
frame.dispose();
frame = null;
puckPanel = null;
}
}