package org.myrobotlab.service; import java.io.IOException; import org.myrobotlab.framework.Service; import org.myrobotlab.framework.ServiceType; import org.myrobotlab.logging.Level; import org.myrobotlab.logging.LoggerFactory; import org.myrobotlab.logging.LoggingFactory; import org.slf4j.Logger; /** * * Pingdar - this service will control a sweeping servo and an ultrasonic sensor * module. The result is a sonar style range finding. * */ public class Pingdar extends Service { public static class Point { public float r; public float theta; public Point(float servoPos, float z) { this.theta = servoPos; this.r = z; } } private static final long serialVersionUID = 1L; public final static Logger log = LoggerFactory.getLogger(Pingdar.class); public int sweepMin = 0; public int sweepMax = 180; public int step = 1; transient private Arduino arduino; transient private Servo servo; transient private UltrasonicSensor sensor; // TODO - changed to XDar - make RangeSensor interface -> publishRange // TODO - set default sample rate // private boolean isAttached = false; private Long lastRange; private Integer lastPos; private int rangeCount = 0; long rangeAvg = 0; public static void main(String[] args) { LoggingFactory.init(Level.INFO); Runtime.createAndStart("gui", "GUIService"); // Runtime.createAndStart("webgui", "WebGui"); /* * Serial.createNullModemCable("uart", "COM10"); Serial serial = * (Serial)Runtime.createAndStart("uart", "Serial"); * * serial.connect("uart"); */ Runtime.start("pingdar", "Pingdar"); // Runtime.createAndStart("gui", "GUIService"); // pingdar.attach("COM15", 7, 8, 9); // pingdar.sweep(); /* * GUIService gui = new GUIService("gui"); gui.startService(); */ } public Pingdar(String n) { super(n); } // ----------- interface begin ---------------- public boolean attach(Arduino arduino, String port, UltrasonicSensor sensor, int trigPin, int echoPin, Servo servo, int servoPin) throws Exception { this.arduino = arduino; this.sensor = sensor; this.servo = servo; arduino.connect(port); // TODO - FIX ME /* if (!sensor.attach(port, trigPin, echoPin)) { error("could not attach sensor"); return false; } */ // FIXME sensor.addRangeListener // publishRange --> onRange sensor.addRangeListener(this); servo.addServoEventListener(this); arduino.servoAttach(servo, servoPin); return true; } // UBER GOOD // UBER GOOD !!!! max & min complexity with service creation support with // Peers !!!! // attach (arduino port sensor trigPin echoPin servo servoPin ) <- max // complexity - no service creation // attach (port trigPin echoPin servoPin) <- min complexity - service // creation on peers public boolean attach(String port, int trigPin, int echoPin, int servoPin) throws Exception { return attach(arduino, port, sensor, trigPin, echoPin, servo, servoPin); } public Arduino getArduino() { return arduino; } // ----------- interface end ---------------- public UltrasonicSensor getSensor() { return sensor; } public Servo getServo() { return servo; } // sensor data has come in // grab the latest position public Long onRange(Long range) { info("range %d", range); // filter too low // TODO this should be done on the Arduino if (range < 10) { return range; } rangeAvg += range; lastRange = range; ++rangeCount; /* * Point p = new Point(lastPos, range); invoke("publishPingdar", p); */ return lastRange; } public Integer onServoEvent(Integer pos) { info("pos %d", pos); lastPos = pos; if (rangeCount > 0) { Point p = new Point(lastPos, rangeAvg / rangeCount); rangeAvg = 0; rangeCount = 0; invoke("publishPingdar", p); } return lastPos; } public Point publishPingdar(Point point) { return point; } @Override public void startService() { super.startService(); arduino = (Arduino) startPeer("arduino"); sensor = (UltrasonicSensor) startPeer("sensor"); servo = (Servo) startPeer("servo"); } public void stop() { super.stopService(); sensor.stopRanging(); servo.eventsEnabled(false); servo.stop(); } public boolean sweep() { return sweep(sweepMin, sweepMax); } public boolean sweep(int sweepMin, int sweepMax) { this.sweepMin = sweepMin; this.sweepMax = sweepMax; this.step = 1; // FIXME STEP // TODO - configurable speed sensor = getSensor(); servo = getServo(); sensor.addRangeListener(this); servo.addServoEventListener(this); servo.setSpeed(0.20); servo.eventsEnabled(true); // STEP ??? servo.sweep(sweepMin, sweepMax, 1, step); sensor.startRanging(); return true; } /** * This static method returns all the details of the class without it having * to be constructed. It has description, categories, dependencies, and peer * definitions. * * @return ServiceType - returns all the data * */ static public ServiceType getMetaData() { ServiceType meta = new ServiceType(Pingdar.class.getCanonicalName()); meta.addDescription("used as a ultra sonic radar"); meta.addCategory("sensor", "display"); // put peer definitions in meta.addPeer("arduino", "Arduino", "arduino"); meta.addPeer("sensor", "UltrasonicSensor", "sensor"); meta.addPeer("servo", "Servo", "servo"); return meta; } }