HierarchyGraph inputGraph, LocationSummary locSummary,
Map<Set<Integer>, Set<Set<Integer>>> mapImSucc) {
- HierarchyGraph simpleHierarchyGraph = infer.getSimpleHierarchyGraph(desc);
-
SSJavaLattice<String> lattice =
new SSJavaLattice<String>(SSJavaAnalysis.TOP, SSJavaAnalysis.BOTTOM);
}
+ inputGraph.removeRedundantEdges();
return lattice;
}
// composite location
int maxTupleSize = 0;
+ int minTupleSize = 0;
CompositeLocation maxCompLoc = null;
Location prevPriorityLoc = null;
maxTupleSize = compLoc.getSize();
maxCompLoc = compLoc;
}
+ if (minTupleSize == 0 || compLoc.getSize() < minTupleSize) {
+ minTupleSize = compLoc.getSize();
+ }
Location priorityLoc = compLoc.get(0);
String priorityLocId = priorityLoc.getLocIdentifier();
priorityLocIdentifierSet.add(priorityLocId);
}
SSJavaLattice<String> locOrder = getLatticeByDescriptor(priorityDescriptor);
- System.out.println("priorityDescriptor=" + priorityDescriptor);
- System.out.println("GLB INPUT=" + priorityLocIdentifierSet);
String glbOfPriorityLoc = locOrder.getGLB(priorityLocIdentifierSet);
- System.out.println("GLB OUTPUT="+glbOfPriorityLoc);
glbCompLoc.addLocation(new Location(priorityDescriptor, glbOfPriorityLoc));
Set<CompositeLocation> compSet = locId2CompLocSet.get(glbOfPriorityLoc);
// in this case, do not take care about delta
// CompositeLocation inputComp = inputSet.iterator().next();
- for (int i = 1; i < maxTupleSize; i++) {
+ // for (int i = 1; i < maxTupleSize; i++) {
+ for (int i = 1; i < minTupleSize; i++) {
glbCompLoc.addLocation(Location.createTopLocation(maxCompLoc.get(i).getDescriptor()));
}
} else {
//
// update return flow nodes in the caller
CompositeLocation returnLoc = getMethodSummary(mdCallee).getRETURNLoc();
-
System.out.println("### min=" + min.printNode(0) + " returnLoc=" + returnLoc);
if (returnLoc != null && returnLoc.get(0).getLocDescriptor().equals(mdCallee.getThis())
&& returnLoc.getSize() > 1) {
}
System.out.println("###NEW RETURN TUPLE FOR CALLER=" + newReturnTuple);
callerFlowGraph.getFlowReturnNode(min).setNewTuple(newReturnTuple);
+ } else {
+ // if the return loc set was empty and later pcloc was connected to the return loc
+ // need to make sure that return loc reflects to this changes.
+ FlowReturnNode flowReturnNode = callerFlowGraph.getFlowReturnNode(min);
+ if (flowReturnNode != null && flowReturnNode.getReturnTupleSet().isEmpty()) {
+
+ if (needToUpdateReturnLocHolder(min.getMethod(), flowReturnNode)) {
+ NTuple<Descriptor> baseTuple = mapMethodInvokeNodeToBaseTuple.get(min);
+ NTuple<Descriptor> newReturnTuple = baseTuple.clone();
+ flowReturnNode.addTuple(newReturnTuple);
+ }
+
+ }
+
}
}
}
+ private boolean needToUpdateReturnLocHolder(MethodDescriptor mdCallee,
+ FlowReturnNode flowReturnNode) {
+ FlowGraph fg = getFlowGraph(mdCallee);
+ MethodSummary summary = getMethodSummary(mdCallee);
+ CompositeLocation returnCompLoc = summary.getRETURNLoc();
+ NTuple<Descriptor> returnDescTuple = translateToDescTuple(returnCompLoc.getTuple());
+ Set<FlowNode> incomingNodeToReturnNode =
+ fg.getIncomingFlowNodeSet(fg.getFlowNode(returnDescTuple));
+ for (Iterator iterator = incomingNodeToReturnNode.iterator(); iterator.hasNext();) {
+ FlowNode inNode = (FlowNode) iterator.next();
+ if (inNode.getDescTuple().get(0).equals(mdCallee.getThis())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private void addMapMethodDescToMethodInvokeNodeSet(MethodInvokeNode min) {
MethodDescriptor md = min.getMethod();
if (!mapMethodDescToMethodInvokeNodeSet.containsKey(md)) {
// calculate a return location:
// the return location type is lower than all parameters and the location of return values
MethodSummary methodSummary = getMethodSummary(md);
- if (methodSummary.getRETURNLoc() != null) {
- return;
- }
+ // if (methodSummary.getRETURNLoc() != null) {
+ // System.out.println("$HERE?");
+ // return;
+ // }
+
FlowGraph fg = getFlowGraph(md);
Map<Integer, CompositeLocation> mapParamToLoc = methodSummary.getMapParamIdxToInferLoc();
Set<Integer> paramIdxSet = mapParamToLoc.keySet();
}
+ // makes sure that PCLOC is higher than RETURNLOC
+ CompositeLocation pcLoc = methodSummary.getPCLoc();
+ if (!pcLoc.get(0).isTop()) {
+ NTuple<Descriptor> pcLocDescTuple = translateToDescTuple(pcLoc.getTuple());
+ fg.addValueFlowEdge(pcLocDescTuple, returnDescTuple);
+ }
+
}
}
--- /dev/null
+/*
+ * Copyright 2009 (c) Florian Frankenberger (darkblue.de)
+ *
+ * This file is part of LEA.
+ *
+ * LEA is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * LEA is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with LEA. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ *
+ * @author Florian
+ */
+
+
+public class Classifier {
+
+
+ private ScanArea[] scanAreas;
+
+
+ private float[] possibilities_FaceYes;
+
+ private float[] possibilities_FaceNo;
+
+ private int possibilityFaceYes = 0;
+
+ private int possibilityFaceNo = 0;
+
+ public Classifier(int numScanAreas) {
+ this.scanAreas = new ScanArea[numScanAreas];
+ this.possibilities_FaceYes = new float[numScanAreas];
+ this.possibilities_FaceNo = new float[numScanAreas];
+ }
+
+ public void setScanArea(int idx, ScanArea area) {
+ scanAreas[idx] = area;
+ }
+
+ public void setPossibilitiesFaceYes(@DELEGATE float[] arr) {
+ this.possibilities_FaceYes = arr;
+ }
+
+ public void setPossibilityFaceYes(int v) {
+ this.possibilityFaceYes = v;
+ }
+
+ public void setPossibilitiesFaceNo(@DELEGATE float[] arr) {
+ this.possibilities_FaceNo = arr;
+ }
+
+ public void setPossibilityFaceNo(int v) {
+ this.possibilityFaceNo = v;
+ }
+
+ /**
+ * Classifies an images region as face
+ *
+ * @param image
+ * @param scaleFactor
+ * please be aware of the fact that the scanareas are scaled for use
+ * with 100x100 px images
+ * @param translationX
+ * @param translationY
+ * @return true if this region was classified as face, else false
+ */
+
+
+ public boolean classifyFace( IntegralImageData image,
+ float scaleFactor, int translationX,
+ int translationY, float borderline) {
+
+ long values[] = new long[scanAreas.length];
+
+ float avg = 0f;
+ int avgItems = 0;
+ for ( int i = 0; i < scanAreas.length; ++i) {
+ values[i] = 0l;
+
+ values[i] +=
+ image.getIntegralAt(translationX + scanAreas[i].getToX(scaleFactor), translationY
+ + scanAreas[i].getToY(scaleFactor));
+ values[i] +=
+ image.getIntegralAt(translationX + scanAreas[i].getFromX(scaleFactor), translationY
+ + scanAreas[i].getFromY(scaleFactor));
+
+ values[i] -=
+ image.getIntegralAt(translationX + scanAreas[i].getToX(scaleFactor), translationY
+ + scanAreas[i].getFromY(scaleFactor));
+ values[i] -=
+ image.getIntegralAt(translationX + scanAreas[i].getFromX(scaleFactor), translationY
+ + scanAreas[i].getToY(scaleFactor));
+
+ values[i] = (long) (values[i] / ((float) scanAreas[i].getSize(scaleFactor)));
+ avg = ((avgItems * avg) + values[i]) / (++avgItems);
+ }
+ // System.out.println("avg=" + avg);
+
+ // int amountYesNo = this.possibilityFaceNo + this.possibilityFaceYes;
+
+ // calculate the possibilites for face=yes and face=no with naive bayes
+ // P(Yes | M1 and ... and Mn) = P(Yes) * P(M1 | Yes) * ... * P(Mn | Yes) /xx
+ // P(No | M1 and ... and Mn) = P(No) * P(M1 | No) * ... * P(Mn | No) / xx
+ // as we just maximize the args we don't actually calculate the accurate
+ // possibility
+
+ float isFaceYes = 1.0f;// this.possibilityFaceYes /
+ // (float)amountYesNo;
+ float isFaceNo = 1.0f;// this.possibilityFaceNo /
+ // (float)amountYesNo;
+
+ for ( int i = 0; i < this.scanAreas.length; ++i) {
+ boolean bright = (values[i] >= avg);
+ isFaceYes *= (bright ? this.possibilities_FaceYes[i] : 1 - this.possibilities_FaceYes[i]);
+ isFaceNo *= (bright ? this.possibilities_FaceNo[i] : 1 - this.possibilities_FaceNo[i]);
+ }
+ // System.out.println("avg=" + avg + " yes=" + isFaceYes + " no=" +
+ // isFaceNo);
+
+ return (isFaceYes >= isFaceNo && (isFaceYes / (isFaceYes + isFaceNo)) > borderline);
+ }
+
+ public ScanArea[] getScanAreas() {
+ return this.scanAreas;
+ }
+
+ public int getLearnedFacesYes() {
+ return this.possibilityFaceYes;
+ }
+
+ public int getLearnedFacesNo() {
+ return this.possibilityFaceNo;
+ }
+
+ public float getPossibility(int scanAreaID, boolean faceYes, boolean bright) {
+ if (faceYes) {
+ return (bright ? this.possibilities_FaceYes[scanAreaID]
+ : 1 - this.possibilities_FaceYes[scanAreaID]);
+ } else {
+ return (bright ? this.possibilities_FaceNo[scanAreaID]
+ : 1 - this.possibilities_FaceNo[scanAreaID]);
+ }
+ }
+
+ public int compareTo(Classifier o) {
+ if (o.getScanAreas().length > this.getScanAreas().length) {
+ return -1;
+ } else if (o.getScanAreas().length < this.getScanAreas().length) {
+ return 1;
+ } else
+ return 0;
+ }
+
+ public String toString() {
+
+ String str = "";
+ for ( int i = 0; i < scanAreas.length; i++) {
+ str += scanAreas[i].toString() + "\n";
+ }
+
+ return str;
+
+ }
+
+}
--- /dev/null
+import SSJava.PCLOC;
+
+/*
+ * Copyright 2009 (c) Florian Frankenberger (darkblue.de)
+ *
+ * This file is part of LEA.
+ *
+ * LEA is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * LEA is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with LEA. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ *
+ * @author Florian
+ */
+
+
+public class ClassifierTree {
+
+
+ private Classifier classifiers[];
+
+ public ClassifierTree(int size) {
+ classifiers = new Classifier[size];
+ }
+
+ public void addClassifier( int idx, Classifier c) {
+ classifiers[idx] = c;
+ }
+
+ /**
+ * Locates a face by searching radial starting at the last known position. If
+ * lastCoordinates are null we simply start in the center of the image.
+ * <p>
+ * TODO: This method could quite possible be tweaked so that face recognition
+ * would be much faster
+ *
+ * @param image
+ * the image to process
+ * @param lastCoordinates
+ * the last known coordinates or null if unknown
+ * @return an rectangle representing the actual face position on success or
+ * null if no face could be detected
+ */
+
+
+ public Rectangle2D locateFaceRadial( Image smallImage,
+ Rectangle2D lastCoordinates) {
+
+ IntegralImageData imageData = new IntegralImageData(smallImage);
+ float originalImageFactor = 1;
+
+ if (lastCoordinates == null) {
+ // if we don't have a last coordinate we just begin in the center
+ int smallImageMaxDimension =
+ Math.min(smallImage.getWidth(), smallImage.getHeight());
+ lastCoordinates =
+ new Rectangle2D((smallImage.getWidth() - smallImageMaxDimension) / 2.0,
+ (smallImage.getHeight() - smallImageMaxDimension) / 2.0, smallImageMaxDimension,
+ smallImageMaxDimension);
+ // System.out.println("lastCoordinates=" + lastCoordinates);
+ } else {
+ // first we have to scale the last coodinates back relative to the resized
+ // image
+ lastCoordinates =
+ new Rectangle2D((lastCoordinates.getX() * (1 / originalImageFactor)),
+ (lastCoordinates.getY() * (1 / originalImageFactor)),
+ (lastCoordinates.getWidth() * (1 / originalImageFactor)),
+ (lastCoordinates.getHeight() * (1 / originalImageFactor)));
+ }
+
+ float startFactor = (float) (lastCoordinates.getWidth() / 100.0f);
+
+ // first we calculate the maximum scale factor for our 200x200 image
+ float maxScaleFactor =
+ Math.min(imageData.getWidth() / 100f, imageData.getHeight() / 100f);
+ // maxScaleFactor = 1.0f;
+
+ // we simply won't recognize faces that are smaller than 40x40 px
+ float minScaleFactor = 0.5f;
+
+ float maxScaleDifference =
+ Math.max(Math.abs(maxScaleFactor - startFactor), Math.abs(minScaleFactor - startFactor));
+
+ // border for faceYes-possibility must be greater that that
+ float maxBorder = 0.999f;
+
+ int startPosX = (int) lastCoordinates.getX();
+ int startPosY = (int) lastCoordinates.getX();
+
+ int loopidx = 0;
+ TERMINATE: for ( float factorDiff = 0.0f; Math.abs(factorDiff) <= maxScaleDifference; factorDiff =
+ (factorDiff + sgn(factorDiff) * 0.1f) * -1 // we alternate between
+ // negative and positiv
+ // factors
+ ) {
+
+ if (++loopidx > 1000) {
+ return null;
+ }
+
+ float factor = startFactor + factorDiff;
+ if (factor > maxScaleFactor || factor < minScaleFactor)
+ continue;
+
+ // now we calculate the actualDimmension
+ int actualDimmension = (int) (100 * factor);
+ int maxX = imageData.getWidth() - actualDimmension;
+ int maxY = imageData.getHeight() - actualDimmension;
+
+ int maxDiffX = Math.max(Math.abs(startPosX - maxX), startPosX);
+ int maxDiffY = Math.max(Math.abs(startPosY - maxY), startPosY);
+
+ int xidx = 0;
+ TERMINATE: for ( float xDiff = 0.1f; Math.abs(xDiff) <= maxDiffX; xDiff =
+ (xDiff + sgn(xDiff) * 0.5f) * -1) {
+
+ if (++xidx > 1000) {
+ return null;
+ }
+
+ int xPos = Math.round((float) (startPosX + xDiff));
+
+ if (xPos < 0 || xPos > maxX)
+ continue;
+
+ int yidx = 0;
+ // yLines:
+ TERMINATE: for ( float yDiff = 0.1f; Math.abs(yDiff) <= maxDiffY; yDiff =
+ (yDiff + sgn(yDiff) * 0.5f) * -1) {
+
+ if (++yidx > 1000) {
+ return null;
+ }
+
+ int yPos = Math.round(startPosY + yDiff);
+ if (yPos < 0 || yPos > maxY)
+ continue;
+
+ // by now we should have a valid coordinate to process which we should
+ // do now
+ boolean backToYLines = false;
+ for ( int idx = 0; idx < classifiers.length; ++idx) {
+ float borderline =
+ 0.8f + (idx / (classifiers.length - 1)) * (maxBorder - 0.8f);
+ if (!classifiers[idx].classifyFace(imageData, factor, xPos, yPos, borderline)) {
+ backToYLines = true;
+ break;
+ // continue yLines;
+ }
+ }
+
+ // if we reach here we have a face recognized because our image went
+ // through all
+ // classifiers
+
+ if (backToYLines) {
+ continue;
+ }
+ Rectangle2D faceRect =
+ new Rectangle2D(xPos * originalImageFactor, yPos * originalImageFactor,
+ actualDimmension * originalImageFactor, actualDimmension * originalImageFactor);
+
+ return faceRect;
+
+ }
+
+ }
+
+ }
+
+ // System.out.println("Time: "+(System.currentTimeMillis()-timeStart)+"ms");
+ return null;
+
+ }
+
+
+
+ private static int sgn( float value) {
+ return (value < 0 ? -1 : (value > 0 ? +1 : 1));
+ }
+
+}
--- /dev/null
+public class Counter {
+
+ static int idx = 0;
+
+ @TRUST
+ static boolean inc() {
+ idx++;
+ }
+
+ @TRUST
+ static int idx() {
+ return idx;
+ }
+
+}
--- /dev/null
+/*\r
+ * Copyright 2009 (c) Florian Frankenberger (darkblue.de)\r
+ * \r
+ * This file is part of LEA.\r
+ * \r
+ * LEA is free software: you can redistribute it and/or modify it under the\r
+ * terms of the GNU Lesser General Public License as published by the Free\r
+ * Software Foundation, either version 3 of the License, or (at your option) any\r
+ * later version.\r
+ * \r
+ * LEA is distributed in the hope that it will be useful, but WITHOUT ANY\r
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR\r
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more\r
+ * details.\r
+ * \r
+ * You should have received a copy of the GNU Lesser General Public License\r
+ * along with LEA. If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+\r
+/**\r
+ * No description given.\r
+ * \r
+ * @author Florian Frankenberger\r
+ */\r
+\r
+\r
+public class DeviationScanner {\r
+\r
+ \r
+ private EyePosition eyePositions[];\r
+\r
+ // LEFT_UP(+1, -1), UP(0, -1), RIGHT_UP(-1, -1), LEFT(+1, 0), NONE(0, 0),\r
+ // RIGHT(-1, 0), LEFT_DOWN(\r
+ // +1, +1), DOWN(0, +1), RIGHT_DOWN(-1, +1);\r
+\r
+ public static final int LEFT_UP = 0;\r
+ public static final int UP = 1;\r
+ public static final int RIGHT_UP = 2;\r
+ public static final int LEFT = 3;\r
+ public static final int NONE = 4;\r
+ public static final int RIGHT = 5;\r
+ public static final int LEFT_DOWN = 6;\r
+ public static final int DOWN = 7;\r
+ public static final int RIGHT_DOWN = 8;\r
+\r
+ public DeviationScanner() {\r
+ eyePositions = new EyePosition[3];\r
+ }\r
+\r
+ \r
+ public void addEyePosition( EyePosition eyePosition) {\r
+\r
+ // for ( int i = 1; i < 3; i++) {\r
+ // eyePositions[i - 1] = eyePositions[i];\r
+ // eyePositions[i] = null;\r
+ // }\r
+ // eyePositions[eyePositions.length - 1] = eyePosition;\r
+\r
+ SSJAVA.append(eyePositions, eyePosition);\r
+\r
+ }\r
+\r
+ // \r
+ \r
+ \r
+ public int scanForDeviation( Rectangle2D faceRect) {\r
+\r
+ int deviation = NONE;\r
+\r
+ for ( int i = 0; i < 3; i++) {\r
+ if (eyePositions[i] == null) {\r
+ return deviation;\r
+ }\r
+ }\r
+\r
+ double deviationX = 0;\r
+ double deviationY = 0;\r
+\r
+ int lastIdx = -1;\r
+ for ( int i = 0; i < 3; ++i) {\r
+ if (lastIdx != -1) {\r
+ deviationX += (eyePositions[i].getX() - eyePositions[lastIdx].getX());\r
+ deviationY += (eyePositions[i].getY() - eyePositions[lastIdx].getY());\r
+ }\r
+ lastIdx = i;\r
+ }\r
+\r
+ final double deviationPercentX = 0.04;\r
+ final double deviationPercentY = 0.04;\r
+\r
+ deviationX /= faceRect.getWidth();\r
+ deviationY /= faceRect.getWidth();\r
+\r
+ int deviationAbsoluteX = 0;\r
+ int deviationAbsoluteY = 0;\r
+ if (deviationX > deviationPercentX)\r
+ deviationAbsoluteX = 1;\r
+ if (deviationX < -deviationPercentX)\r
+ deviationAbsoluteX = -1;\r
+ if (deviationY > deviationPercentY)\r
+ deviationAbsoluteY = 1;\r
+ if (deviationY < -deviationPercentY)\r
+ deviationAbsoluteY = -1;\r
+\r
+ deviation = getDirectionFor(deviationAbsoluteX, deviationAbsoluteY);\r
+\r
+ if (deviation != NONE) {\r
+ eyePositions = new EyePosition[3];\r
+ }\r
+ // System.out.println(String.format("%.2f%% | %.2f%% => %d and %d >>> %s",\r
+ // deviationX*100, deviationY*100, deviationAbsoluteX, deviationAbsoluteY,\r
+ // deviation.toString()));\r
+\r
+ return deviation;\r
+ }\r
+\r
+ \r
+ public int getDirectionFor( int directionX, int directionY) {\r
+\r
+ if (directionX == +1 && directionY == -1) {\r
+ return LEFT_UP;\r
+ } else if (directionX == 0 && directionY == -1) {\r
+ return UP;\r
+ } else if (directionX == -1 && directionY == -1) {\r
+ return RIGHT_UP;\r
+ } else if (directionX == +1 && directionY == 0) {\r
+ return LEFT;\r
+ } else if (directionX == 0 && directionY == 0) {\r
+ return NONE;\r
+ } else if (directionX == -1 && directionY == 0) {\r
+ return RIGHT;\r
+ } else if (directionX == +1 && directionY == +1) {\r
+ return LEFT_DOWN;\r
+ } else if (directionX == 0 && directionY == +1) {\r
+ return DOWN;\r
+ } else if (directionX == -1 && directionY == +1) {\r
+ return RIGHT_DOWN;\r
+ }\r
+\r
+ return -1;\r
+ }\r
+\r
+ public void clear() {\r
+ System.out.println("CLEAR");\r
+ eyePositions = new EyePosition[3];\r
+ }\r
+\r
+ public String toStringDeviation( int dev) {\r
+ if (dev == LEFT_UP) {\r
+ return "LEFT_UP";\r
+ } else if (dev == UP) {\r
+ return "UP";\r
+ } else if (dev == RIGHT_UP) {\r
+ return "RIGHT_UP";\r
+ } else if (dev == LEFT) {\r
+ return "LEFT";\r
+ } else if (dev == NONE) {\r
+ return "NONE";\r
+ } else if (dev == RIGHT) {\r
+ return "RIGHT";\r
+ } else if (dev == LEFT_DOWN) {\r
+ return "LEFT_DOWN";\r
+ } else if (dev == DOWN) {\r
+ return "DOWN";\r
+ } else if (dev == RIGHT_DOWN) {\r
+ return "RIGHT_DOWN";\r
+ }\r
+ return "ERROR";\r
+ }\r
+\r
+}\r
--- /dev/null
+public class Dimension {
+ public int width;
+ public int height;
+
+}
--- /dev/null
+/**\r
+ * \r
+ */\r
+\r
+import java.awt.Color;\r
+import java.awt.Graphics2D;\r
+import java.awt.image.BufferedImage;\r
+\r
+import de.darkblue.lea.ifaces.ICaptureDevice;\r
+\r
+/**\r
+ * No description given.\r
+ * \r
+ * @author Florian Frankenberger\r
+ */\r
+public class DummyCaptureDevice implements ICaptureDevice {\r
+\r
+ /**\r
+ * \r
+ */\r
+ public DummyCaptureDevice() {\r
+ // TODO Auto-generated constructor stub\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see de.darkblue.lea.ifaces.ICaptureDevice#close()\r
+ */\r
+ @Override\r
+ public void close() {\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see de.darkblue.lea.ifaces.ICaptureDevice#getFrameRate()\r
+ */\r
+ @Override\r
+ public int getFrameRate() {\r
+ return 15;\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see de.darkblue.lea.ifaces.ICaptureDevice#getImage()\r
+ */\r
+ @Override\r
+ public BufferedImage getImage() {\r
+ BufferedImage image = new BufferedImage(640, 480, BufferedImage.TYPE_INT_RGB);\r
+ Graphics2D g2d = (Graphics2D)image.getGraphics();\r
+ g2d.setColor(new Color(255, 255, 255));\r
+ g2d.fillRect(0, 0, 639, 479);\r
+ return image;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*
+ * Copyright 2009 (c) Florian Frankenberger (darkblue.de)
+ *
+ * This file is part of LEA.
+ *
+ * LEA is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * LEA is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with LEA. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * No description given.
+ *
+ * @author Florian Frankenberger
+ */
+
+
+class EyeDetector {
+
+
+ private int width;
+
+ private int height;
+
+ private int[] pixelBuffer;
+
+ double percent;
+
+ public EyeDetector(Image image, Rectangle2D faceRect) {
+
+ percent = 0.15 * faceRect.getWidth();
+ Rectangle2D adjustedFaceRect =
+ new Rectangle2D(faceRect.getX() + percent, faceRect.getY() + percent, faceRect.getWidth()
+ - percent, faceRect.getHeight() - 2 * percent);
+
+ width = (int) adjustedFaceRect.getWidth() / 2;
+ height = (int) adjustedFaceRect.getHeight() / 2;
+ pixelBuffer = new int[width * height];
+
+ int startX = (int) adjustedFaceRect.getX();
+ int startY = (int) adjustedFaceRect.getY();
+
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ pixelBuffer[(y * width) + x] = (int) image.getPixel(x + startX, y + startY);
+ }
+ }
+
+ }
+
+
+ public Point detectEye() {
+ Point eyePosition = null;
+ float brightness = 255f;
+ for ( int y = 0; y < height; ++y) {
+ for ( int x = 0; x < width; ++x) {
+ final int position = y * width + x;
+ final int[] color =
+ new int[] { (pixelBuffer[position] & 0xFF0000) >> 16,
+ (pixelBuffer[position] & 0x00FF00) >> 8, pixelBuffer[position] & 0x0000FF };
+ // System.out.println("("+x+","+y+")="+color[0]+" "+color[1]+" "+color[2]);
+ final float acBrightness = getBrightness(color);
+
+ if (acBrightness < brightness) {
+ eyePosition = new Point(x + (int) percent, y + (int) percent);
+ brightness = acBrightness;
+ }
+ }
+ }
+
+ return eyePosition;
+ }
+
+
+ private static float getBrightness( int[] color) {
+ int min = Math.min(Math.min(color[0], color[1]), color[2]);
+ int max = Math.max(Math.max(color[0], color[1]), color[2]);
+
+ return 0.5f * (max + min);
+ }
+}
--- /dev/null
+/*
+ * Copyright 2009 (c) Florian Frankenberger (darkblue.de)
+ *
+ * This file is part of LEA.
+ *
+ * LEA is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * LEA is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with LEA. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * No description given.
+ *
+ * @author Florian Frankenberger
+ */
+
+
+public class EyePosition {
+
+ private int x;
+
+ private int y;
+
+ private Rectangle2D faceRect;
+
+ public EyePosition(Point p, Rectangle2D faceRect) {
+ this(p.x, p.y, faceRect);
+ }
+
+ public EyePosition(int x, int y, Rectangle2D faceRect) {
+ this.x = x;
+ this.y = y;
+ this.faceRect = faceRect;
+ }
+
+ public int getX() {
+ return this.x;
+ }
+
+ public int getY() {
+ return this.y;
+ }
+
+ public String toString() {
+ return "(" + x + "," + y + ")";
+ }
+
+ // public Deviation getDeviation(EyePosition oldEyePosition) {
+ // if (oldEyePosition == null) return Deviation.NONE;
+ //
+ // //first we check if the faceRects are corresponding
+ // double widthChange = (this.faceRect.getWidth() -
+ // oldEyePosition.faceRect.getWidth()) / this.faceRect.getWidth();
+ // if (widthChange > 0.1) return Deviation.NONE;
+ //
+ // int maxDeviationX = (int)Math.round(this.faceRect.getWidth() / 4f);
+ // int maxDeviationY = (int)Math.round(this.faceRect.getWidth() / 8f);
+ // int minDeviation = (int)Math.round(this.faceRect.getWidth() / 16f);
+ //
+ // int deviationX = Math.abs(x - oldEyePosition.x);
+ // int directionX = sgn(x - oldEyePosition.x);
+ // if (deviationX < minDeviation || deviationX > maxDeviationX) directionX =
+ // 0;
+ //
+ // int deviationY = Math.abs(y - oldEyePosition.y);
+ // int directionY = sgn(y - oldEyePosition.y);
+ // if (deviationY < minDeviation || deviationY > maxDeviationY) directionY =
+ // 0;
+ //
+ // double deviationXPercent = deviationX / this.faceRect.getWidth();
+ // double deviationYPercent = deviationY / this.faceRect.getWidth();
+ //
+ // System.out.println(String.format("devX: %.2f | devY: %.2f",
+ // deviationXPercent*100f, deviationYPercent*100f));
+ // return Deviation.getDirectionFor(directionX, directionY);
+ // }
+
+ private static int sgn(int i) {
+ if (i > 0)
+ return 1;
+ if (i < 0)
+ return -1;
+ return 0;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2009 (c) Florian Frankenberger (darkblue.de)
+ *
+ * This file is part of LEA.
+ *
+ * LEA is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * LEA is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with LEA. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * No description given.
+ *
+ * @author Florian Frankenberger
+ */
+
+
+public class FaceAndEyePosition {
+
+
+ private Rectangle2D facePosition;
+
+ private EyePosition eyePosition;
+
+ public FaceAndEyePosition(Rectangle2D facePosition, EyePosition eyePosition) {
+ this.facePosition = facePosition;
+ this.eyePosition = eyePosition;
+ }
+
+ public Rectangle2D getFacePosition() {
+ return this.facePosition;
+ }
+
+ public EyePosition getEyePosition() {
+ return this.eyePosition;
+ }
+
+}
--- /dev/null
+/*\r
+ * Copyright 2009 (c) Florian Frankenberger (darkblue.de)\r
+ * \r
+ * This file is part of LEA.\r
+ * \r
+ * LEA is free software: you can redistribute it and/or modify it under the\r
+ * terms of the GNU Lesser General Public License as published by the Free\r
+ * Software Foundation, either version 3 of the License, or (at your option) any\r
+ * later version.\r
+ * \r
+ * LEA is distributed in the hope that it will be useful, but WITHOUT ANY\r
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR\r
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more\r
+ * details.\r
+ * \r
+ * You should have received a copy of the GNU Lesser General Public License\r
+ * along with LEA. If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+\r
+\r
+import java.awt.image.BufferedImage;\r
+\r
+/**\r
+ * Describes a capture device. For now it is only tested\r
+ * with images in <code>640x480</code> at <code>RGB</code> or <code>YUV</code> color space.\r
+ * \r
+ * @author Florian Frankenberger\r
+ */\r
+public interface ICaptureDevice {\r
+\r
+ /**\r
+ * Returns the frame rate of the image source per second\r
+ * \r
+ * @return the frame rate (e.g. 15 = 15 frames per second)\r
+ */\r
+ public int getFrameRate();\r
+\r
+ /**\r
+ * Will be called a maximum of getFrameRate()-times in a second and returns\r
+ * the actual image of the capture device\r
+ * \r
+ * @return the actual image of the capture device \r
+ */\r
+ public BufferedImage getImage();\r
+ \r
+ /**\r
+ * LEA calls this when it cleans up. You should put your own cleanup code in here.\r
+ */\r
+ public void close();\r
+ \r
+ \r
+}\r
--- /dev/null
+
+
+public class Image {
+
+
+ int width;
+
+ int height;
+
+ int pixel[][];
+
+ public Image(int width, int height) {
+ this.width = width;
+ this.height = height;
+ pixel = new int[width][height];
+ }
+
+ public void setPixel(int x, int y, int R, int G, int B) {
+ pixel[x][y] = (R << 16) | (G << 8) | B;
+ }
+
+ public int getRed(int x, int y) {
+ return (pixel[x][y] >> 16) & 0xff;
+ }
+
+ public int getGreen(int x, int y) {
+ return (pixel[x][y] >> 8) & 0xff;
+ }
+
+ public int getBlue(int x, int y) {
+ return pixel[x][y] & 0xff;
+ }
+
+ public void setPixel(int x, int y, int p) {
+ pixel[x][y] = p;
+ }
+
+ public long getPixel(int x, int y) {
+ return pixel[x][y];
+ }
+
+ public int getWidth() {
+ return width;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+}
--- /dev/null
+public class ImageReader {
+
+ static int idx = 0;
+
+ public ImageReader() {
+ }
+
+ @TRUST
+ public static Image getImage() {
+ System.out.println(idx);
+ Image image = ImageReader.readImage("data/b" + idx + ".bmp");
+ idx++;
+ if (idx > 73) {
+ return null;
+ }
+ return image;
+ }
+
+ public static Image readImage(String file) {
+
+ FileInputStream fs = new FileInputStream(file);
+ int bflen = 14; // 14 byte BITMAPFILEHEADER
+ byte bf[] = new byte[bflen];
+ // fs.read(bf,0,bflen);
+ fs.read(bf);
+ int bilen = 40; // 40-byte BITMAPINFOHEADER
+ byte bi[] = new byte[bilen];
+ // fs.read(bi,0,bilen);
+ fs.read(bi);
+ // Interperet data.
+ int nsize =
+ (((int) bf[5] & 0xff) << 24) | (((int) bf[4] & 0xff) << 16) | (((int) bf[3] & 0xff) << 8)
+ | (int) bf[2] & 0xff;
+ // System.out.println("File type is :" + (char) bf[0] + (char) bf[1]);
+ // System.out.println("Size of file is :" + nsize);
+ int nbisize =
+ (((int) bi[3] & 0xff) << 24) | (((int) bi[2] & 0xff) << 16) | (((int) bi[1] & 0xff) << 8)
+ | (int) bi[0] & 0xff;
+ // System.out.println("Size of bitmapinfoheader is :" + nbisize);
+ int nwidth =
+ (((int) bi[7] & 0xff) << 24) | (((int) bi[6] & 0xff) << 16) | (((int) bi[5] & 0xff) << 8)
+ | (int) bi[4] & 0xff;
+ // System.out.println("Width is :" + nwidth);
+ int nheight =
+ (((int) bi[11] & 0xff) << 24) | (((int) bi[10] & 0xff) << 16) | (((int) bi[9] & 0xff) << 8)
+ | (int) bi[8] & 0xff;
+ // System.out.println("Height is :" + nheight);
+ int nplanes = (((int) bi[13] & 0xff) << 8) | (int) bi[12] & 0xff;
+ // System.out.println("Planes is :" + nplanes);
+ int nbitcount = (((int) bi[15] & 0xff) << 8) | (int) bi[14] & 0xff;
+ // System.out.println("BitCount is :" + nbitcount);
+ // Look for non-zero values to indicate compression
+ int ncompression =
+ (((int) bi[19]) << 24) | (((int) bi[18]) << 16) | (((int) bi[17]) << 8) | (int) bi[16];
+ // System.out.println("Compression is :" + ncompression);
+ int nsizeimage =
+ (((int) bi[23] & 0xff) << 24) | (((int) bi[22] & 0xff) << 16)
+ | (((int) bi[21] & 0xff) << 8) | (int) bi[20] & 0xff;
+ // System.out.println("SizeImage is :" + nsizeimage);
+
+ int nxpm =
+ (((int) bi[27] & 0xff) << 24) | (((int) bi[26] & 0xff) << 16)
+ | (((int) bi[25] & 0xff) << 8) | (int) bi[24] & 0xff;
+ // System.out.println("X-Pixels per meter is :" + nxpm);
+ int nypm =
+ (((int) bi[31] & 0xff) << 24) | (((int) bi[30] & 0xff) << 16)
+ | (((int) bi[29] & 0xff) << 8) | (int) bi[28] & 0xff;
+ // System.out.println("Y-Pixels per meter is :" + nypm);
+ int nclrused =
+ (((int) bi[35] & 0xff) << 24) | (((int) bi[34] & 0xff) << 16)
+ | (((int) bi[33] & 0xff) << 8) | (int) bi[32] & 0xff;
+ // System.out.println("Colors used are :" + nclrused);
+ int nclrimp =
+ (((int) bi[39] & 0xff) << 24) | (((int) bi[38] & 0xff) << 16)
+ | (((int) bi[37] & 0xff) << 8) | (int) bi[36] & 0xff;
+ // System.out.println("Colors important are :" + nclrimp);
+
+ Image image = new Image(nwidth, nheight);
+
+ if (nbitcount == 24) {
+ // No Palatte data for 24-bit format but scan lines are
+ // padded out to even 4-byte boundaries.
+ int npad = (nsizeimage / nheight) - nwidth * 3;
+ // ndata = new int[(nheight * nwidth) + 4];
+ byte brgb[] = new byte[(nwidth + npad) * 3 * nheight];
+ // fs.read (brgb, 0, (nwidth + npad) * 3 * nheight);
+ fs.read(brgb);
+ int nindex = 0;
+ int yPos = 0;
+ for (int j = 0; j < nheight; j++) {
+ for (int i = 0; i < nwidth; i++) {
+ // ndata[nwidth * (nheight - j - 1) + i] =
+ // (255 & 0xff) << 24 | (((int) brgb[nindex + 2] & 0xff) << 16)
+ // | (((int) brgb[nindex + 1] & 0xff) << 8) | (int) brgb[nindex] &
+ // 0xff;
+ int ta =
+ ((3 * ((int) (brgb[nindex + 2]) & 0xff) + 6 * ((int) brgb[nindex + 1] & 0xff) + ((int) brgb[nindex] & 0xff))) / 10;
+
+ // ndata[nwidth * (nheight - j - 1) + i + 4] = ta;
+ yPos = nheight - j - 1;
+ // System.out.println("yPos=" + yPos + " nheight=" + nheight + " j=" +
+ // j);
+ // System.out.println("Encoded Color at (" + i + "," + yPos + ")is:" +
+ // brgb + " (R,G,B)= ("
+ // + ((int) (brgb[nindex + 2]) & 0xff) + "," + ((int) brgb[nindex + 1]
+ // & 0xff) + ","
+ // + ((int) brgb[nindex] & 0xff) + ")" + "cufoff=" + ta);
+ image.setPixel(i, yPos, ((int) brgb[nindex + 2] & 0xff), ((int) brgb[nindex + 1] & 0xff),
+ ((int) brgb[nindex] & 0xff));
+ nindex += 3;
+ }
+ nindex += npad;
+ }
+ // image = createImage
+ // ( new MemoryImageSource (nwidth, nheight,
+ // ndata, 0, nwidth));
+
+ } else if (nbitcount == 8) {
+ // Have to determine the number of colors, the clrsused
+ // parameter is dominant if it is greater than zero. If
+ // zero, calculate colors based on bitsperpixel.
+ int nNumColors = 0;
+ if (nclrused > 0) {
+ nNumColors = nclrused;
+ } else {
+ nNumColors = (1 & 0xff) << nbitcount;
+ }
+ System.out.println("The number of Colors is" + nNumColors);
+ // Some bitmaps do not have the sizeimage field calculated
+ // Ferret out these cases and fix 'em.
+ if (nsizeimage == 0) {
+ nsizeimage = ((((nwidth * nbitcount) + 31) & 31) >> 3);
+ nsizeimage *= nheight;
+ System.out.println("nsizeimage (backup) is" + nsizeimage);
+ }
+ // Read the palatte colors.
+ int npalette[] = new int[nNumColors];
+ byte bpalette[] = new byte[nNumColors * 4];
+ // fs.read (bpalette, 0, nNumColors*4);
+ fs.read(bpalette);
+ int nindex8 = 0;
+ for (int n = 0; n < nNumColors; n++) {
+ npalette[n] =
+ (255 & 0xff) << 24 | (((int) bpalette[nindex8 + 2] & 0xff) << 16)
+ | (((int) bpalette[nindex8 + 1] & 0xff) << 8) | (int) bpalette[nindex8] & 0xff;
+ // System.out.println ("Palette Color "+n
+ // +" is:"+npalette[n]+" (res,R,G,B)= (" +((int)(bpalette[nindex8+3]) &
+ // 0xff)+"," +((int)(bpalette[nindex8+2]) & 0xff)+","
+ // +((int)bpalette[nindex8+1]&0xff)+","
+ // +((int)bpalette[nindex8]&0xff)+")");
+
+ nindex8 += 4;
+ }
+ // Read the image data (actually indices into the palette)
+ // Scan lines are still padded out to even 4-byte
+ // boundaries.
+ int npad8 = (nsizeimage / nheight) - nwidth;
+ // System.out.println("nPad is:" + npad8);
+ // int ndata8[] = new int[nwidth * nheight];
+ // ndata = new int[(nwidth * nheight) + 4];
+ byte bdata[] = new byte[(nwidth + npad8) * nheight];
+ // fs.read (bdata, 0, (nwidth+npad8)*nheight);
+ fs.read(bdata);
+ nindex8 = 0;
+ for (int j8 = 0; j8 < nheight; j8++) {
+ for (int i8 = 0; i8 < nwidth; i8++) {
+ // ndata[nwidth * (nheight - j8 - 1) + i8 + 4] = npalette[((int)
+ // bdata[nindex8] & 0xff)];
+ image.setPixel(i8, j8, npalette[((int) bdata[nindex8] & 0xff)]);
+ // System.out.println("Encoded Color at (" + i8 + "," + j8 + ")is: "
+ // + ndata[nwidth * (nheight - j8 - 1) + i8 + 4]);
+ nindex8++;
+ }
+ nindex8 += npad8;
+ }
+ // image = createImage ( new MemoryImageSource (nwidth, nheight,
+ // ndata8, 0, nwidth));
+ } else {
+ System.out.println("Not a 24-bit or 8-bit Windows Bitmap, aborting...");
+ // image = (Image)null;
+ }
+ fs.close();
+
+ // ndata[0] = nheight;
+ // ndata[1] = nwidth;
+ // ndata[2] = nheight * nwidth;
+ // ndata[3] = 2;
+
+ return image;
+ // return ndata;
+
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2009 (c) Florian Frankenberger (darkblue.de)
+ *
+ * This file is part of LEA.
+ *
+ * LEA is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * LEA is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with LEA. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * No description given.
+ *
+ * @author Florian Frankenberger
+ */
+
+
+public class IntegralImageData {
+
+
+ private long[][] integral;
+
+ private int width;
+
+ private int hegith;
+
+ // private Dimension dimension;
+
+ public IntegralImageData(Image bufferedImage) {
+ this.integral = new long[bufferedImage.getWidth()][bufferedImage.getHeight()];
+ this.width = bufferedImage.getWidth();
+ this.hegith = bufferedImage.getHeight();
+
+ long[][] s = new long[bufferedImage.getWidth()][bufferedImage.getHeight()];
+ for (int y = 0; y < bufferedImage.getHeight(); ++y) {
+ for (int x = 0; x < bufferedImage.getWidth(); ++x) {
+ s[x][y] = (y - 1 < 0 ? 0 : s[x][y - 1]) + (bufferedImage.getBlue(x, y) & 0xff);
+ this.integral[x][y] = (x - 1 < 0 ? 0 : this.integral[x - 1][y]) + s[x][y];
+ // System.out.println("integral ("+x+","+y+")="+integral[x][y]);
+ }
+ }
+
+ }
+
+ public long getIntegralAt( int x, int y) {
+ return this.integral[x][y];
+ }
+
+ public int getWidth() {
+ return width;
+ }
+
+ public int getHeight() {
+ return hegith;
+ }
+
+}
--- /dev/null
+public @interface LATTICE {
+ String value();
+}
--- /dev/null
+/*
+ * Copyright 2009 (c) Florian Frankenberger (darkblue.de)
+ *
+ * This file is part of LEA.
+ *
+ * LEA is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * LEA is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with LEA. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * This is the main class of LEA.
+ * <p>
+ * It uses a face detection algorithm to find an a face within the provided
+ * image(s). Then it searches for the eye in a region where it most likely
+ * located and traces its position relative to the face and to the last known
+ * position. The movements are estimated by comparing more than one movement. If
+ * a movement is distinctly pointing to a direction it is recognized and all
+ * listeners get notified.
+ * <p>
+ * The notification is designed as observer pattern. You simply call
+ * <code>addEyeMovementListener(IEyeMovementListener)</code> to add an
+ * implementation of <code>IEyeMovementListener</code> to LEA. When a face is
+ * recognized/lost or whenever an eye movement is detected LEA will call the
+ * appropriate methods of the listener
+ * <p>
+ * LEA also needs an image source implementing the <code>ICaptureDevice</code>.
+ * One image source proxy to the <code>Java Media Framework</code> is included (
+ * <code>JMFCaptureDevice</code>).
+ * <p>
+ * Example (for using LEA with <code>Java Media Framework</code>):
+ * <p>
+ * <code>
+ * LEA lea = new LEA(new JMFCaptureDevice(), true);
+ * </code>
+ * <p>
+ * This will start LEA with the first available JMF datasource with an extra
+ * status window showing if face/eye has been detected successfully. Please note
+ * that face detection needs about 2 seconds to find a face. After detection the
+ * following face detection is much faster.
+ *
+ * @author Florian Frankenberger
+ */
+
+
+public class LEA {
+
+
+ private LEAImplementation implementation;
+
+ private FaceAndEyePosition lastPositions = new FaceAndEyePosition(null, null);
+
+ private DeviationScanner deviationScanner = new DeviationScanner();
+
+ public LEA() {
+ // this.imageProcessor = new
+ // ImageProcessor(this.captureDevice.getFrameRate());
+ implementation = new LEAImplementation();
+ }
+
+ /**
+ * Clears the internal movement buffer. If you just capture some of the eye
+ * movements you should call this every time you start recording the
+ * movements. Otherwise you may get notified for movements that took place
+ * BEFORE you started recording.
+ */
+ public void clear() {
+ // this.imageProcessor.clearDeviationScanner();
+ }
+
+ /**
+ * @METHOD To test LEA with the first capture device from the
+ * <code>Java Media Framework</code> just start from here.
+ *
+ * @param args
+ * @throws Exception
+ */
+ public static void main(String[] args) throws Exception {
+ LEA lea = new LEA();
+ lea.doRun();
+ }
+
+
+ public void doRun() {
+
+ int i = 0;
+
+ SSJAVA: while (true) {
+ Image image = ImageReader.getImage();
+ if (image == null) {
+ break;
+ }
+ processImage(image);
+ }
+
+ System.out.println("Done.");
+
+ }
+
+
+ private void processImage( Image image) {
+ FaceAndEyePosition positions = implementation.getEyePosition(image);
+ // if (positions.getEyePosition() != null) {
+ deviationScanner.addEyePosition(positions.getEyePosition());
+ int deviation =
+ deviationScanner.scanForDeviation(positions.getFacePosition());// positions.getEyePosition().getDeviation(lastPositions.getEyePosition());
+ if (deviation != DeviationScanner.NONE) {
+ System.out.println("deviation=" + deviationScanner.toStringDeviation(deviation));
+ // notifyEyeMovementListenerEyeMoved(deviation);
+ }
+ // }
+ lastPositions = positions;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2009 (c) Florian Frankenberger (darkblue.de)
+ *
+ * This file is part of LEA.
+ *
+ * LEA is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * LEA is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with LEA. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * No description given.
+ *
+ * @author Florian Frankenberger
+ */
+
+
+public class LEAImplementation {
+
+
+ private ClassifierTree classifierTree;
+
+
+ private Rectangle2D lastRectangle;
+
+ public LEAImplementation() {
+ this.loadFaceData();
+ }
+
+
+
+ public FaceAndEyePosition getEyePosition( Image image) {
+ if (image == null)
+ return null;
+ Rectangle2D faceRect =
+ classifierTree.locateFaceRadial(image, lastRectangle);
+ if (faceRect.getWidth() > image.getWidth() || faceRect.getHeight() > image.getHeight()) {
+ return null;
+ }
+ EyePosition eyePosition = null;
+ if (faceRect != null) {
+ lastRectangle = faceRect;
+ faceRect = null;
+ Point point = readEyes(image, lastRectangle);
+ if (point != null) {
+ eyePosition = new EyePosition(point, lastRectangle);
+ }
+ } else {
+ lastRectangle = null;
+ }
+ System.out.println("eyePosition=" + eyePosition);
+
+ return new FaceAndEyePosition(lastRectangle, eyePosition);
+ }
+
+
+
+ private Point readEyes( Image image, Rectangle2D rect) {
+ EyeDetector ed = new EyeDetector(image, rect);
+ return ed.detectEye();
+ }
+
+ public boolean needsCalibration() {
+ return false;
+ }
+
+ /**
+ * This method loads the faceData from a file called facedata.dat which should
+ * be within the jar-file
+ */
+ private void loadFaceData() {
+
+ FileInputStream inputFile = new FileInputStream("facedata.dat");
+
+ int numClassifier = Integer.parseInt(inputFile.readLine());
+ classifierTree = new ClassifierTree(numClassifier);
+ for (int c = 0; c < numClassifier; c++) {
+
+ int numArea = Integer.parseInt(inputFile.readLine());
+ Classifier classifier = new Classifier(numArea);
+ // parsing areas
+ for (int idx = 0; idx < numArea; idx++) {
+ // 54,54,91,62,296.0
+ Point fromPoint = new Point();
+ Point toPoint = new Point();
+ fromPoint.x = Integer.parseInt(inputFile.readLine());
+ fromPoint.y = Integer.parseInt(inputFile.readLine());
+ toPoint.x = Integer.parseInt(inputFile.readLine());
+ toPoint.y = Integer.parseInt(inputFile.readLine());
+ float size = Float.parseFloat(inputFile.readLine());
+ ScanArea area = new ScanArea(fromPoint, toPoint, size);
+ classifier.setScanArea(idx, area);
+ }
+
+ // parsing possibilities face yes
+ float array[] = new float[numArea];
+ for (int idx = 0; idx < numArea; idx++) {
+ array[idx] = Float.parseFloat(inputFile.readLine());
+ }
+ classifier.setPossibilitiesFaceYes(array);
+
+ // parsing possibilities face no
+ array = new float[numArea];
+ for (int idx = 0; idx < numArea; idx++) {
+ array[idx] = Float.parseFloat(inputFile.readLine());
+ }
+ classifier.setPossibilitiesFaceNo(array);
+
+ classifier.setPossibilityFaceYes(Integer.parseInt(inputFile.readLine()));
+ classifier.setPossibilityFaceNo(Integer.parseInt(inputFile.readLine()));
+
+ classifierTree.addClassifier(c, classifier);
+ }
+ }
+
+}
--- /dev/null
+public @interface LOC {
+ String value();
+}
+
+public @interface RETURNLOC {
+ String value();
+}
\ No newline at end of file
--- /dev/null
+
+
+public class Point {
+
+ public int x;
+ public int y;
+
+ public Point(int x, int y) {
+ this.x = x;
+ this.y = y;
+ }
+
+ public Point() {
+ }
+
+ public String toString(){
+ return "("+x+","+y+")";
+ }
+
+}
--- /dev/null
+
+
+public class Rectangle2D {
+
+ double x;
+ double y;
+ double width;
+ double height;
+
+ public Rectangle2D(double x, double y, double w, double h) {
+ this.x = x;
+ this.y = y;
+ this.width = w;
+ this.height = h;
+ }
+
+ public double getX() {
+ return x;
+ }
+
+ public double getY() {
+ return y;
+ }
+
+ public double getWidth() {
+ return width;
+ }
+
+ public double getHeight() {
+ return height;
+ }
+
+ public String toString() {
+ return "(" + x + "," + y + "," + width + "," + height + ")";
+ }
+}
--- /dev/null
+/*
+ * Copyright 2009 (c) Florian Frankenberger (darkblue.de)
+ *
+ * This file is part of LEA.
+ *
+ * LEA is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * LEA is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with LEA. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ *
+ * @author Florian
+ */
+
+
+public class ScanArea {
+
+
+ private Point fromPoint;
+
+ private Point toPoint;
+
+ private float size;
+
+ /**
+ * Imagine you want to classify an image with 100px x 100px what would be the
+ * scanarea in this kind of image. That size gets automatically scalled to fit
+ * bigger images
+ *
+ * @param fromPoint
+ * @param toPoint
+ */
+ public ScanArea(Point fromPoint, Point toPoint) {
+ this.fromPoint = fromPoint;
+ this.toPoint = toPoint;
+
+ this.size = (this.toPoint.x - this.fromPoint.x) * (this.toPoint.y - this.fromPoint.y);
+ }
+
+ public ScanArea(Point fromPoint, Point toPoint, float size) {
+ this.fromPoint = fromPoint;
+ this.toPoint = toPoint;
+ this.size = size;
+ }
+
+ public ScanArea(int fromX, int fromY, int width, int height) {
+ this(new Point(fromX, fromY), new Point(fromX + width, fromY + height));
+ }
+
+ public int getFromX( float scaleFactor) {
+ return (int) (this.fromPoint.x * scaleFactor);
+ }
+
+ public int getFromY( float scaleFactor) {
+ return (int) (this.fromPoint.y * scaleFactor);
+ }
+
+ public int getToX( float scaleFactor) {
+ return (int) (this.toPoint.x * scaleFactor);
+ }
+
+ public int getToY( float scaleFactor) {
+ return (int) (this.toPoint.y * scaleFactor);
+ }
+
+ public int getSize( float scaleFactor) {
+ return (int) (this.size * Math.pow(scaleFactor, 2));
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ ScanArea other = (ScanArea) o;
+
+ return pointsWithin(other.fromPoint.x, other.toPoint.x, this.fromPoint.x, this.toPoint.x)
+ && pointsWithin(other.fromPoint.y, other.toPoint.y, this.fromPoint.y, this.toPoint.y);
+ }
+
+ private static boolean pointsWithin(int pointA1, int pointA2, int pointB1, int pointB2) {
+ boolean within = false;
+ within = within || (pointB1 >= pointA1 && pointB1 <= pointA2);
+ within = within || (pointB2 >= pointA1 && pointB2 <= pointA2);
+ within = within || (pointA1 >= pointB1 && pointA1 <= pointB2);
+ within = within || (pointA2 >= pointB1 && pointA2 <= pointB2);
+
+ return within;
+ }
+
+ // private boolean checkPoints(ScanArea a, ScanArea b) {
+ // Point[] pointsToCheck = new Point[] {
+ // a.fromPoint, a.toPoint,
+ // new Point (a.fromPoint.x, a.toPoint.y),
+ // new Point (a.toPoint.x, a.fromPoint.y)
+ // };
+ // for (Point point: pointsToCheck) {
+ // if (point.x >= b.fromPoint.x && point.x <= b.toPoint.x &&
+ // point.y >= b.fromPoint.y && point.y <= b.toPoint.y) return true;
+ // }
+ //
+ // return false;
+ // }
+
+ public String toString() {
+ String str = "";
+ str += "fromPoint=(" + fromPoint.x + "," + fromPoint.y + ")";
+ str += "toPoint=(" + toPoint.x + "," + toPoint.y + ")";
+ str += "size=" + size;
+ return str;
+ }
+}
--- /dev/null
+BUILDSCRIPT=../../../buildscript
+
+PROGRAM=LEA
+SOURCE_FILES=LEA.java
+
+ifndef INV_ERROR_PROB
+INV_ERROR_PROB=1000
+endif
+
+ifndef RANDOMSEED
+RANDOMSEED=12345
+endif
+
+SSJAVA= -ssjava -ssjavainfer -ssjavadebug
+BSFLAGS= -32bit -mainclass $(PROGRAM) -heapsize-mb 1350 -nooptimize -debug -garbagestats #-printlinenum #-joptimize
+NORMAL= -ssjava-inject-error 0 0
+INJECT_ERROR= -ssjava-inject-error $(INV_ERROR_PROB) $(RANDOMSEED)
+
+
+default: $(PROGRAM)s.bin
+
+normal: $(PROGRAM)n.bin
+
+error: $(PROGRAM)e.bin
+
+
+$(PROGRAM)s.bin: $(SOURCE_FILES) makefile
+ $(BUILDSCRIPT) $(SSJAVA) $(BSFLAGS) -o $(PROGRAM)s -builddir ssj $(SOURCE_FILES)
+
+$(PROGRAM)n.bin: $(SOURCE_FILES) makefile
+ $(BUILDSCRIPT) $(NORMAL) $(BSFLAGS) -o $(PROGRAM)n -builddir norm $(SOURCE_FILES)
+
+$(PROGRAM)e.bin: $(SOURCE_FILES) makefile
+ $(BUILDSCRIPT) $(SSJAVA) $(INJECT_ERROR) $(BSFLAGS) -o $(PROGRAM)e -builddir injerr $(SOURCE_FILES)
+
+cleanerror:
+ rm -f $(PROGRAM)e.bin
+ rm -rf injerr
+
+clean:
+ rm -f $(PROGRAM)s.bin $(PROGRAM)n.bin $(PROGRAM)e.bin
+ rm -fr ssj norm injerr
+ rm -f nve-diff.tmp nve-diff-ranges.tmp
+ rm -f *~
+ rm -f *.dot
+ rm -f *.png
+ rm -f *.pdf
+ rm -f aliases.txt
+ rm -f results*txt
+ rm -f output.txt
+ rm -f *log
+
--- /dev/null
+/*\r
+ * PWMRtsj.java\r
+ *\r
+ * Copyright (c) 1993-2002 Sun Microsystems, Inc. All Rights Reserved.\r
+ *\r
+ * This software is the confidential and proprietary information of Sun\r
+ * Microsystems, Inc. ("Confidential Information"). You shall not\r
+ * disclose such Confidential Information and shall use it only in\r
+ * accordance with the terms of the license agreement you entered into\r
+ * with Sun.\r
+ *\r
+ * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF\r
+ * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED\r
+ * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\r
+ * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR\r
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR\r
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.\r
+ */\r
+\r
+/**\r
+ * This class is a wrapper for a PWMControl introduced by porting to SSJava. It\r
+ * maintains two key fields motorLeftUpTime and motorRightUpTime and expects\r
+ * that the control thread who is running from the other side gets the current\r
+ * settings.\r
+ */\r
+\r
+\r
+\r
+public class MotorControl {\r
+ \r
+ boolean DEBUG = true;\r
+ \r
+ int motorLeftUpTime = 150;\r
+ \r
+ int motorRightUpTime = 150;\r
+ \r
+ int speedFactor;\r
+ \r
+ int agilityFactor;\r
+\r
+ public MotorControl(int speedFactor, int agilityFactor) {\r
+ this.speedFactor = speedFactor;\r
+ this.agilityFactor = agilityFactor;\r
+ }\r
+\r
+ // A poor's man ajustimg for the 0 speed which found\r
+ // to be 450000 nano seconds.\r
+ \r
+ private int normalizeTime( int timePosition) {\r
+ if ((timePosition <= 50) && (timePosition >= 44)) {\r
+ return 45;\r
+ }\r
+ return timePosition;\r
+ }\r
+\r
+ /**\r
+ * setSpeedSpin - Set speed for the spin case motor 1.\r
+ * \r
+ * @param uptime\r
+ * pulse width (time position)\r
+ */\r
+ public void setSpeedSpinLeft( int timePosition) {\r
+ /* Speed comes in as a number between 0 - 100 */\r
+ /* It represents values between 1 to 2 ms */\r
+ /* 100-input to get reverse polarity for this motor */\r
+ /* since it's mounted in reverse direction to the other motor */\r
+ if (DEBUG) {\r
+ System.out.println("setSpeedSpinLeft: input-> " + Integer.toString(timePosition));\r
+ }\r
+ int timePos = normalizeTime(timePosition);\r
+\r
+ int motorUpTime = (int) (timePos * agilityFactor * speedFactor);\r
+ // System.out.println("Left Motor UpTime1: " +\r
+ // Integer.toString(motorUpTime));\r
+ // Since the right motor is hanging in reverse position\r
+ // the direction should be opposit\r
+ // Bug in wait. Can't take 0 nanoseconds\r
+ if (motorUpTime == 0) {\r
+ motorUpTime = 1;\r
+ // System.out.println("returning....");\r
+ // return; // ndr\r
+ } else if (motorUpTime == 1000000) {\r
+ motorUpTime--;\r
+ }\r
+\r
+ // if (DEBUG) {\r
+ // System.out.println("setSpeedSpinLeft: output-> = " +\r
+ // Integer.toString(motorUpTime));\r
+ // }\r
+ // synchronized (this) {\r
+ /* Factor in the speed and agility factors */\r
+ motorLeftUpTime = motorUpTime;\r
+ // }\r
+ if (DEBUG) {\r
+ System.out.println("MotorControl: setSpeedSpinLeft: output-> " + motorLeftUpTime);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * setSpeedSpinRight - Set speed for the spin case right motor.\r
+ * \r
+ * @param uptime\r
+ * pulse width (time position)\r
+ */\r
+ public void setSpeedSpinRight( int timePosition) {\r
+ /* Speed comes in as a number between 0 - 100 */\r
+ /* It represents values between 1 to 2 ms */\r
+ /* An input of 50 should result in 0 speed. */\r
+ /* 100 should result in full speed forward */\r
+ /* while 0 should result in full speed backwords */\r
+ if (DEBUG) {\r
+ System.out.println("setSpeedSpinRight: input-> " + Integer.toString(timePosition));\r
+ }\r
+ int timePos = normalizeTime(timePosition);\r
+ int motorUpTime = (int) ((timePos) * agilityFactor * speedFactor);\r
+ // Bug in wait. Cant take 0 nanoseconds\r
+ if (motorUpTime == 0) {\r
+ motorUpTime = 1;\r
+ // System.out.println("returning....");\r
+ // return; // ndr\r
+ } else if (motorUpTime == 1000000) {\r
+ motorUpTime--;\r
+ }\r
+\r
+ // if (DEBUG) {\r
+ // System.out.println("setSpeedSpinRight: output-> = " +\r
+ // Integer.toString(motorUpTime));\r
+ // }\r
+ // synchronized (this) {\r
+ /* Factor in the speed and agility factors */\r
+ motorRightUpTime = motorUpTime;\r
+ // }\r
+ if (DEBUG) {\r
+ System.out.println("MotorControl: setSpeedSpinRight: output-> " + motorRightUpTime);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * setSpeedTurnM1 - set speed considering agility factor for motor 1\r
+ * \r
+ * @param uptime\r
+ * pulse width (time position)\r
+ */\r
+ public void setSpeedTurnLeft( int timePosition) {\r
+ /* Speed comes in as a number between 0 - 100 */\r
+ /* It represents values between 1 to 2 ms */\r
+ /* 100-input to get reverse polarity for this motor */\r
+ /* since it's mounted in reverse direction to the other motor */\r
+ if (DEBUG) {\r
+ System.out.println("setSpeedTurnLeft: input-> " + Integer.toString(timePosition));\r
+ }\r
+ int timePosLocal = normalizeTime(timePosition);\r
+ int motorUpTime =\r
+ (timePosLocal * 100 + ((100 - timePosLocal) * (100 - agilityFactor))) * speedFactor;\r
+ if (motorUpTime == 0) {\r
+ motorUpTime = 1;\r
+ // System.out.println("returning....");\r
+ // return; // ndr\r
+ } else if (motorUpTime == 1000000) {\r
+ motorUpTime--;\r
+ }\r
+ // if (DEBUG) {\r
+ // System.out.println("setSpeedTurnLeft: output-> = " +\r
+ // Integer.toString(motorUpTime));\r
+ // }\r
+ // synchronized (this) {\r
+ /* Factor in the speed and agility factors */\r
+ motorLeftUpTime = motorUpTime;\r
+ // }\r
+ if (DEBUG) {\r
+ System.out.println("MotorControl: setSpeedTurnLeft: output-> " + motorLeftUpTime);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * setSpeedTurnM1 - set speed considering agility factor for motor 2\r
+ * \r
+ * @param uptime\r
+ * pulse width (time position)\r
+ */\r
+ public void setSpeedTurnRight( int timePosition) {\r
+ /* Speed comes in as a number between 0 - 100 */\r
+ /* It represents values between 1 to 2 ms */\r
+ if (DEBUG) {\r
+ System.out.println("setSpeedTurnRight: input-> " + Integer.toString(timePosition));\r
+ }\r
+ int timePos = normalizeTime(timePosition);\r
+ int motorUpTime =\r
+ ((timePos * 100) + ((100 - timePos) * (100 - agilityFactor))) * speedFactor;\r
+ if (motorUpTime == 0) {\r
+ motorUpTime = 1;\r
+ // System.out.println("returning....");\r
+ // return; // ndr\r
+ } else if (motorUpTime == 1000000) {\r
+ motorUpTime--;\r
+ }\r
+\r
+ // synchronized (this) {\r
+ /* Factor in the speed and agility factors */\r
+ motorRightUpTime = motorUpTime;\r
+ // }\r
+ if (DEBUG) {\r
+ System.out.println("MotorControl: setSpeedTurnRight: output-> " + motorRightUpTime);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * setSpeedLeft - speed control for motor 1.\r
+ * \r
+ * @param uptime\r
+ * pulse width (time position)\r
+ */\r
+ public void setSpeedLeft( int timePosition) {\r
+ /* Speed comes in as a number between 0 - 100 */\r
+ /* It represents values between 1 to 2 ms */\r
+ /* 100-input to get reverse polarity for this motor */\r
+ /* since it's mounted in reverse direction to the other motor */\r
+ if (DEBUG) {\r
+ System.out.println("setSpeedLeft: input-> " + Integer.toString(timePosition));\r
+ }\r
+ int timePos = normalizeTime(timePosition);\r
+ int motorUpTime = (int) (timePos * 100) * speedFactor;\r
+ /*\r
+ * System.out.println("motorUpTime = " + Integer.toStri\r
+ * ng(motorUpTime) + " timePos = " + Integer.toString((int)timePos) +\r
+ * " timePosition = " + Integer.toString((int)timePosition) +\r
+ * " speedFactor = " + Integer.toString(speedFactor));\r
+ */\r
+ if (motorUpTime == 0) {\r
+ motorUpTime = 1;\r
+ // System.out.println("returning....");\r
+ // return; // ndr\r
+ } else if (motorUpTime == 1000000) {\r
+ motorUpTime--;\r
+ }\r
+\r
+ // synchronized (this) {\r
+ /* Factor in speedFactor */\r
+ motorLeftUpTime = motorUpTime;\r
+ // }\r
+ if (DEBUG) {\r
+ System.out\r
+ .println("MotorContol: setSpeedLeft: output-> " + Integer.toString(motorLeftUpTime));\r
+ }\r
+ }\r
+\r
+ /**\r
+ * setSpeedRight - speed control for motor 1.\r
+ * \r
+ * @param uptime\r
+ * pulse width (time position)\r
+ */\r
+ public void setSpeedRight( int timePosition) {\r
+ if (DEBUG) {\r
+ System.out.println("setSpeedRight: input-> " + Integer.toString(timePosition));\r
+ }\r
+ /* Speed comes in as a number between 0 - 100 */\r
+ /* It represents values between 1 to 2 ms */\r
+ int timePos = normalizeTime(timePosition);\r
+ int motorUpTime = (int) (timePos * 100) * speedFactor;\r
+ if (motorUpTime == 0) {\r
+ motorUpTime = 1;\r
+ // System.out.println("returning....");\r
+ // return; // ndr\r
+ } else if (motorUpTime == 1000000) {\r
+ motorUpTime--;\r
+ }\r
+ // synchronized (this) {\r
+ /* Factor in speedFactor */\r
+ motorRightUpTime = motorUpTime;\r
+ // }\r
+ if (DEBUG) {\r
+ System.out.println("MotorControl: setSpeedRight: output-> " + motorRightUpTime);\r
+ }\r
+ }\r
+\r
+ public void setUrgentReverse() {\r
+ // synchronized (this) {\r
+ motorLeftUpTime = 1;\r
+ motorRightUpTime = 1;\r
+ // }\r
+ if (DEBUG) {\r
+ System.out.println("MotorControl: setUrgentReverse: motorLeftUpTime-> " + motorLeftUpTime);\r
+ System.out.println("MotorControl: setUrgentReverse: motorRightUpTime-> " + motorRightUpTime);\r
+ }\r
+ }\r
+\r
+ public void setUrgentStraight() {\r
+ // synchronized (this) {\r
+ motorLeftUpTime = 99;\r
+ motorRightUpTime = 99;\r
+ if (DEBUG) {\r
+ System.out.println("MotorControl: setUrgentStraight: motorLeftUpTime-> " + motorLeftUpTime);\r
+ System.out.println("MotorControl: setUrgentStraight: motorRightUpTime-> " + motorRightUpTime);\r
+ }\r
+ // }\r
+ }\r
+\r
+ public void justSync() {\r
+ // synchronized (this) {\r
+ motorLeftUpTime = motorLeftUpTime;\r
+ motorRightUpTime = motorRightUpTime;\r
+ if (DEBUG) {\r
+ System.out.println("MotorControl: justSync: motorLeftUpTime-> " + motorLeftUpTime);\r
+ System.out.println("MotorControl: justSync: motorRightUpTime-> " + motorRightUpTime);\r
+ }\r
+ // }\r
+ }\r
+\r
+ /**\r
+ * Control debug messageing. true - Activate debug messages false - deactivate\r
+ * debug messages\r
+ */\r
+ public void setDebug(boolean debug) {\r
+ DEBUG = debug;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * PWMControl.java\r
+ *\r
+ * Copyright (c) 1993-2002 Sun Microsystems, Inc. All Rights Reserved.\r
+ *\r
+ * This software is the confidential and proprietary information of Sun\r
+ * Microsystems, Inc. ("Confidential Information"). You shall not\r
+ * disclose such Confidential Information and shall use it only in\r
+ * accordance with the terms of the license agreement you entered into\r
+ * with Sun.\r
+ *\r
+ * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF\r
+ * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED\r
+ * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\r
+ * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR\r
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR\r
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.\r
+ */\r
+\r
+/**\r
+ * This class is the super class of all motor control classes. The class\r
+ * represent a generic interface to such class. In our case the motor controller\r
+ * require for 0 speed 1.5 ms out of 10-20ms cycle and a change between 1 to 2\r
+ * seconds for max reverse and forward speed. These values: 1, 1.5, 2 and 20 ms\r
+ * are thus this class specific\r
+ * \r
+ * @author Michael Gesundheit\r
+ * @version 1.0\r
+ */\r
+\r
+public abstract class PWMControl {\r
+\r
+ PWMManager pwmManager;\r
+ boolean DEBUG = false;\r
+ // boolean DEBUG = true;\r
+ static final byte PULSE_HIGH = 1;\r
+ static final byte PULSE_LOW = 0;\r
+ int highMask;\r
+ int m1HighMask;\r
+ int m2HighMask;\r
+ int lowMask;\r
+ int myOwnBit;\r
+ int myBitPos;\r
+ int m1BitPos;\r
+ int m2BitPos;\r
+ int speedFactor;\r
+ int agilityFactor;\r
+ boolean updateTime;\r
+ int pulseWidth;\r
+ Object obj;\r
+\r
+ int motorLeftUpTime = 150;\r
+ int motorRightUpTime = 150;\r
+ boolean manualMode = false;\r
+\r
+ PWMControl(PWMManager pwmMan, int motor1bit, int motor2bit) {\r
+ pwmManager = pwmMan; // This is papa\r
+ m1BitPos = 0x1 << motor1bit;\r
+ m2BitPos = 0x1 << motor2bit;\r
+ m1HighMask = 0x1 << motor1bit;\r
+ m2HighMask = 0x1 << motor2bit;\r
+ lowMask = 0x0;\r
+ obj = new Object();\r
+ }\r
+\r
+ public void setManualMode() {\r
+ if (DEBUG)\r
+ System.out.println("PWMContolr: setManualMode... ");\r
+// synchronized (obj) {\r
+ if (manualMode == false) {\r
+ manualMode = true;\r
+ }\r
+// }\r
+ }\r
+\r
+ public void setAutomatedMode() {\r
+ if (DEBUG)\r
+ System.out.println("PWMControl: setAutomatedMode... ");\r
+// synchronized (obj) {\r
+ if (manualMode == true) {\r
+ System.out.println("PWMControl: wake me up... ");\r
+ manualMode = false;\r
+ // obj.notify();\r
+ System.out.println("PWMControl: wake me up...... tried!!!");\r
+ }\r
+// }\r
+ }\r
+\r
+ /**\r
+ * OutPut value to motor control line\r
+ */\r
+ public void outToPortMLeft(byte value) {\r
+ /*\r
+ * System.out.println("PWMControl " + Integer.toString(myOwnBit) +\r
+ * //" bit position = 0x" + Integer.toHexString(myOwnBit) +\r
+ * " output value = 0x" + Integer.toHexString(value));\r
+ */\r
+ if (value == PULSE_HIGH) {\r
+ pwmManager.writeToPort(m1BitPos, m1HighMask);\r
+ } else {\r
+ pwmManager.writeToPort(m1BitPos, lowMask);\r
+ }\r
+ }\r
+\r
+ public void outToPortMRight(byte value) {\r
+ /*\r
+ * System.out.println("PWMControl " + Integer.toString(myOwnBit) +\r
+ * //" bit position = 0x" + Integer.toHexString(myOwnBit) +\r
+ * " output value = 0x" + Integer.toHexString(value));\r
+ */\r
+ if (value == PULSE_HIGH) {\r
+ pwmManager.writeToPort(m2BitPos, m2HighMask);\r
+ } else {\r
+ pwmManager.writeToPort(m2BitPos, lowMask);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * setSpeedSpin - Set speed for the spin case motor 1.\r
+ * \r
+ * @param uptime\r
+ * pulse width (time position)\r
+ */\r
+ public void setSpeedSpinLeft(int timePosition) {\r
+ }\r
+\r
+ /**\r
+ * setSpeedSpinRight - Set speed for the spin case right motor.\r
+ * \r
+ * @param uptime\r
+ * pulse width (time position)\r
+ */\r
+ public void setSpeedSpinRight(int timePosition) {\r
+ }\r
+\r
+ /**\r
+ * setSpeedTurnM1 - set speed considering agility factor for motor 1\r
+ * \r
+ * @param uptime\r
+ * pulse width (time position)\r
+ */\r
+ public void setSpeedTurnLeft(int timePosition) {\r
+ }\r
+\r
+ /**\r
+ * setSpeedTurnM1 - set speed considering agility factor for motor 2\r
+ * \r
+ * @param uptime\r
+ * pulse width (time position)\r
+ */\r
+ public void setSpeedTurnRight(int timePosition) {\r
+ }\r
+\r
+ /**\r
+ * setSpeedLeft - speed control for motor 1.\r
+ * \r
+ * @param uptime\r
+ * pulse width (time position)\r
+ */\r
+ public void setSpeedLeft(int timePosition) {\r
+ }\r
+\r
+ /**\r
+ * setSpeedRight - speed control for motor 1.\r
+ * \r
+ * @param uptime\r
+ * pulse width (time position)\r
+ */\r
+ public void setSpeedRight(int timePosition) {\r
+ }\r
+\r
+ public void setSpeedAgilityFactors(int speed, int agility) {\r
+// synchronized (this) {\r
+ speedFactor = speed;\r
+ agilityFactor = agility;\r
+// }\r
+ }\r
+\r
+ public void setUrgentReverse() {\r
+ }\r
+\r
+ public void setUrgentStraight() {\r
+ }\r
+\r
+ /**\r
+ * Control debug messageing. true - Activate debug messages false - deactivate\r
+ * debug messages\r
+ */\r
+ public void setDebug(boolean debug) {\r
+ DEBUG = debug;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * PWMManager.java\r
+ *\r
+ * Copyright (c) 1993-2002 Sun Microsystems, Inc. All Rights Reserved.\r
+ *\r
+ * This software is the confidential and proprietary information of Sun\r
+ * Microsystems, Inc. ("Confidential Information"). You shall not\r
+ * disclose such Confidential Information and shall use it only in\r
+ * accordance with the terms of the license agreement you entered into\r
+ * with Sun.\r
+ *\r
+ * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF\r
+ * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED\r
+ * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\r
+ * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR\r
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR\r
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.\r
+ */\r
+\r
+/**\r
+ * PWMManager - Interface between robot strategy code and the various motors\r
+ * PWMControl classes. Agility is a number between 0 to 100 and represent the\r
+ * precentage of max speed to be applied to the turn side wheel. On left turn\r
+ * the left wheel will receive less speed as % of "speed" value represented by\r
+ * agility.\r
+ * \r
+ * @author Michael Gesundheit\r
+ * @version 1.0\r
+ */\r
+\r
+\r
+\r
+public class PWMManager {\r
+\r
+ // private int GPIO_A_OER = 0x09002000;\r
+ // private int GPIO_A_OUT = GPIO_A_OER + 4;\r
+ // private int GPIO_E_OER = 0x09002400;\r
+ // private int GPIO_E_OUT = 0x09002404;\r
+ // private byte MOTOR_PORTID_6 = 6; // Bit 2 (...3,2,1,0)\r
+ // private byte MOTOR_PORTID_7 = 7; // Bit 3 (...3,2,1,0)\r
+ \r
+ private int currentRegMask;\r
+ \r
+ private boolean DEBUG = false;\r
+ // private PWMControl pwmControl;\r
+ \r
+ private RCBridge rcb;\r
+ \r
+ private int speedFactor;\r
+ \r
+ private int agilityFactor;\r
+ \r
+ private int zeroSpeed = 45;\r
+\r
+ /**\r
+ * Constractor\r
+ */\r
+ public PWMManager(String pwmSelection) {\r
+ /*\r
+ * Instantiate PWM Makers one for each motor. motorPortId is 1 to 8 and is\r
+ * corresponding to 8 bits in a byte.\r
+ */\r
+ // if (pwmSelection.equals("rtsj"))\r
+ // pwmControl = new PWMRtsj(this, MOTOR_PORTID_6, MOTOR_PORTID_7);\r
+ // else {\r
+ // System.out.println("Selection PWMNative is activated");\r
+ // pwmControl = new PWMNative(this, MOTOR_PORTID_6, MOTOR_PORTID_7);\r
+ // System.out.println("Selection PWMNative is activated.... Return");\r
+ // }\r
+\r
+ // rcb = new RCBridge(this);\r
+ rcb = new RCBridge();\r
+\r
+ /* Enable input bits 0,1 Enable output for the rest */\r
+ // rawJEM.set(GPIO_E_OER, 0x00C0);\r
+ }\r
+\r
+ public void setManualMode() {\r
+ if (DEBUG)\r
+ System.out.println("PWMManager: setManualMode....");\r
+ // pwmControl.setManualMode();\r
+ rcb.setManualMode();\r
+ }\r
+\r
+ public void setAutomatedMode() {\r
+ if (DEBUG)\r
+ System.out.println("PWMManager: setAutomatedMode....");\r
+ // pwmControl.setAutomatedMode();\r
+ rcb.setAutomatedMode();\r
+ }\r
+\r
+ // public PWMControl getPWMControl() {\r
+ // if (DEBUG)\r
+ // System.out.println("PWMManager: getPWMControl....");\r
+ // return pwmControl;\r
+ // }\r
+\r
+ public synchronized void writeToPort(int myBit, int myValue) {\r
+ currentRegMask &= ~myBit; // e.g. 0x11110111\r
+ currentRegMask |= myValue;\r
+ /*\r
+ * // if (DEBUG){ // System.out.println("PWMM: writeToPort: myBit = 0x" +\r
+ * Integer.toHexString(myBit) + // " ~myBit = 0x" +\r
+ * Integer.toHexString(~myBit) + " myValue = 0x" + //\r
+ * Integer.toHexString(myValue) + " currentRegMask = 0x" + //\r
+ * Integer.toHexString(currentRegMask)); //}\r
+ */\r
+ // rawJEM.set(GPIO_E_OUT, currentRegMask);\r
+ }\r
+\r
+ /*\r
+ * public void stop(){ if(DEBUG) System.out.println("PWMManager: stop....");\r
+ * pwmControl.setSpeedLeft(zeroSpeed); pwmControl.setSpeedRight(zeroSpeed); }\r
+ * \r
+ * public void search(){ if(DEBUG)\r
+ * System.out.println("PWMManager: search...."); pwmControl.setSpeedLeft(70);\r
+ * pwmControl.setSpeedRight(50); }\r
+ * \r
+ * public void straight(){ if(DEBUG)\r
+ * System.out.println("PWMManager: strait...."); pwmControl.setSpeedLeft(100);\r
+ * pwmControl.setSpeedRight(100); }\r
+ * \r
+ * public void spinRight(){ if(DEBUG)\r
+ * System.out.println("PWMManager: spinRight....");\r
+ * pwmControl.setSpeedSpinLeft(100); pwmControl.setSpeedSpinRight(0); }\r
+ * \r
+ * public void spinLeft(){ if(DEBUG)\r
+ * System.out.println("PWMManager: spinLeft....");\r
+ * pwmControl.setSpeedSpinLeft(0); pwmControl.setSpeedSpinRight(100); }\r
+ * \r
+ * public void spin180(){ int mod = (rand.nextInt() % 2);\r
+ * \r
+ * if(DEBUG) System.out.println("PWMManager: spin180...."); if(mod == 1){\r
+ * pwmControl.setSpeedSpinLeft(0); pwmControl.setSpeedSpinRight(100); }else{\r
+ * pwmControl.setSpeedSpinLeft(100); pwmControl.setSpeedSpinRight(0); } }\r
+ * \r
+ * public void right(){ if(DEBUG) System.out.println("PWMManager: right....");\r
+ * pwmControl.setSpeedTurnLeft(100); pwmControl.setSpeedRight(zeroSpeed); }\r
+ * \r
+ * public void left(){ if(DEBUG) System.out.println("PWMManager: left....");\r
+ * pwmControl.setSpeedLeft(zeroSpeed); pwmControl.setSpeedTurnRight(100); }\r
+ * \r
+ * public void bearRight(){ if(DEBUG)\r
+ * System.out.println("PWMManager: bearRight....");\r
+ * pwmControl.setSpeedTurnLeft(100); pwmControl.setSpeedTurnRight(60); }\r
+ * \r
+ * public void bearLeft(){ if(DEBUG)\r
+ * System.out.println("PWMManager: bearLeft....");\r
+ * pwmControl.setSpeedTurnLeft(60); pwmControl.setSpeedTurnRight(100); }\r
+ * \r
+ * public void back(){ if(DEBUG) System.out.println("PWMManager: back....");\r
+ * pwmControl.setSpeedLeft(0); pwmControl.setSpeedRight(0); }\r
+ * \r
+ * public void backBearLeft(){ if(DEBUG)\r
+ * System.out.println("PWMManager: backBearLeft....");\r
+ * pwmControl.setSpeedLeft(30); pwmControl.setSpeedRight(0); }\r
+ * \r
+ * public void backBearRight(){ if(DEBUG)\r
+ * System.out.println("PWMManager: backBearRight....");\r
+ * pwmControl.setSpeedLeft(0); pwmControl.setSpeedRight(30); }\r
+ */\r
+ public void resume() {\r
+ if (DEBUG)\r
+ System.out.println("PWMManager: Reasume...........");\r
+ }\r
+\r
+ /**\r
+ * setSpeedFactor - set speed factor value\r
+ * \r
+ * @param speed\r
+ * factor\r
+ */\r
+ public synchronized void setSpeedFactor(int speedFactor) {\r
+ if (DEBUG)\r
+ System.out.println("PWMManager: setSpeedFactor....");\r
+ this.speedFactor = speedFactor;\r
+ // pwmControl.setSpeedAgilityFactors(speedFactor, agilityFactor);\r
+ }\r
+\r
+ /**\r
+ * setAgilityFactor\r
+ * \r
+ * @param agility\r
+ * factor\r
+ */\r
+ public synchronized void setAgilityFactor(int agilityFactor) {\r
+ if (DEBUG)\r
+ System.out.println("PWMManager: setAgilityFactor....");\r
+ this.agilityFactor = agilityFactor;\r
+ // pwmControl.setSpeedAgilityFactors(speedFactor, agilityFactor);\r
+ }\r
+\r
+ /**\r
+ * setSpeedAgilityFactors - set both speed and agility\r
+ * \r
+ * @param speed\r
+ * @param agility\r
+ */\r
+ public synchronized void setSpeedAgilityFactors( int speed, int agility) {\r
+ if (DEBUG)\r
+ System.out.println("PWMManager: setSpeedAgilityFactors....");\r
+ speedFactor = speed;\r
+ agilityFactor = agility;\r
+ // pwmControl.setSpeedAgilityFactors(speedFactor, agilityFactor);\r
+ }\r
+\r
+ /**\r
+ * Control debug messaging. true - Activate debug messages false - deactivate\r
+ * debug messages\r
+ */\r
+ public void setDebug(boolean debug) {\r
+ DEBUG = debug;\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/*\r
+ * PWMNative.java\r
+ *\r
+ * Copyright (c) 1993-2002 Sun Microsystems, Inc. All Rights Reserved.\r
+ *\r
+ * This software is the confidential and proprietary information of Sun\r
+ * Microsystems, Inc. ("Confidential Information"). You shall not\r
+ * disclose such Confidential Information and shall use it only in\r
+ * accordance with the terms of the license agreement you entered into\r
+ * with Sun.\r
+ *\r
+ * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF\r
+ * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED\r
+ * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\r
+ * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR\r
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR\r
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.\r
+ */\r
+\r
+//public class PWMNative extends PWMControl implements Runnable, InterruptEventListener {\r
+public class PWMNative extends PWMControl {\r
+\r
+ private int PULSE_INTERVAL = 2000;\r
+ private int NATIVE_OFFSET = 100;\r
+ private Object obj;\r
+ private Object tc0Obj;\r
+ private Object tc1Obj;\r
+ private int pulseUpTime;\r
+\r
+ // private TimerCounter tc0;\r
+ // private TimerCounter tc1;\r
+ // private TimerCounter[] tcSet = new TimerCounter[2];\r
+\r
+ PWMNative(PWMManager pwmMan, int motor1bit, int motor2bit) {\r
+ super(pwmMan, motor1bit, motor2bit);\r
+\r
+ System.out.println("PWMNative constructor.....Start");\r
+ obj = new Object();\r
+ tc0Obj = new Object();\r
+ tc1Obj = new Object();\r
+\r
+ // TimerCounter.setPrescalerClockSource(TimerCounter.INTERNAL_PERIPHERAL_CLOCK);\r
+ // TimerCounter.setPrescalerReloadRegisterValue(375);\r
+ // TimerCounter.setPrescalerEnabled(true);\r
+\r
+ // tc0 = tcSet[0] = new TimerCounter(0);\r
+ // tc0.setMode_IO_Line_A(TimerCounter.TIMER_0_OUTPUT);\r
+ // // bring TIMER_0_OUTPUT_DIVIDE_BY_2 out via IO_Line_B\r
+ // tc0.setMode_IO_Line_B(TimerCounter.TIMER_0_OUTPUT_DIVIDE_BY_2);\r
+ // // In JemBuilder, go to Pin Setup 2 and allocate Port E bit 6 to\r
+ // // be Timer IO_Line_B.\r
+ //\r
+ // // Connect signal lead of servo (usually the white one) to IOE6 on\r
+ // // JStamp\r
+ // tc0.set_IO_Line_A_Polarity(TimerCounter.POLARITY_ACTIVE_STATE_HIGH);\r
+ // tc0.set_IO_Line_B_Polarity(TimerCounter.POLARITY_ACTIVE_STATE_HIGH);\r
+ // tc0.setExternalTimerEnableMode(TimerCounter.TIMER_ENABLED_ONLY_VIA_MTEN_AND_TRIGGER);\r
+ // tc0.setReloadRegisterValue(100);\r
+ // tc0.setExternalStartTriggerMode(TimerCounter.NO_EXTERNAL_START_TRIGGER);\r
+ // tc0.setMasterTimerEnabled(true);\r
+ // tc0.setGlobalInterruptEnabled(true);\r
+ // tc0.setTimeOutInterruptEnabled(true);\r
+ // tc0.setTimerTriggerRegister(false);\r
+ // System.out.println("PWMNative: Constructor completed 1....");\r
+ /*\r
+ * tc1 = tcSet[1] = new TimerCounter ( 1 ); tc1.setMode_IO_Line_A(\r
+ * TimerCounter.TIMER_1_OUTPUT ); //bring TIMER_0_OUTPUT_DIVIDE_BY_2 out via\r
+ * IO_Line_B tc1.setMode_IO_Line_B( TimerCounter.TIMER_1_OUTPUT_DIVIDE_BY_2\r
+ * ); //In JemBuilder, go to Pin Setup 2 and allocate Port E bit 6 to //be\r
+ * Timer IO_Line_B.\r
+ * tc1.set_IO_Line_A_Polarity(TimerCounter.POLARITY_ACTIVE_STATE_HIGH);\r
+ * tc1.set_IO_Line_B_Polarity(TimerCounter.POLARITY_ACTIVE_STATE_HIGH);\r
+ * tc1.setExternalTimerEnableMode\r
+ * (TimerCounter.TIMER_ENABLED_ONLY_VIA_MTEN_AND_TRIGGER );\r
+ * tc1.setReloadRegisterValue( 100 );\r
+ * tc1.setExternalStartTriggerMode(TimerCounter.NO_EXTERNAL_START_TRIGGER );\r
+ * tc1.setMasterTimerEnabled( true ); tc1.setGlobalInterruptEnabled( true);\r
+ * tc1.setTimeOutInterruptEnabled( true); tc1.setTimerTriggerRegister( false\r
+ * );\r
+ */\r
+ /*\r
+ * // Add interrupt event listener for GPTC\r
+ * InterruptController.addInterruptListener( this,\r
+ * InterruptController.GPTC_INTERRUPT );\r
+ * \r
+ * // Turn on interrupts InterruptController.enableInterrupt(\r
+ * InterruptController.GPTC_INTERRUPT );\r
+ * \r
+ * // start all prescaler based timers TimerCounter.setPrescalerEnabled(\r
+ * true );\r
+ */\r
+ // t2 = new Thread(this);\r
+ // t2.start();\r
+ // t2.setPriority(20);\r
+ System.out.println("PWMNative: Constructor return.....");\r
+ }\r
+\r
+ public void setUpTime(int upTime) {\r
+ // synchronized (obj) {\r
+ pulseUpTime = upTime;\r
+ // }\r
+ }\r
+\r
+ /*\r
+ * public void interruptEvent() { TimerCounter tc; int tcIntrState;\r
+ * \r
+ * System.out.println("PWMNative: InterruptEvent"); do { for ( int tcNum=0;\r
+ * tcNum<2; tcNum++ ) { tc = tcSet[ tcNum ];\r
+ * if(tc.readAndClear_TimeOutInterruptStatus()){ switch(tcNum){ case 0:\r
+ * System.out.println("PWMNative: Interrupt case 0"); synchronized(tc0Obj){\r
+ * System.out.println("PWMNative: Interrupt notify 0"); tc0Obj.notify(); }\r
+ * break; case 1: System.out.println("PWMNative: Interrupt case 1");\r
+ * synchronized(tc1Obj){ System.out.println("PWMNative: Interrupt notify 1");\r
+ * tc1Obj.notify(); } break; default:; } } } } while (\r
+ * TimerCounter.isGPTCInterruptPending() ); }\r
+ */\r
+ public void run() {\r
+ //\r
+ // System.out.println("PWMNative: run method........");\r
+ // int upTime0 = 150; // 1.5 milli seconds = 0 speed\r
+ // int upTime1 = 150; // 1.5 milli seconds = 0 speed\r
+ //\r
+ // while (true) {\r
+ // synchronized (obj) {\r
+ // /*\r
+ // * System.out.println("PWMNative: Updating Up Times......Left = " +\r
+ // * Integer.toString(motorLeftUpTime) + " Right = " +\r
+ // * Integer.toString(motorRightUpTime));\r
+ // */\r
+ // upTime0 = motorLeftUpTime;\r
+ // upTime1 = motorRightUpTime;\r
+ // }\r
+ //\r
+ // // Timer number 1\r
+ // tc0.setReloadRegisterValue(upTime0);\r
+ // outToPortMLeft(PULSE_HIGH);\r
+ // tc0.setTimerTriggerRegister(true);\r
+ // do {\r
+ // } while (tc0.didTimeOutInterruptOccur());\r
+ // outToPortMLeft(PULSE_LOW);\r
+ // tc0.setTimerTriggerRegister(false);\r
+ // tc0.resetTimeOutInterruptStatus();\r
+ //\r
+ // // System.out.println("PWMNative: Big loop long suspend1");\r
+ // try {\r
+ // tc0Obj.wait(18, 500000);\r
+ // } catch (Exception e) {\r
+ // }\r
+ // // System.out.println("PWMNative: Big loop long suspend2");\r
+ //\r
+ // tc0.setReloadRegisterValue(upTime1);\r
+ // outToPortMRight(PULSE_HIGH);\r
+ // tc0.setTimerTriggerRegister(true);\r
+ // do {\r
+ // } while (tc0.didTimeOutInterruptOccur());\r
+ // outToPortMRight(PULSE_LOW);\r
+ // tc0.setTimerTriggerRegister(false);\r
+ // tc0.resetTimeOutInterruptStatus();\r
+ //\r
+ // try {\r
+ // tc0Obj.wait(18, 500000);\r
+ // } catch (Exception e) {\r
+ // }\r
+\r
+ /*\r
+ * // Timer number 2 tc1.setReloadRegisterValue( upTime1 );\r
+ * tc1.setTimerTriggerRegister( true ); synchronized(tc1Obj){ try{\r
+ * System.out.println("PWMNative: Sleep 3"); tc1Obj.wait();\r
+ * System.out.println("PWMNative: Wake Up 3"); }catch(Exception e){ } }\r
+ * tc1.setTimerTriggerRegister( false ); tc1.resetTimeOutInterruptStatus();\r
+ * tc1.setReloadRegisterValue( PULSE_INTERVAL - upTime1 ); //this sets pulse\r
+ * interval tc1.setTimerTriggerRegister( true ); synchronized(tc1Obj){ try{\r
+ * System.out.println("PWMNative: Sleep 3"); tc1Obj.wait();\r
+ * System.out.println("PWMNative: Wake Up 3"); }catch(Exception e){ } }\r
+ * tc1.setTimerTriggerRegister( false ); tc1.resetTimeOutInterruptStatus();\r
+ */\r
+ // }\r
+ }\r
+\r
+ public void setManualMode() {\r
+ if (DEBUG)\r
+ System.out.println("PWMControl: setManualMode... ");\r
+ // synchronized (obj) {\r
+ if (manualMode == false) {\r
+ manualMode = true;\r
+ }\r
+ // }\r
+ }\r
+\r
+ public void setAutomatedMode() {\r
+ if (DEBUG)\r
+ System.out.println("PWMControl: setAutomatedMode... ");\r
+ /*\r
+ * synchronized(obj){ if(manualMode == true){\r
+ * System.out.println("PWMControl: wake me up... "); obj.notifyAll();\r
+ * manualMode = false; } }\r
+ */\r
+ }\r
+\r
+ /**\r
+ * setSpeedSpin - Set speed for the spin case motor 1.\r
+ * \r
+ * @param uptime\r
+ * pulse width (time position)\r
+ */\r
+ public void setSpeedSpinLeft(int timePosition) {\r
+ /* Speed comes in as a number between 0 - 100 */\r
+ /* It represents values between 1 to 2 ms */\r
+ /* 100-input to get reverse polarity for this motor */\r
+ /* since it's mounted in reverse direction to the other motor */\r
+\r
+ if (DEBUG) {\r
+ System.out.println("setSpeedSpinLeft: input-> " + Integer.toString(timePosition));\r
+ }\r
+ int timePos = timePosition + NATIVE_OFFSET;\r
+ int motorUpTime = (int) (timePos * agilityFactor * speedFactor) / 10000;\r
+\r
+ if (DEBUG) {\r
+ System.out.println("setSpeedSpinLeft: output-> = " + Integer.toString(motorUpTime));\r
+ }\r
+ // synchronized (obj) {\r
+ /* Factor in the speed and agility factors */\r
+ motorLeftUpTime = motorUpTime;\r
+ // }\r
+ }\r
+\r
+ /**\r
+ * setSpeedSpinRight - Set speed for the spin case right motor.\r
+ * \r
+ * @param uptime\r
+ * pulse width (time position)\r
+ */\r
+ public void setSpeedSpinRight(int timePosition) {\r
+ /* Speed comes in as a number between 0 - 100 */\r
+ /* It represents values between 1 to 2 ms */\r
+ /* An input of 50 should result in 0 speed. */\r
+ /* 100 should result in full speed forward */\r
+ /* while 0 should result in full speed backwords */\r
+ if (DEBUG) {\r
+ System.out.println("setSpeedSpinRight: input-> " + Integer.toString(timePosition));\r
+ }\r
+ int timePos = timePosition + NATIVE_OFFSET;\r
+ int motorUpTime = (int) ((timePos) * agilityFactor * speedFactor) / 10000;\r
+\r
+ if (DEBUG) {\r
+ System.out.println("setSpeedSpinRight: output-> = " + Integer.toString(motorUpTime));\r
+ }\r
+ // synchronized (obj) {\r
+ /* Factor in the speed and agility factors */\r
+ motorRightUpTime = motorUpTime;\r
+ // }\r
+ }\r
+\r
+ /**\r
+ * setSpeedTurnM1 - set speed considering agility factor for motor 1\r
+ * \r
+ * @param uptime\r
+ * pulse width (time position)\r
+ */\r
+ public void setSpeedTurnLeft(int timePosition) {\r
+ /* Speed comes in as a number between 0 - 100 */\r
+ /* It represents values between 1 to 2 ms */\r
+ /* 100-input to get reverse polarity for this motor */\r
+ /* since it's mounted in reverse direction to the other motor */\r
+ if (DEBUG) {\r
+ System.out.println("setSpeedTurnLeft: input-> " + Integer.toString(timePosition));\r
+ }\r
+ int timePosLocal = timePosition + NATIVE_OFFSET;\r
+ int motorUpTime =\r
+ ((timePosLocal * 100 + ((100 - timePosLocal) * (100 - agilityFactor))) * speedFactor) / 10000;\r
+ if (DEBUG) {\r
+ System.out.println("setSpeedTurnLeft: output-> = " + Integer.toString(motorUpTime));\r
+ }\r
+ // synchronized (obj) {\r
+ /* Factor in the speed and agility factors */\r
+ motorLeftUpTime = motorUpTime;\r
+ // }\r
+ }\r
+\r
+ /**\r
+ * setSpeedTurnM1 - set speed considering agility factor for motor 2\r
+ * \r
+ * @param uptime\r
+ * pulse width (time position)\r
+ */\r
+ public void setSpeedTurnRight(int timePosition) {\r
+ /* Speed comes in as a number between 0 - 100 */\r
+ /* It represents values between 1 to 2 ms */\r
+ if (DEBUG) {\r
+ System.out.println("setSpeedTurnRight: input-> " + Integer.toString(timePosition));\r
+ }\r
+ int timePos = timePosition + NATIVE_OFFSET;\r
+ int motorUpTime =\r
+ (((timePos * 100) + ((100 - timePos) * (100 - agilityFactor))) * speedFactor) / 10000;\r
+\r
+ if (DEBUG) {\r
+ System.out.println("setSpeedTurnRight: output-> " + Integer.toString(motorUpTime));\r
+ }\r
+ // synchronized (obj) {\r
+ /* Factor in the speed and agility factors */\r
+ motorRightUpTime = motorUpTime;\r
+ // }\r
+ }\r
+\r
+ /**\r
+ * setSpeedLeft - speed control for motor 1.\r
+ * \r
+ * @param uptime\r
+ * pulse width (time position)\r
+ */\r
+ public void setSpeedLeft(int timePosition) {\r
+ /* Speed comes in as a number between 0 - 100 */\r
+ /* It represents values between 1 to 2 ms */\r
+ /* 100-input to get reverse polarity for this motor */\r
+ /* since it's mounted in reverse direction to the other motor */\r
+ if (DEBUG) {\r
+ System.out.println("setSpeedLeft: input-> " + Integer.toString(timePosition));\r
+ }\r
+ int timePos = timePosition + NATIVE_OFFSET;\r
+ int motorUpTime = (int) ((timePos * 100) * speedFactor) / 10000;\r
+\r
+ if (DEBUG) {\r
+ System.out.println("setSpeedLeft: output-> " + Integer.toString(motorUpTime));\r
+ }\r
+ // synchronized (obj) {\r
+ /* Factor in speedFactor */\r
+ motorLeftUpTime = motorUpTime;\r
+ // }\r
+ }\r
+\r
+ /**\r
+ * setSpeedRight - speed control for motor 1.\r
+ * \r
+ * @param uptime\r
+ * pulse width (time position)\r
+ */\r
+ public void setSpeedRight(int timePosition) {\r
+ if (DEBUG) {\r
+ System.out.println("setSpeedRight: input-> " + Integer.toString(timePosition));\r
+ }\r
+ /* Speed comes in as a number between 0 - 100 */\r
+ /* It represents values between 1 to 2 ms */\r
+ int timePos = timePosition + NATIVE_OFFSET;\r
+ int motorUpTime = (int) (((timePos * 100) * speedFactor) / 10000);\r
+\r
+ if (DEBUG) {\r
+ System.out.println("setSpeedRight: output-> " + Integer.toString(motorUpTime));\r
+ }\r
+ // synchronized (obj) {\r
+ /* Factor in speedFactor */\r
+ motorRightUpTime = motorUpTime;\r
+ // }\r
+ }\r
+\r
+ public void setSpeedAgilityFactors(int speed, int agility) {\r
+ // synchronized (obj) {\r
+ speedFactor = speed;\r
+ agilityFactor = agility;\r
+ // }\r
+ }\r
+\r
+ public void setUrgentReverse() {\r
+ // synchronized (obj) {\r
+ motorLeftUpTime = 1;\r
+ motorRightUpTime = 1;\r
+ // }\r
+ }\r
+\r
+ /**\r
+ * Control debug messageing. true - Activate debug messages false - deactivate\r
+ * debug messages\r
+ */\r
+ public void setDebug(boolean debug) {\r
+ DEBUG = debug;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * PWMRtsj.java\r
+ *\r
+ * Copyright (c) 1993-2002 Sun Microsystems, Inc. All Rights Reserved.\r
+ *\r
+ * This software is the confidential and proprietary information of Sun\r
+ * Microsystems, Inc. ("Confidential Information"). You shall not\r
+ * disclose such Confidential Information and shall use it only in\r
+ * accordance with the terms of the license agreement you entered into\r
+ * with Sun.\r
+ *\r
+ * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF\r
+ * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED\r
+ * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\r
+ * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR\r
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR\r
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.\r
+ */\r
+\r
+/**\r
+ * This class is motor controller specific. In our case the motor controller\r
+ * require for 0 speed 1.5 ms out of 10-20ms cycle and a change between 1 to 2\r
+ * seconds for max reverse and forward speed. These values: 1, 1.5, 2 and 20 ms\r
+ * are thus this class specific\r
+ * \r
+ * @author Michael Gesundheit\r
+ * @version 1.0\r
+ */\r
+\r
+public class PWMRtsj extends PWMControl {\r
+\r
+ // RelativeTime zeroSpeedDuration;\r
+ // RelativeTime timeUpDuration;\r
+ // RelativeTime timeDownDuration;\r
+ // RelativeTime cycleTime;\r
+ boolean updateTime;\r
+ int sleepUpDurationNano = 500000;\r
+ long sleepUpDurationMilli = 1;\r
+ int sleepDownDurationNano = 500000;\r
+ long sleepDownDurationMilli = 18;\r
+ int pulseWidth;\r
+ // Object obj;\r
+\r
+ private static final int GPIO_A_OER = 0x09002000;\r
+ private static final int GPIO_A_OUT = GPIO_A_OER + 4;\r
+ private static final int GPIO_A_IN = GPIO_A_OER + 8;\r
+\r
+ /**\r
+ * Constructor - Start a standard Java thread. The thread is suspended and\r
+ * will wake up evey 18 ms. It will issue a 1-2ms pulse and suspends itself\r
+ * again to 18ms. This is to have a total of 20ms or less yet it's the maxim\r
+ * possible cycle so as to load the cpu as little as possible.\r
+ */\r
+ public PWMRtsj(PWMManager pwmMan, int motor1bit, int motor2bit) {\r
+\r
+ super(pwmMan, motor1bit, motor2bit); // This is papa\r
+\r
+ motorLeftUpTime = 450000; // Nano seconds\r
+ motorRightUpTime = 450000; // Nano seconds\r
+\r
+ if (DEBUG) {\r
+ System.out.println("PWMRtsj: About to start RoboThread...");\r
+ }\r
+\r
+ // t2 = new RoboThread();\r
+ // t2.start();\r
+ // t2.setPriority(10);\r
+ }\r
+\r
+ // A poor's man ajustimg for the 0 speed which found\r
+ // to be 450000 nano seconds.\r
+ private int normalizeTime(int timePosition) {\r
+ if ((timePosition <= 50) && (timePosition >= 44)) {\r
+ return 45;\r
+ }\r
+ return timePosition;\r
+ }\r
+\r
+ /**\r
+ * setSpeedSpin - Set speed for the spin case motor 1.\r
+ * \r
+ * @param uptime\r
+ * pulse width (time position)\r
+ */\r
+ public void setSpeedSpinLeft(int timePosition) {\r
+ /* Speed comes in as a number between 0 - 100 */\r
+ /* It represents values between 1 to 2 ms */\r
+ /* 100-input to get reverse polarity for this motor */\r
+ /* since it's mounted in reverse direction to the other motor */\r
+ if (DEBUG) {\r
+ System.out.println("setSpeedSpinLeft: input-> " + Integer.toString(timePosition));\r
+ }\r
+ int timePos = normalizeTime(timePosition);\r
+\r
+ int motorUpTime = (int) (timePos * agilityFactor * speedFactor);\r
+ // System.out.println("Left Motor UpTime1: " +\r
+ // Integer.toString(motorUpTime));\r
+ // Since the right motor is hanging in reverse position\r
+ // the direction should be opposit\r
+ // Bug in wait. Can't take 0 nanoseconds\r
+ if (motorUpTime == 0) {\r
+ motorUpTime = 1;\r
+ // System.out.println("returning....");\r
+ // return; // ndr\r
+ } else if (motorUpTime == 1000000) {\r
+ motorUpTime--;\r
+ }\r
+\r
+ if (DEBUG) {\r
+ System.out.println("setSpeedSpinLeft: output-> = " + Integer.toString(motorUpTime));\r
+ }\r
+// synchronized (this) {\r
+ /* Factor in the speed and agility factors */\r
+ motorLeftUpTime = motorUpTime;\r
+// }\r
+ }\r
+\r
+ /**\r
+ * setSpeedSpinRight - Set speed for the spin case right motor.\r
+ * \r
+ * @param uptime\r
+ * pulse width (time position)\r
+ */\r
+ public void setSpeedSpinRight(int timePosition) {\r
+ /* Speed comes in as a number between 0 - 100 */\r
+ /* It represents values between 1 to 2 ms */\r
+ /* An input of 50 should result in 0 speed. */\r
+ /* 100 should result in full speed forward */\r
+ /* while 0 should result in full speed backwords */\r
+ if (DEBUG) {\r
+ System.out.println("setSpeedSpinRight: input-> " + Integer.toString(timePosition));\r
+ }\r
+ int timePos = normalizeTime(timePosition);\r
+\r
+ int motorUpTime = (int) ((timePos) * agilityFactor * speedFactor);\r
+ // Bug in wait. Cant take 0 nanoseconds\r
+ if (motorUpTime == 0) {\r
+ motorUpTime = 1;\r
+ // System.out.println("returning....");\r
+ // return; // ndr\r
+ } else if (motorUpTime == 1000000) {\r
+ motorUpTime--;\r
+ }\r
+\r
+ if (DEBUG) {\r
+ System.out.println("setSpeedSpinRight: output-> = " + Integer.toString(motorUpTime));\r
+ }\r
+// synchronized (this) {\r
+ /* Factor in the speed and agility factors */\r
+ motorRightUpTime = motorUpTime;\r
+// }\r
+ }\r
+\r
+ /**\r
+ * setSpeedTurnM1 - set speed considering agility factor for motor 1\r
+ * \r
+ * @param uptime\r
+ * pulse width (time position)\r
+ */\r
+ public void setSpeedTurnLeft(int timePosition) {\r
+ /* Speed comes in as a number between 0 - 100 */\r
+ /* It represents values between 1 to 2 ms */\r
+ /* 100-input to get reverse polarity for this motor */\r
+ /* since it's mounted in reverse direction to the other motor */\r
+ if (DEBUG) {\r
+ System.out.println("setSpeedTurnLeft: input-> " + Integer.toString(timePosition));\r
+ }\r
+ int timePosLocal = normalizeTime(timePosition);\r
+ int motorUpTime =\r
+ (timePosLocal * 100 + ((100 - timePosLocal) * (100 - agilityFactor))) * speedFactor;\r
+ if (motorUpTime == 0) {\r
+ motorUpTime = 1;\r
+ // System.out.println("returning....");\r
+ // return; // ndr\r
+ } else if (motorUpTime == 1000000) {\r
+ motorUpTime--;\r
+ }\r
+ if (DEBUG) {\r
+ System.out.println("setSpeedTurnLeft: output-> = " + Integer.toString(motorUpTime));\r
+ }\r
+// synchronized (this) {\r
+ /* Factor in the speed and agility factors */\r
+ motorLeftUpTime = motorUpTime;\r
+// }\r
+ }\r
+\r
+ /**\r
+ * setSpeedTurnM1 - set speed considering agility factor for motor 2\r
+ * \r
+ * @param uptime\r
+ * pulse width (time position)\r
+ */\r
+ public void setSpeedTurnRight(int timePosition) {\r
+ /* Speed comes in as a number between 0 - 100 */\r
+ /* It represents values between 1 to 2 ms */\r
+ if (DEBUG) {\r
+ System.out.println("setSpeedTurnRight: input-> " + Integer.toString(timePosition));\r
+ }\r
+ int timePos = normalizeTime(timePosition);\r
+ int motorUpTime = ((timePos * 100) + ((100 - timePos) * (100 - agilityFactor))) * speedFactor;\r
+ if (motorUpTime == 0) {\r
+ motorUpTime = 1;\r
+ // System.out.println("returning....");\r
+ // return; // ndr\r
+ } else if (motorUpTime == 1000000) {\r
+ motorUpTime--;\r
+ }\r
+\r
+ if (DEBUG) {\r
+ System.out.println("setSpeedTurnRight: output-> " + Integer.toString(motorUpTime));\r
+ }\r
+// synchronized (this) {\r
+ /* Factor in the speed and agility factors */\r
+ motorRightUpTime = motorUpTime;\r
+// }\r
+ }\r
+\r
+ /**\r
+ * setSpeedLeft - speed control for motor 1.\r
+ * \r
+ * @param uptime\r
+ * pulse width (time position)\r
+ */\r
+ public void setSpeedLeft(int timePosition) {\r
+ /* Speed comes in as a number between 0 - 100 */\r
+ /* It represents values between 1 to 2 ms */\r
+ /* 100-input to get reverse polarity for this motor */\r
+ /* since it's mounted in reverse direction to the other motor */\r
+ if (DEBUG) {\r
+ System.out.println("setSpeedLeft: input-> " + Integer.toString(timePosition));\r
+ }\r
+ int timePos = normalizeTime(timePosition);\r
+ int motorUpTime = (int) (timePos * 100) * speedFactor;\r
+ /*\r
+ * System.out.println("motorUpTime = " + Integer.toString(motorUpTime) +\r
+ * " timePos = " + Integer.toString((int)timePos) + " timePosition = " +\r
+ * Integer.toString((int)timePosition) + " speedFactor = " +\r
+ * Integer.toString(speedFactor));\r
+ */\r
+ if (motorUpTime == 0) {\r
+ motorUpTime = 1;\r
+ // System.out.println("returning....");\r
+ // return; // ndr\r
+ } else if (motorUpTime == 1000000) {\r
+ motorUpTime--;\r
+ }\r
+ if (DEBUG) {\r
+ System.out.println("setSpeedLeft: output-> " + Integer.toString(motorUpTime));\r
+ }\r
+// synchronized (this) {\r
+ /* Factor in speedFactor */\r
+ motorLeftUpTime = motorUpTime;\r
+// }\r
+ }\r
+\r
+ /**\r
+ * setSpeedRight - speed control for motor 1.\r
+ * \r
+ * @param uptime\r
+ * pulse width (time position)\r
+ */\r
+ public void setSpeedRight(int timePosition) {\r
+ if (DEBUG) {\r
+ System.out.println("setSpeedRight: input-> " + Integer.toString(timePosition));\r
+ }\r
+ /* Speed comes in as a number between 0 - 100 */\r
+ /* It represents values between 1 to 2 ms */\r
+ int timePos = normalizeTime(timePosition);\r
+ int motorUpTime = (int) (timePos * 100) * speedFactor;\r
+ if (motorUpTime == 0) {\r
+ motorUpTime = 1;\r
+ // System.out.println("returning....");\r
+ // return; // ndr\r
+ } else if (motorUpTime == 1000000) {\r
+ motorUpTime--;\r
+ }\r
+ if (DEBUG) {\r
+ System.out.println("setSpeedRight: output-> " + Integer.toString(motorUpTime));\r
+ }\r
+// synchronized (this) {\r
+ /* Factor in speedFactor */\r
+ motorRightUpTime = motorUpTime;\r
+// }\r
+ }\r
+\r
+ public void setSpeedAgilityFactors(int speed, int agility) {\r
+// synchronized (this) {\r
+ speedFactor = speed;\r
+ agilityFactor = agility;\r
+// }\r
+ }\r
+\r
+ public void setUrgentReverse() {\r
+// synchronized (this) {\r
+ motorLeftUpTime = 1;\r
+ motorRightUpTime = 1;\r
+// }\r
+ }\r
+\r
+ public void setUrgentStraight() {\r
+// synchronized (this) {\r
+ motorLeftUpTime = 99;\r
+ motorRightUpTime = 99;\r
+// }\r
+ }\r
+\r
+ public void justSync() {\r
+// synchronized (this) {\r
+ motorLeftUpTime = motorLeftUpTime;\r
+ motorRightUpTime = motorRightUpTime;\r
+// }\r
+ }\r
+\r
+ /**\r
+ * Control debug messageing. true - Activate debug messages false - deactivate\r
+ * debug messages\r
+ */\r
+ public void setDebug(boolean debug) {\r
+ DEBUG = debug;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*
+ * PWMControl.java
+ *
+ * Copyright (c) 1993-2002 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * This software is the confidential and proprietary information of Sun
+ * Microsystems, Inc. ("Confidential Information"). You shall not
+ * disclose such Confidential Information and shall use it only in
+ * accordance with the terms of the license agreement you entered into
+ * with Sun.
+ *
+ * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
+ * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+ * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
+ */
+
+/**
+ * Manage the software link between two IO port lines.
+ * <p>
+ * Copyright: Copyright (c) 2002
+ * </p>
+ *
+ * @author Michael Gesundheit
+ * @version 1.0
+ */
+
+public class RCBridge {
+
+ public void setManualMode() {
+ // rcLleft.activate();
+ // rcLright.activate();
+ }
+
+ public void setAutomatedMode() {
+ // rcLleft.deActivate();
+ // rcLright.deActivate();
+ }
+}
\ No newline at end of file
--- /dev/null
+/*\r
+ * RobotMain.java\r
+ *\r
+ * Copyright (c) 1993-2002 Sun Microsystems, Inc. All Rights Reserved.\r
+ *\r
+ * This software is the confidential and proprietary information of Sun\r
+ * Microsystems, Inc. ("Confidential Information"). You shall not\r
+ * disclose such Confidential Information and shall use it only in\r
+ * accordance with the terms of the license agreement you entered into\r
+ * with Sun.\r
+ *\r
+ * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF\r
+ * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED\r
+ * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\r
+ * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR\r
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR\r
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.\r
+ */\r
+\r
+/**\r
+ * Robot's Main class - instantiates all required classes and resources.\r
+ * \r
+ * @author Michael Gesundheit\r
+ * @version 1.0\r
+ */\r
+\r
+\r
+public class RobotMain {\r
+\r
+ \r
+ private static boolean DEBUG1 = true;\r
+ \r
+ private static boolean DEBUG = true;\r
+\r
+ private static final int OFF_MODE = 1;\r
+ private static final int ON_MODE = 2;\r
+ private static final int MANUAL_MODE = 1;\r
+ private static final int AUTONOMUS_MODE = 2;\r
+ private static final int ON_OFF = 128;// 0x80\r
+ private static final int MANUAL_AUTONOMUS = 32; // 0x20\r
+ public static final int LINE_SENSORS = 64; // 0x40\r
+ private static final int SONAR_SENSORS = 96; // 0x60\r
+ public static final int ALL_COMMANDS = 0xe0;\r
+\r
+ public static final byte LF_FRONT = 0x1;\r
+ public static final byte RT_FRONT = 0x2;\r
+ public static final byte RT_SIDE = 0x4;\r
+ public static final byte BK_SIDE = 0x8;\r
+ public static final byte LF_SIDE = 0x10;\r
+ public static final byte ALL_SONARS = 0x1f;\r
+ public static final byte LF_RT_FRONT = 0x3; // LF_FRONT | RT_FRONT;\r
+ public static final byte LS_LEFT = 0x1;\r
+ public static final byte LS_RIGHT = 0x2;\r
+ public static final byte LS_REAR = 0x4;\r
+ public static final byte LS_LEFT_RIGHT = 0x3;\r
+ public static final byte LS_LEFT_REAR = 0x5;\r
+ public static final byte LS_RIGHT_REAR = 0x6;\r
+ public static final byte LS_ALL = 0x7;\r
+ private static final int ALL_DATA = 0x1f;\r
+\r
+ \r
+ private static PWMManager pwmm;\r
+ \r
+ private static StrategyMgr strategyMgr;\r
+\r
+ \r
+ private static int onOffMode = ON_MODE;\r
+ \r
+ private static int manualAutonomusMode = AUTONOMUS_MODE;\r
+ \r
+ private static byte lineSensorsMask;\r
+ \r
+ private static byte sonarSensors;\r
+ \r
+ private static byte currentCommand;\r
+ \r
+ private static byte privSonars;\r
+ \r
+ private static byte privLineSensors;\r
+ \r
+ private static byte currentSonars;\r
+ \r
+ public static String pwmSelection;\r
+\r
+ /**\r
+ * Constructor for the class for the robot main thread.\r
+ */\r
+ RobotMain() {\r
+ }\r
+\r
+ /**\r
+ * Processes sonar sensor input. This method is called each time new sonar\r
+ * sensor data arrives, and each time that a mode switch occurs between ON/OFF\r
+ * and Manual Override.\r
+ */\r
+ static void processSonars() {\r
+ strategyMgr.processSonars(sonarSensors);\r
+ }\r
+\r
+ /**\r
+ * Processes line sensor input. This method is called each time new line\r
+ * sensor data arrives, and each time that a mode switch occurs between ON/OFF\r
+ * and Manual Override.\r
+ */\r
+ static void processLineSensors() {\r
+ strategyMgr.processLineSensors(lineSensorsMask);\r
+ resume();\r
+ }\r
+\r
+ /**\r
+ * Resumes motors as per the last sonar command.\r
+ */\r
+ public static void resume() {\r
+ processSonars();\r
+ }\r
+\r
+ /**\r
+ * Extracts sonar sensor data from the adjunct sensor controller and from line\r
+ * sensor data from the JStamp line sensor pins.\r
+ */\r
+ \r
+ private static void processIOCommand() {\r
+\r
+ // int data = 0;\r
+ // int opCode = 0;\r
+ // synchronized (obj1) {\r
+ int data = (int) (currentCommand & ALL_DATA);\r
+ int opCode = (int) (currentCommand & 0xe0); // ALL_COMMANDS);\r
+ // }\r
+\r
+ if (DEBUG) {\r
+ System.out.println("processIOCommand: Default: opCode = " + Integer.toString((int) opCode)\r
+ + " data = " + Integer.toString((int) data));\r
+ }\r
+ switch ((int) opCode) {\r
+ case ON_OFF:\r
+ if (DEBUG) {\r
+ System.out.println("processIO: ON_OFF....");\r
+ }\r
+ if ((data & 0x1) == 0x1) {\r
+ System.out.println("processIO: ON MODE........");\r
+ onOffMode = ON_MODE;\r
+ processLineSensors();\r
+ processSonars();\r
+ } else {\r
+ System.out.println("processIO: OFF MODE.......");\r
+ onOffMode = OFF_MODE;\r
+ strategyMgr.stop();\r
+ }\r
+ break;\r
+ case MANUAL_AUTONOMUS:\r
+ if (DEBUG) {\r
+ System.out.println("processIO: Setting manual_autonomus mode");\r
+ }\r
+ if ((data & 0x1) == 0x1) {\r
+ manualAutonomusMode = MANUAL_MODE;\r
+ pwmm.setManualMode();\r
+ } else {\r
+ manualAutonomusMode = AUTONOMUS_MODE;\r
+ pwmm.setAutomatedMode();\r
+ processLineSensors();\r
+ processSonars();\r
+ }\r
+ break;\r
+ case LINE_SENSORS:\r
+ if (DEBUG) {\r
+ // System.out.println("processIO: Line Sensors.................."\r
+ // + Integer.toBinaryString((int) (data & LS_ALL)));\r
+ }\r
+ lineSensorsMask = (byte) (data & LS_ALL);\r
+\r
+ /*\r
+ * Line sensors with '0' data means the robot moved off the edge line, and\r
+ * there is nothing to do.\r
+ */\r
+ if (((data & LS_ALL) == 0) || ((data & LS_ALL) == privLineSensors)) {\r
+ privLineSensors = (byte) (data & LS_ALL);\r
+ return;\r
+ }\r
+ if ((onOffMode == ON_MODE) && (manualAutonomusMode == AUTONOMUS_MODE)) {\r
+ if (DEBUG)\r
+ System.out.println("processIO: Line Sensors..Process...!!!");\r
+ processLineSensors();\r
+ }\r
+ break;\r
+ case SONAR_SENSORS:\r
+ if (DEBUG) {\r
+ // System.out.println("processIO: SONAR_SENORS: bits = ......"\r
+ // + Integer.toBinaryString((int) (currentCommand & ALL_SONARS)));\r
+ }\r
+ currentSonars = (byte) (data & ALL_SONARS);\r
+ /*\r
+ * No need to synchronized on this variable assignment since all referring\r
+ * code is on the same logical thread\r
+ */\r
+ sonarSensors = (byte) currentSonars;\r
+ if ((onOffMode == ON_MODE) && (manualAutonomusMode == AUTONOMUS_MODE)) {\r
+ processSonars();\r
+ }\r
+ break;\r
+ default:\r
+ strategyMgr.stop();\r
+ System.out.println("processIOCommand: Default: opCode = " + Integer.toString((int) opCode)\r
+ + " data = " + Integer.toString((int) data));\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Sets the simulation mode on in the IOManager.\r
+ */\r
+ // static public void setSimulation() {\r
+ // sm.setSimulation();\r
+ // }\r
+\r
+ /**\r
+ * Resets the simulation mode in the IOManager.\r
+ */\r
+ // static public void resetSimulation() {\r
+ // sm.resetSimulation();\r
+ // }\r
+\r
+ /**\r
+ * Saves the current IOManager command byte locally.\r
+ */\r
+ static public void setIOManagerCommand(byte[] cmd) {\r
+ // synchronized (obj1) {\r
+ currentCommand = cmd[0];\r
+ // }\r
+ // synchronized (obj) {\r
+ try {\r
+ // obj.notify();\r
+ } catch (IllegalMonitorStateException ie) {\r
+ System.out.println("IllegalMonitorStateException caught trying to notify");\r
+ }\r
+ // }\r
+ }\r
+\r
+ /**\r
+ * Sets debug messaging state: true - Activate debug messages false -\r
+ * deactivate debug messages\r
+ */\r
+ static public void setDebug(boolean debug) {\r
+ DEBUG = debug;\r
+ }\r
+\r
+ /**\r
+ * Runs the robot's main thread.\r
+ */\r
+ \r
+ public static void main( String args[]) {\r
+\r
+ TestSensorInput.init();\r
+ boolean active = true;\r
+ /**\r
+ * RealTime management of the robot behaviour based on sensors and commands\r
+ * input.\r
+ */\r
+\r
+ /**\r
+ * Set the low level PWM interface type, e.g. "rtsj" or "native" (ajile\r
+ * library-based).\r
+ */\r
+ pwmSelection = "rtsj";\r
+\r
+ System.out.println("PWM Selction is: " + pwmSelection);\r
+\r
+ pwmm = new PWMManager(pwmSelection);\r
+\r
+ // Pass in the PWMManager for callbacks.\r
+ // sm = new IOManager(pwmm);\r
+ // ram = new RemoteApplicationManager(pwmm);\r
+ MotorControl mc = new MotorControl(100, 100);\r
+ strategyMgr = new StrategyMgr(mc);\r
+\r
+ /*\r
+ * Sets initial values for the speed and agility parameters. Speed and\r
+ * agility are arbitrary scale factors for the overall speed and speed of\r
+ * turns, respectively. These work with PWM via the native ajile libraries,\r
+ * but do not work well with the RTSJ implementation due to limits on the\r
+ * granularity of timing for the PWM pulse (quantization).\r
+ */\r
+ pwmm.setSpeedAgilityFactors(100, 100);\r
+\r
+ /*\r
+ * Robot's initial state is "ON" by default. Set this parameter to "OFF" if\r
+ * the robot is to be started over the TCP/IP link.\r
+ */\r
+ // issueCommand("OFF");\r
+\r
+ SSJAVA: while (active) {\r
+\r
+ // if (DEBUG) {\r
+ // System.out.println("Main: Waiting for remote commands");\r
+ // }\r
+ // try {\r
+ // obj.wait();\r
+ // } catch (IllegalMonitorStateException ie) {\r
+ // System.out.println("IllegalMonitorStateException caught in main loop");\r
+ // }\r
+ currentCommand = TestSensorInput.getCommand();\r
+ if (currentCommand == -1) {\r
+ break;\r
+ }\r
+ System.out.println("currentCommand=" + currentCommand);\r
+ processIOCommand();\r
+ }\r
+ System.exit(0);\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * StragegyMgr.java\r
+ *\r
+ * Copyright (c) 1993-2002 Sun Microsystems, Inc. All Rights Reserved.\r
+ *\r
+ * This software is the confidential and proprietary information of Sun\r
+ * Microsystems, Inc. ("Confidential Information"). You shall not\r
+ * disclose such Confidential Information and shall use it only in\r
+ * accordance with the terms of the license agreement you entered into\r
+ * with Sun.\r
+ *\r
+ * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF\r
+ * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED\r
+ * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\r
+ * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR\r
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR\r
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.\r
+ */\r
+\r
+/**\r
+ * StrategyMgr - an isolation class ment for programmers to modify and create\r
+ * thier own code for robot strategy.\r
+ * \r
+ * @author Michael Gesundheit\r
+ * @version 1.0\r
+ */\r
+\r
+\r
+public class StrategyMgr {\r
+\r
+ \r
+ private MotorControl mc;\r
+ private static final int zeroSpeed = 45;\r
+ \r
+ private Random rand;\r
+ \r
+ private boolean DEBUGL = true;\r
+ // private boolean DEBUGL = false;\r
+\r
+ // private boolean DEBUG = true;\r
+ \r
+ private boolean DEBUG = true;\r
+\r
+ /**\r
+ * Constructor - Invoke communication to remote application thread\r
+ */\r
+ public StrategyMgr(@DELEGATE MotorControl motorControl) {\r
+ mc = motorControl;\r
+ rand = new Random();\r
+ }\r
+\r
+ void processSonars( byte sonarSensors) {\r
+\r
+ // 5 sensors. 1,2 are fromnt left and right.\r
+ // Sensor 3 is right side, 4 back and 5 is left side.\r
+ if ((sonarSensors & 0x1f) == 0) {\r
+ // No sensor data may mean dead area between sensors.\r
+ // Continue with the last gesture until any sensor\r
+ // provide data.\r
+ if (DEBUG) {\r
+ System.out.println("sonar: NO SONARS!!!!!!!!");\r
+ }\r
+ } else if ((sonarSensors & (RobotMain.LF_RT_FRONT)) == (RobotMain.LF_RT_FRONT)) {\r
+ if (DEBUG) {\r
+ System.out.println("sonar: straight");\r
+ }\r
+ straight();\r
+ } else if ((sonarSensors & RobotMain.LF_FRONT) == RobotMain.LF_FRONT) {\r
+ if (DEBUG) {\r
+ System.out.println("sonar: bearLeft");\r
+ }\r
+ bearLeft();\r
+ } else if ((sonarSensors & RobotMain.RT_FRONT) == RobotMain.RT_FRONT) {\r
+ if (DEBUG) {\r
+ System.out.println("sonar: bearRight");\r
+ }\r
+ bearRight();\r
+ } else if ((sonarSensors & RobotMain.RT_SIDE) == RobotMain.RT_SIDE) {\r
+ if (DEBUG) {\r
+ System.out.println("sonar: right");\r
+ }\r
+ spinRight();\r
+ } else if ((sonarSensors & RobotMain.LF_SIDE) == RobotMain.LF_SIDE) {\r
+ if (DEBUG) {\r
+ System.out.println("sonar: left");\r
+ }\r
+ spinLeft();\r
+ } else if ((sonarSensors & RobotMain.BK_SIDE) == RobotMain.BK_SIDE) {\r
+ if (DEBUG) {\r
+ System.out.println("sonar: spin180");\r
+ }\r
+ spin180();\r
+ }\r
+ }\r
+\r
+ void processLineSensors( byte lineSensorsMask) {\r
+\r
+ int count = 0;\r
+\r
+ while ((lineSensorsMask & RobotMain.LS_ALL) != 0) {\r
+\r
+ if (count > 100) {\r
+ // if the robot fail to get out of weird condition wihtin 100 steps,\r
+ // terminate while loop for stabilizing behavior.\r
+ stop();\r
+ break;\r
+ }\r
+ count++;\r
+\r
+ if ((lineSensorsMask & RobotMain.LS_ALL) == RobotMain.LS_ALL) {\r
+ if (DEBUGL)\r
+ System.out.println("Line Sensors - ALL");\r
+ stop();\r
+ } else if ((lineSensorsMask & RobotMain.LS_LEFT_RIGHT) == RobotMain.LS_LEFT_RIGHT) {\r
+ if (DEBUGL)\r
+ System.out.println("Line Sensors - Left & Right");\r
+ back();\r
+ try {\r
+ // Thread.sleep(1000);\r
+ } catch (InterruptedException ie) {\r
+ }\r
+ spin180();\r
+ try {\r
+ // Thread.sleep(1000);\r
+ } catch (InterruptedException ie) {\r
+ }\r
+ } else if ((lineSensorsMask & RobotMain.LS_LEFT_REAR) == RobotMain.LS_LEFT_REAR) {\r
+ if (DEBUGL)\r
+ System.out.println("Line Sensors - Left & Rear");\r
+ bearRight();\r
+ try {\r
+ // Thread.sleep(1000);\r
+ } catch (InterruptedException ie) {\r
+ }\r
+ } else if ((lineSensorsMask & RobotMain.LS_RIGHT_REAR) == RobotMain.LS_RIGHT_REAR) {\r
+ if (DEBUGL)\r
+ System.out.println("Line Sensors - Right & Rear");\r
+ bearLeft();\r
+ try {\r
+ // Thread.sleep(1000);\r
+ } catch (InterruptedException ie) {\r
+ }\r
+ } else if ((lineSensorsMask & RobotMain.LS_LEFT) == RobotMain.LS_LEFT) {\r
+ if (DEBUGL)\r
+ System.out.println("Line Sensors - Left");\r
+ backBearRight();\r
+\r
+ try {\r
+ // Thread.sleep(1000);\r
+ } catch (InterruptedException ie) {\r
+ }\r
+ } else if ((lineSensorsMask & RobotMain.LS_RIGHT) == RobotMain.LS_RIGHT) {\r
+ if (DEBUGL)\r
+ System.out.println("Line Sensors - Right");\r
+ backBearLeft();\r
+ try {\r
+ // Thread.sleep(1000);\r
+ } catch (InterruptedException ie) {\r
+ }\r
+ } else if ((lineSensorsMask & RobotMain.LS_REAR) == RobotMain.LS_REAR) {\r
+ if (DEBUGL)\r
+ System.out.println("Line Sensors - Rear");\r
+ straight();\r
+ try {\r
+ // Thread.sleep(1000);\r
+ } catch (InterruptedException ie) {\r
+ }\r
+ }\r
+ lineSensorsMask = TestSensorInput.getCommand();\r
+ }// while loop\r
+ }\r
+\r
+ public void stop() {\r
+ if (DEBUG)\r
+ System.out.println("StrageyMgr: stop....");\r
+ mc.setSpeedLeft(zeroSpeed);\r
+ mc.setSpeedRight(zeroSpeed);\r
+ }\r
+\r
+ public void search() {\r
+ if (DEBUG)\r
+ System.out.println("StrategyMgr: search....");\r
+ mc.setSpeedLeft(70);\r
+ mc.setSpeedRight(50);\r
+ }\r
+\r
+ public void straight() {\r
+ if (DEBUG)\r
+ System.out.println("StrategyMgr: strait....");\r
+ mc.setSpeedLeft(100);\r
+ mc.setSpeedRight(100);\r
+ }\r
+\r
+ public void spinRight() {\r
+ if (DEBUG)\r
+ System.out.println("StrategyMgr: spinRight....");\r
+ mc.setSpeedSpinLeft(100);\r
+ mc.setSpeedSpinRight(0);\r
+ }\r
+\r
+ public void spinLeft() {\r
+ if (DEBUG)\r
+ System.out.println("StrategyMgr: spinLeft....");\r
+ mc.setSpeedSpinLeft(0);\r
+ mc.setSpeedSpinRight(100);\r
+ }\r
+\r
+ public void spin180() {\r
+ int mod = (rand.nextInt() % 2);\r
+\r
+ if (DEBUG)\r
+ System.out.println("StrategyMgr: spin180....");\r
+ if (mod == 1) {\r
+ mc.setSpeedSpinLeft(0);\r
+ mc.setSpeedSpinRight(100);\r
+ } else {\r
+ mc.setSpeedSpinLeft(100);\r
+ mc.setSpeedSpinRight(0);\r
+ }\r
+ }\r
+\r
+ public void right() {\r
+ if (DEBUG)\r
+ System.out.println("StrategyMgr: right....");\r
+ mc.setSpeedTurnLeft(100);\r
+ mc.setSpeedRight(zeroSpeed);\r
+ }\r
+\r
+ public void left() {\r
+ if (DEBUG)\r
+ System.out.println("StrategyMgr: left....");\r
+ mc.setSpeedLeft(zeroSpeed);\r
+ mc.setSpeedTurnRight(100);\r
+ }\r
+\r
+ public void bearRight() {\r
+ if (DEBUG)\r
+ System.out.println("StrategyMgr: bearRight....");\r
+ mc.setSpeedTurnLeft(100);\r
+ mc.setSpeedTurnRight(60);\r
+ }\r
+\r
+ public void bearLeft() {\r
+ if (DEBUG)\r
+ System.out.println("StrategyMgr: bearLeft....");\r
+ mc.setSpeedTurnLeft(60);\r
+ mc.setSpeedTurnRight(100);\r
+ }\r
+\r
+ public void back() {\r
+ if (DEBUG)\r
+ System.out.println("StrategyMgr: back....");\r
+ mc.setSpeedLeft(0);\r
+ mc.setSpeedRight(0);\r
+ }\r
+\r
+ public void backBearLeft() {\r
+ if (DEBUG)\r
+ System.out.println("StrategyMgr: backBearLeft....");\r
+ mc.setSpeedLeft(30);\r
+ mc.setSpeedRight(0);\r
+ }\r
+\r
+ public void backBearRight() {\r
+ if (DEBUG)\r
+ System.out.println("StrategyMgr: backBearRight....");\r
+ mc.setSpeedLeft(0);\r
+ mc.setSpeedRight(30);\r
+ }\r
+}\r
--- /dev/null
+public class TestSensorInput {
+
+ private static FileInputStream inputFile;
+ private static int idx=0;
+
+ @TRUST
+ public static void init() {
+ inputFile = new FileInputStream("input.dat");
+ }
+
+ @TRUST
+ public static byte getCommand() {
+ String in = inputFile.readLine();
+ if (in == null) {
+ return (byte) -1;
+ }
+ // DEBUG_OUTPUT();
+ return (byte) Integer.parseInt(in);
+ }
+
+ public static DEBUG_OUTPUT(){
+ idx++;
+ System.out.println(idx);
+ }
+
+}
--- /dev/null
+BUILDSCRIPT=../../../buildscript
+
+PROGRAM=RobotMain
+SOURCE_FILES=RobotMain.java
+
+ifndef INV_ERROR_PROB
+INV_ERROR_PROB=1000
+endif
+
+ifndef RANDOMSEED
+RANDOMSEED=12345
+endif
+
+SSJAVA= -ssjava -ssjavainfer -ssjavadebug
+BSFLAGS= -32bit -mainclass $(PROGRAM) -heapsize-mb 1350 -nooptimize -debug -garbagestats #-printlinenum #-joptimize
+NORMAL= -ssjava-inject-error 0 0
+INJECT_ERROR= -ssjava-inject-error $(INV_ERROR_PROB) $(RANDOMSEED)
+
+
+default: $(PROGRAM)s.bin
+
+normal: $(PROGRAM)n.bin
+
+error: $(PROGRAM)e.bin
+
+
+$(PROGRAM)s.bin: $(SOURCE_FILES) makefile
+ $(BUILDSCRIPT) $(SSJAVA) $(BSFLAGS) -o $(PROGRAM)s -builddir ssj $(SOURCE_FILES)
+
+$(PROGRAM)n.bin: $(SOURCE_FILES) makefile
+ $(BUILDSCRIPT) $(NORMAL) $(BSFLAGS) -o $(PROGRAM)n -builddir norm $(SOURCE_FILES)
+
+$(PROGRAM)e.bin: $(SOURCE_FILES) makefile
+ $(BUILDSCRIPT) $(SSJAVA) $(INJECT_ERROR) $(BSFLAGS) -o $(PROGRAM)e -builddir injerr $(SOURCE_FILES)
+
+cleanerror:
+ rm -f $(PROGRAM)e.bin
+ rm -rf injerr
+
+clean:
+ rm -f $(PROGRAM)s.bin $(PROGRAM)n.bin $(PROGRAM)e.bin
+ rm -fr ssj norm injerr
+ rm -f nve-diff.tmp nve-diff-ranges.tmp
+ rm -f *~
+ rm -f *.dot
+ rm -f *.png
+ rm -f *.pdf
+ rm -f aliases.txt
+ rm -f results*txt
+ rm -f output.txt
+ rm -f *log
+