diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml index 6965a52..6f2932f 100644 --- a/dependency-reduced-pom.xml +++ b/dependency-reduced-pom.xml @@ -4,7 +4,7 @@ org.baxter.disco ocr Disco OCR Accuracy Over Life Testing - 4.3.3 + 4.3.4 Testing Discos for long-term accuracy, using automated optical character recognition. Baxter International diff --git a/pom.xml b/pom.xml index 4059755..d081594 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 org.baxter.disco ocr - 4.3.3 + 4.3.4 jar Disco OCR Accuracy Over Life Testing Testing Discos for long-term accuracy, using automated optical character recognition. diff --git a/runScript.sh b/runScript.sh index 6729115..e69739b 100644 --- a/runScript.sh +++ b/runScript.sh @@ -1,2 +1,2 @@ #! /usr/bin/env sh -sudo java -jar discoTesting-4.3.3.jar 2>/dev/null +sudo java -jar discoTesting-4.3.4.jar 2>/dev/null diff --git a/src/main/java/org/baxter/disco/ocr/Cli.java b/src/main/java/org/baxter/disco/ocr/Cli.java index 755bb01..d633d68 100644 --- a/src/main/java/org/baxter/disco/ocr/Cli.java +++ b/src/main/java/org/baxter/disco/ocr/Cli.java @@ -25,7 +25,7 @@ public class Cli /** * Complete build version number */ - private static final String version = "4.3.3"; + private static final String version = "4.3.4"; /** * Currently saved iteration count. @@ -108,7 +108,7 @@ public class Cli { //Show the main menu, wait for user input printMainMenu(); - userInput = inputFiltering(inputScanner.nextLine()); + userInput = (int)inputFiltering(inputScanner.nextLine()); //Perform action based on user input switch (userInput) @@ -430,7 +430,7 @@ public class Cli println("Testing movement..."); fixture.testMotions(); printMovementMenu(); - userInput = inputFiltering(inputScanner.nextLine()); + userInput = (int)inputFiltering(inputScanner.nextLine()); switch (userInput) { /* @@ -442,7 +442,7 @@ public class Cli */ case 1: prompt("Input the desired duty cycle value: "); - int newDutyCycle = inputFiltering(inputScanner.nextLine()); + int newDutyCycle = (int)inputFiltering(inputScanner.nextLine()); if (newDutyCycle != -1) { fixture.setDutyCycle(newDutyCycle); @@ -450,7 +450,7 @@ public class Cli } case 2: prompt("Input the desired frequency value: "); - int newFrequency = inputFiltering(inputScanner.nextLine()); + int newFrequency = (int)inputFiltering(inputScanner.nextLine()); if (newFrequency != -1) { fixture.setFrequency(newFrequency); @@ -458,7 +458,7 @@ public class Cli } case 3: prompt("Input the desired time-out (in seconds): "); - int newTimeout = inputFiltering(inputScanner.nextLine()); + double newTimeout = inputFiltering(inputScanner.nextLine()); if (newTimeout != -1) { fixture.setTimeout(newTimeout); @@ -496,7 +496,7 @@ public class Cli do { prompt("Enter a camera number to configure: "); - userInput = inputFiltering(inputScanner.nextLine()); + userInput = (int)inputFiltering(inputScanner.nextLine()); userInput--; } while (cameraList.size() < userInput && userInput < 0); @@ -527,7 +527,7 @@ public class Cli //list configurable settings printCameraConfigMenu(cameraName,tesseractValue); - userInput = inputFiltering(inputScanner.nextLine(),Menus.CAMERA); + userInput = (int)inputFiltering(inputScanner.nextLine(),Menus.CAMERA); switch (userInput) { case 1: @@ -573,7 +573,7 @@ public class Cli //Prompt is in int, as the ultimate values are cast //to int anyways, a decimal would be confusing (int)ConfigFacade.getValue(cameraName,modifiedProperty) + "): "); - userInput = inputFiltering(inputScanner.nextLine()); + userInput = (int)inputFiltering(inputScanner.nextLine()); ConfigFacade.setValue(cameraName,modifiedProperty,userInput); } @@ -607,7 +607,7 @@ public class Cli do { prompt("Enter the camera you wish to set the serial of: "); - userInput = inputFiltering(inputScanner.nextLine()); + userInput = (int)inputFiltering(inputScanner.nextLine()); //Compensate for off-by-one errors userInput--; } while (cameraList.size() < userInput || userInput < 0); @@ -634,7 +634,7 @@ public class Cli do { prompt("Input the number of test iterations to complete: "); - input = inputFiltering(inputScanner.nextLine()); + input = (int)inputFiltering(inputScanner.nextLine()); } while(input == -1); iterationCount = input; } @@ -659,7 +659,7 @@ public class Cli do { prompt("Enter the camera you wish to toggle: "); - userInput = inputFiltering(inputScanner.nextLine()); + userInput = (int)inputFiltering(inputScanner.nextLine()); userInput--; } while (cameraList.size() < userInput || userInput < 0); @@ -830,7 +830,7 @@ public class Cli * * @param input The unparsed user input, directly from the {@link Scanner} */ - private static int inputFiltering(String input) + private static double inputFiltering(String input) { return inputFiltering(input, Menus.OTHER); } /** @@ -841,18 +841,18 @@ public class Cli * * @return The parsed value from the user. Returns -1 upon any error. */ - private static int inputFiltering(String input, Menus menu) + private static double inputFiltering(String input, Menus menu) { - int output = -1; + double output = -1; input.trim(); try(Scanner sc = new Scanner(input)) { - if(!sc.hasNextInt()) + if(!sc.hasNextDouble()) { invalidInput(); return output; } - output = sc.nextInt(); + output = sc.nextDouble(); if(output < 0) { negativeInput(); diff --git a/src/main/java/org/baxter/disco/ocr/MovementFacade.java b/src/main/java/org/baxter/disco/ocr/MovementFacade.java index 07d8bc8..c959c9e 100644 --- a/src/main/java/org/baxter/disco/ocr/MovementFacade.java +++ b/src/main/java/org/baxter/disco/ocr/MovementFacade.java @@ -23,7 +23,7 @@ import com.pi4j.io.pwm.PwmType; * Currently missing Run switch compatibility. * * @author Blizzard Finnegan - * @version 2.2.0, 06 Feb. 2023 + * @version 2.3.0, 27 Feb. 2023 */ public class MovementFacade { @@ -68,7 +68,7 @@ public class MovementFacade /** * PWM Frequency */ - private static int FREQUENCY = 70000; + private static int FREQUENCY = 75000; /** * PWM Duty Cycle @@ -78,7 +78,7 @@ public class MovementFacade /** * Number of seconds to wait before timing out a fixture movement. */ - private static int TIME_OUT = 3; + private static double TIME_OUT = 2.5; //PWM Addresses //All addresses are in BCM format. @@ -118,6 +118,17 @@ public class MovementFacade */ private static final int LOWER_LIMIT_ADDR = 24; + /** + * How many milliseconds to wait before polling the GPIO + */ + private static final int POLL_WAIT = 20; + + /** + * How many times to poll the GPIO during a movement call. + * The 1000/POLL_WAIT in this definition is converting poll-times to polls-per-second. + */ + private static double POLL_COUNT = TIME_OUT * (1000 / POLL_WAIT); + //Pi GPIO pin objects /** @@ -332,7 +343,7 @@ public class MovementFacade * * @return True if the value was set successfully; otherwise false. */ - public boolean setTimeout(int newTimeout) + public boolean setTimeout(double newTimeout) { boolean output = false; if(newTimeout < 0) @@ -342,6 +353,7 @@ public class MovementFacade else { TIME_OUT = newTimeout; + POLL_COUNT = TIME_OUT * ( 1000 / POLL_WAIT ); output = true; } return output; @@ -352,7 +364,7 @@ public class MovementFacade * * @return The current timeout. */ - public int getTimeout() { return TIME_OUT; } + public double getTimeout() { return TIME_OUT; } /** * Setter for the fixture's PWM frequency. @@ -385,13 +397,15 @@ public class MovementFacade public int getFrequency() { return FREQUENCY; } /** - * Internal function to send the fixture to one limit switch or another. + * Internal function to send the fixture to a given limit switch. + * + * Motor slows down after timeout is halfway through, to protect hardware. * * @param moveUp Whether to send the fixture up or down. (True = up, False = down) * @param timeout How long (in seconds) to wait before timing out. * @return true if movement was successful; otherwise false */ - private boolean gotoLimit(boolean moveUp, int timeout) + private boolean gotoLimit(boolean moveUp, double timeout) { boolean output = false; DigitalInput limitSense; @@ -408,16 +422,22 @@ public class MovementFacade ErrorLogging.logError("DEBUG: Sending fixture down..."); } + double mostlyThere = (POLL_COUNT * 2) / 3; + int slowerSpeed = FREQUENCY / 4; + motorEnable.on(); - for(int i = 0; i < (timeout * 20);i++) + for(int i = 0; i < (POLL_COUNT);i++) { - try{ Thread.sleep(50); } catch(Exception e) {ErrorLogging.logError(e);}; + try{ Thread.sleep(POLL_WAIT); } catch(Exception e) {ErrorLogging.logError(e);}; output = limitSense.isHigh(); if(output) break; + else if(i >= mostlyThere) + { pwm.on(DUTY_CYCLE, slowerSpeed); continue; } } if(output == false) ErrorLogging.logError("FIXTURE MOVEMENT ERROR! - Motor movement timed out!"); motorEnable.off(); + pwm.on(DUTY_CYCLE, FREQUENCY); return output; } @@ -427,7 +447,7 @@ public class MovementFacade * @param timeout How long (in seconds) to wait before timing out. * @return true if movement was successful; otherwise false */ - public boolean goDown(int timeout) { return gotoLimit(false, timeout); } + public boolean goDown(double timeout) { return gotoLimit(false, timeout); } /** * Send the fixture to the upper limit switch. @@ -435,7 +455,7 @@ public class MovementFacade * @param timeout How long (in seconds) to wait before timing out. * @return true if movement was successful; otherwise false */ - public boolean goUp(int timeout) { return gotoLimit(true, timeout); } + public boolean goUp(double timeout) { return gotoLimit(true, timeout); } /** * Send the fixture to the lower limit switch. diff --git a/src/main/java/org/baxter/disco/ocr/TesseractFacade.java b/src/main/java/org/baxter/disco/ocr/TesseractFacade.java index cac5626..991ae45 100644 --- a/src/main/java/org/baxter/disco/ocr/TesseractFacade.java +++ b/src/main/java/org/baxter/disco/ocr/TesseractFacade.java @@ -20,7 +20,7 @@ import org.bytedeco.tesseract.TessBaseAPI; * information for this specific testing aparatus. * * @author Blizzard Finnegan - * @version 2.1.0, 06 Feb. 2023 + * @version 2.2.0, 27 Feb. 2023 */ public class TesseractFacade { @@ -79,8 +79,15 @@ public class TesseractFacade { ErrorLogging.logError("OCR WARNING - OCR output is too high for DUT, attempting to adjust..."); output = output / 10; - if(output >= 200) + if(output >= 300) + { + output = output / 10; + ErrorLogging.logError("OCR output saved, as value appears to be real. Value needs to be verified."); + } + else if(output >= 200) ErrorLogging.logError("OCR WARNING - OCR output is too high for DUT, potential misread."); + else + ErrorLogging.logError("OCR output successfully adjusted. Disregard warning."); } if(output <= -10) ErrorLogging.logError("OCR ERROR!!! - OCR output is too low for DUT, potential misread.");