package org.myrobotlab.service; import java.io.IOException; import java.util.Date; import java.util.HashMap; import java.util.TimerTask; import java.util.TooManyListenersException; import org.myrobotlab.framework.Service; import org.myrobotlab.framework.ServiceType; import org.myrobotlab.logging.Level; import org.myrobotlab.logging.LoggerFactory; import org.myrobotlab.logging.Logging; import org.myrobotlab.logging.LoggingFactory; import org.myrobotlab.service.data.Pin; import org.slf4j.Logger; /** * * Plantoid - Unknown state * * A plantoid is a hypothetical robot or synthetic organism designed to look, * act and grow like a plant. The concept was first scientifically published in * 2010 More info at : http://www.plantoidrobotics.org/ * http://myrobotlab.org/service/plantoid * */ public class Plantoid extends Service { // video0 = rgbpilot cam // video1 = pink plant static NIR - // Imaged from there should be taken and put through the infrapix, then // opencv // Nope static camera view of the braaaains // video2 = NIR pilot cam public class Scanner extends Thread { int start = 0; int end = 180; int delay = 400; boolean isScanning = false; int pos = start; int increment = 1; Servo servo; public Scanner(Servo servo, int start, int end, int delay) { this.servo = servo; this.start = start; this.end = end; this.delay = delay; this.pos = start; } @Override public void run() { isScanning = true; while (isScanning) { servo.moveTo(pos); pos = pos + increment; Service.sleep(delay); if (pos >= end || pos <= start) { increment = increment * -1; } } } } class SendReport extends TimerTask { Plantoid plantoid; SendReport(Plantoid plantoid) { this.plantoid = plantoid; } @Override public void run() { sendReport(); } } public final static Logger log = LoggerFactory.getLogger(Plantoid.class); private static final long serialVersionUID = 1L; transient private Arduino arduino; // transient private AudioFile audioFile; // transient private JFugue jFugue; // transient private Keyboard keyboard; transient private OpenCV opencv; transient private Servo leg1, leg2, leg3, leg4, pan, tilt; // transient private SpeechSynthesis speech; transient private Tracking tracking; transient private VideoStreamer streamer; // FIXME make part of ServoControl // transient private WebGui webgui; transient private Xmpp xmpp; transient public Scanner scanner = null; int everyNHours = 8; transient HashMap<String, Object> p = new HashMap<String, Object>(); public String port = "/dev/ttyACM0"; /** * analog read pins */ public final int soildMoisture = 0; public final int tempHumidity = 2; public final int leftLight = 4; public final int rightLight = 6; public final int airQuality = 10; private int sampleRate = 8000; public static void main(String[] args) { LoggingFactory.getInstance().configure(); LoggingFactory.getInstance().setLevel(Level.INFO); try { Plantoid plantoid = (Plantoid) Runtime.create("plantoid", "Plantoid"); plantoid.connect("COM12"); plantoid.startService(); // Runtime.createAndStart("python", "Python"); // Runtime.createAndStart("webgui", "WebGui"); /* * GUIService gui = new GUIService("gui"); gui.startService(); */ } catch (Exception e) { Logging.logError(e); } } /** * Plantoid Service - this service controls all peer services. It is a * OrbousMundus Genus and flagship of the BEPSL Republic. * * Its mission is to go forth explore and be one with nature in alien * environments while reporting telemetry back to BEPSL control * * @param n */ public Plantoid(String n) { super(n); arduino = (Arduino) createPeer("arduino"); xmpp = (Xmpp) createPeer("xmpp"); // webgui = (WebGui) createPeer("webgui"); leg1 = (Servo) createPeer("leg1"); leg2 = (Servo) createPeer("leg2"); leg3 = (Servo) createPeer("leg3"); leg4 = (Servo) createPeer("leg4"); pan = (Servo) createPeer("pan"); tilt = (Servo) createPeer("tilt"); opencv = (OpenCV) createPeer("opencv"); tracking = (Tracking) createPeer("tracking"); // OLD WAY /* * leg1.setPin(2); leg2.setPin(3); leg3.setPin(4); leg4.setPin(5); * * pan.setPin(6); tilt.setPin(7); * * leg1.setController(arduino); leg2.setController(arduino); * leg3.setController(arduino); leg4.setController(arduino); * * pan.setController(arduino); tilt.setController(arduino); * */ arduino.servoAttach(leg1, 2); arduino.servoAttach(leg2, 3); arduino.servoAttach(leg3, 4); arduino.servoAttach(leg4, 5); arduino.servoAttach(pan, 6); arduino.servoAttach(tilt, 7); pan.setRest(90); tilt.setRest(90); leg1.setRest(90); leg2.setRest(90); leg3.setRest(90); leg4.setRest(90); streamer = (VideoStreamer) createPeer("streamer"); } /** * attaches the legs only */ public void attachLegs() { leg1.attach(); leg2.attach(); leg3.attach(); leg4.attach(); } // public int scaleUp scaleDown /** * attaches only the pan tilt */ public void attachPanTilt() { pan.attach(); tilt.attach(); } /** * attaches all the servos legs and pan tilt kit */ public void attachServos() { attachPanTilt(); attachLegs(); } public boolean connect() throws IOException { arduino.connect(port); arduino.broadcastState(); return arduino.isConnected(); } /** * Connects the plantoid server's Arduino service to the appropriate serial * port. This is automatically called when the Plantoid service starts. * Default is /dev/ttyACM0 * * @param port * @return true if connected false otherwise * @throws TooManyListenersException * @throws IOException */ public boolean connect(String port) throws IOException { this.port = port; return connect(); } /** * detaches the legs only */ public void detachLegs() { leg1.detach(); leg2.detach(); leg3.detach(); leg4.detach(); } // ------- servos begin ----------- /** * detaches the pan tilt only */ public void detachPanTilt() { pan.detach(); tilt.detach(); } /** * detaches all servos */ public void detachServos() { detachPanTilt(); detachLegs(); } /** * current uptime of the plantoid server this represents the longevity and * quality of our plantoid craft LONG LIVE BEPSL !! * * @return the uptime */ public String getUptime() { return Runtime.getUptime(); } public void initTelemetryPayload() { p.put("soildMoistureCurrent", 0); p.put("soildMoistureMin", 0); p.put("soildMoistureMax", 0); p.put("soildMoistureAvg", 0); p.put("tempHumidityCurrent", 0); p.put("tempHumidityMin", 0); p.put("tempHumidityMax", 0); p.put("tempHumidityAvg", 0); p.put("soildMoistureCurrent", 0); p.put("soildMoistureMin", 0); p.put("soildMoistureMax", 0); p.put("soildMoistureAvg", 0); p.put("soildMoistureCurrent", 0); p.put("soildMoistureMin", 0); p.put("soildMoistureMax", 0); p.put("soildMoistureAvg", 0); p.put("soildMoistureCurrent", 0); p.put("soildMoistureMin", 0); p.put("soildMoistureMax", 0); p.put("soildMoistureAvg", 0); } /** * moveX moves the plantoid on the X axis * * @param power * -90 - down the X axis 0 (stop) 90 - up the X axis */ public void moveX(Integer power) { leg1.moveTo(90 - power); leg2.moveTo(90); leg3.moveTo(90 + power); leg4.moveTo(90); } /** * moveY moves the plantoid on the Y axis * * @param power * -90 - down the Y axis 0 (stop) 90 - up the Y axis */ public void moveY(Integer power) { leg2.moveTo(90); leg3.moveTo(90 - power); leg4.moveTo(90); leg1.moveTo(90 + power); } public void onPin(Pin pin) { // if (log.isDebugEnabled()) { log.info(String.format("pin %d value %d", pin.pin, pin.value)); } /* * switch(pin.pin) { case soildMoisture: //p.put("soildMoistureCurrent", * value) break; } */ } public String sendReport() { StringBuffer sb = new StringBuffer(); sb.append(String.format("report from orbous on the Idahosian landing site, I am still alive after %s- all is well - *HAIL BEPSL* !", Runtime.getUptime())); xmpp.broadcast(sb.toString()); return sb.toString(); } // ------- servos begin ----------- // FIXME FIXME FIXME // setScannerDelay(int delay) - can not be found (must upcast) - so null is // found ??? public int setScannerDelay(Integer delay) { if (scanner != null) { scanner.delay = delay; return delay; } return -1; } /** * shuts down the planoid server */ public void shutdown() { if (xmpp != null) { xmpp.broadcast("MY LIFE FOR BEPSL !"); } detachServos(); Runtime.releaseAll(); } /** * Spin spins the plantoid server * * @param power * power range is from -90 (spin full clock wise) 0 (stop) 90 * (spin full counter clockwise) */ public void spin(Integer power) { int s = 90 - power; leg2.moveTo(s); leg3.moveTo(s); leg4.moveTo(s); leg1.moveTo(s); } /** * square dance "should" make a square by moving the plantoid up and down * the X and Y axis's * * @param power * power applied to legs * @param time * run time on each axis */ public void squareDance(Integer power, Integer time) { int s = 90 - power; moveX(s); sleep(time); moveY(s); sleep(time); moveX(-s); sleep(time); moveX(-s); sleep(time); stop(); } public void startCannyScanning() { opencv.addFilter("Canny"); opencv.setDisplayFilter("Canny"); opencv.capture(); startScanning(); } public void startHSVScanning() { opencv.removeFilters(); opencv.addFilter("PyramidDown"); opencv.addFilter("HSV"); opencv.setDisplayFilter("HSV"); opencv.capture(); startScanning(); } /** * This begins polling of the various analog senesors of the Plantoid * server. It is automatically started when the Plantoid service is started. * Soil, temperature, left and right light sensors and air quality are all * polled */ public void startPolling() { arduino.setSampleRate(sampleRate); arduino.enablePin(soildMoisture); arduino.enablePin(tempHumidity); arduino.enablePin(leftLight); arduino.enablePin(rightLight); arduino.enablePin(airQuality); } public void startScanning() { startScanning(pan); } public void startScanning(Servo servo) { if (scanner != null) { stopScanning(); } scanner = new Scanner(servo, 10, 160, 300); scanner.start(); } public void startScanning(String name, int begin, int end, int delay) { Servo servo = (Servo) Runtime.getService(name); if (scanner != null) { stopScanning(); } scanner = new Scanner(servo, 10, 160, 300); scanner.start(); } // FIXME FIXME FIXME - Service.isValidForStart() !!!! @Override public void startService() { try { super.startService(); xmpp.startService(); xmpp.connect("talk.google.com", 5222, "orbous@myrobotlab.org", "mrlRocks!"); // gets all users it can send messages to xmpp.setStatus(true, String.format("online all the time - %s", new Date())); // xmpp.addAuditor("incubator incubator"); // xmpp.addAuditor("David Ultis"); // xmpp.addAuditor("Greg Perry"); // xmpp.broadcast("reporting for duty *SIR* !"); if (tracking != null) { tracking.startService(); } arduino.connect(port); // the BEPSL report // timer.scheduleAtFixedRate(new SendReport(this), 0, 1000 * 60 * 60 // * // everyNHours); leg1.attach(); leg2.attach(); leg3.attach(); leg4.attach(); pan.attach(); tilt.attach(); subscribe(arduino.getName(), "publishPin"); // startPolling(); attachPanTilt(); tracking.startService(); opencv.startService(); // attachServos(); detachLegs(); // at the moment detach legs // stop(); streamer.startService(); streamer.attach(opencv); } catch (Exception e) { log.error("starting plantoid error", e); } } public void startVisualScanning() { opencv.addFilter("PyramidDown"); opencv.setDisplayFilter("PyramidDown"); opencv.removeFilters(); opencv.capture(); startScanning(); } /** * stops all legs */ public void stop() { leg1.moveTo(90); leg2.moveTo(90); leg3.moveTo(90); leg4.moveTo(90); } /** * shut down polling of analog sensors */ public void stopPolling() { arduino.disablePin(soildMoisture); arduino.enablePin(tempHumidity); arduino.enablePin(leftLight); arduino.enablePin(rightLight); arduino.enablePin(airQuality); } public void stopScanning() { if (scanner != null) { scanner.isScanning = false; scanner.interrupt(); scanner = null; } } /** * 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(Plantoid.class.getCanonicalName()); meta.addDescription("The Plantoid Service"); meta.addCategory("robot"); // put peer definitions in meta.addPeer("arduino", "Arduino", "arduino service"); meta.addPeer("audioFile", "AudioFile", "audio file service"); meta.addPeer("jFugue", "JFugue", "jfugue service"); // TODO: removed this, why is webgui a peer here? // meta.addPeer("webgui", "WebGui", "WebGui service"); meta.addPeer("xmpp", "Xmpp", "Xmpp service"); meta.addPeer("leg1", "Servo", "leg1"); meta.addPeer("leg2", "Servo", "leg2"); meta.addPeer("leg3", "Servo", "leg3"); meta.addPeer("leg4", "Servo", "leg4"); meta.addPeer("pan", "Servo", "pan"); meta.addPeer("tilt", "Servo", "tilt"); meta.addPeer("tracking", "Tracking", "tracking service"); meta.addPeer("opencv", "OpenCV", "pilot camera"); meta.addPeer("streamer", "VideoStreamer", "video streamer"); return meta; } }