All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.kjkoster.wedo.activities.Drawbridge Maven / Gradle / Ivy

package org.kjkoster.wedo.activities;

import static com.google.common.base.Preconditions.checkState;
import static java.lang.System.exit;
import static java.lang.System.out;
import static java.lang.Thread.sleep;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.kjkoster.wedo.bricks.Tilt.Direction.BACKWARD;
import static org.kjkoster.wedo.bricks.Tilt.Direction.FORWARD;
import static org.kjkoster.wedo.bricks.Tilt.Direction.NO_TILT;

import java.util.Collection;

import org.kjkoster.wedo.bricks.Tilt;
import org.kjkoster.wedo.bricks.Tilt.Direction;
import org.kjkoster.wedo.systems.wedo.WeDoBricks;
import org.kjkoster.wedo.transport.usb.Usb;

/**
 * The drawbridge is interesting because of the limitations of the tilt sensor
 * and the WeDo hub. Using only a rather brief tilt sensor we have to decide
 * what angle the drawbridge is at.
 * 

* For the solution below, we make the assumption that the tilt sensor only * changes a little bit between two readings. We run the motor slowly and use a * worm wheel to slow the bridge motion. This gives us time to read the tilt * sensor and reason about the angle it must be at. * * @author Kees Jan Koster <[email protected]> */ public class Drawbridge { private static final byte DOWN = 0x40; private static final byte UP = (byte) (-DOWN & 0xff); private static final byte STOP = 0x00; private static WeDoBricks weDoBricks; /** * The main drawbridge program. * * @param args * Ignored. */ public static void main(final String[] args) { try (final Usb usb = new Usb(false)) { weDoBricks = new WeDoBricks(usb, false); weDoBricks.reset(); findFlatPoint(); for (;;) { sleep(SECONDS.toMillis(5L)); out.println("Opening the bridge..."); weDoBricks.motor(UP); sleep(SECONDS.toMillis(2L)); runUntilFlat(); sleep(SECONDS.toMillis(2L)); out.println("Closing the bridge..."); weDoBricks.motor(DOWN); sleep(SECONDS.toMillis(2L)); runUntilFlat(); } } catch (Exception e) { e.printStackTrace(); exit(1); } finally { weDoBricks.reset(); // It seems that under Mac OS X a thread is still stuck in the // hidapi USB library, so we force the JVM to exit. exit(0); } } /** * Find the bridge's flat point. If the tilt sensor says the bridge is at a * forward or backward angle that is easy, we just run the motor until the * tilt sensor stops reading an angle. *

* If the tilt sensor says it cannot read the angle, we are in trouble. The * bridge may either be flat or upright at that point. We run the motor for * a brief time and see what happens to the tilt sensor reading. */ private static void findFlatPoint() throws InterruptedException { switch (readTilt()) { case BACKWARD: out.println("Bridge is still open, closing it first..."); weDoBricks.motor(DOWN); runUntilFlat(); break; case FORWARD: out.println("Bridge is hanging in the water, pulling it up..."); weDoBricks.motor(UP); runUntilFlat(); break; case NO_TILT: out.println("Bridge is either flat or upright, trying to see which it is..."); weDoBricks.motor(UP); sleep(SECONDS.toMillis(1L)); if (readTilt() == NO_TILT) { out.println("Bridge was tilted backwards, reversing..."); weDoBricks.motor(DOWN); sleep(SECONDS.toMillis(4L)); // carry it back over upright } else { out.println("Bridge was flat, reversing..."); weDoBricks.motor(DOWN); } runUntilFlat(); break; default: throw new IllegalArgumentException("unsupported tilt direction"); } } private static Direction readTilt() { final Collection tilts = weDoBricks.readTilts(); checkState(tilts.size() == 1); return tilts.iterator().next().getDirection(); } private static void runUntilFlat() throws InterruptedException { Direction direction = readTilt(); while (direction == BACKWARD || direction == FORWARD) { sleep(MILLISECONDS.toMillis(100L)); direction = readTilt(); } weDoBricks.motor(STOP); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy