diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml index bb421ef..546df28 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.5 + 4.3.6 Testing Discos for long-term accuracy, using automated optical character recognition. Baxter International diff --git a/pom.xml b/pom.xml index af94a17..dee8341 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 org.baxter.disco ocr - 4.3.5 + 4.3.6 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 b4ef9f6..9cb3eae 100644 --- a/runScript.sh +++ b/runScript.sh @@ -1,2 +1,2 @@ #! /usr/bin/env sh -sudo java -jar discoTesting-4.3.5.jar 2>/dev/null +sudo java -jar discoTesting-4.3.6.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 a816065..370d151 100644 --- a/src/main/java/org/baxter/disco/ocr/Cli.java +++ b/src/main/java/org/baxter/disco/ocr/Cli.java @@ -18,14 +18,14 @@ import java.util.concurrent.locks.ReentrantLock; * classes). * * @author Blizzard Finnegan - * @version 1.6.1, 10 Feb. 2023 + * @version 1.7.0, 06 Mar. 2023 */ public class Cli { /** * Complete build version number */ - private static final String version = "4.3.5"; + private static final String version = "4.3.6"; /** * Currently saved iteration count. @@ -55,11 +55,6 @@ public class Cli */ private static final int mainMenuOptionCount = 7; - /** - * Number of options currently available in the movement sub-menu. - */ - private static final int movementMenuOptionCount = 5; - /** * Number of options currently available in the camera configuration sub-menu. */ @@ -90,70 +85,71 @@ public class Cli ConfigFacade.init(); - int userInput = 0; + //int userInput = 0; + ErrorLogging.logError("Initialising fixture movement. This will take a few moments, and may produce some temporary unnerving sounds from the motor. This is expected behaviour, and no damage is being done."); MovementFacade.calibrate(); - do - { - printMainMenu(); - userInput = (int)inputFiltering(inputScanner.nextLine()); + //do + //{ + // printMainMenu(); + // userInput = (int)inputFiltering(inputScanner.nextLine()); - switch (userInput) - { - case 1: - println("Setting up cameras..."); - println("This may take a moment..."); - configureCameras(); - camerasConfigured = true; - break; - case 2: - setDUTSerials(); - break; - case 3: - setIterationCount(); - break; - case 4: - setActiveCameras(); - break; - case 5: - if(!camerasConfigured) - { - prompt("You have not configured the cameras yet! Are you sure you would like to continue? (y/N): "); - String input = inputScanner.nextLine().toLowerCase().trim(); - if( input.isBlank() || input.charAt(0) != 'y' ) break; - else - ErrorLogging.logError("DEBUG: Potential for error: Un-initialised cameras."); - } + // switch (userInput) + // { + // case 1: + // println("Setting up cameras..."); + // println("This may take a moment..."); + // configureCameras(); + // camerasConfigured = true; + // break; + // case 2: + // setDUTSerials(); + // break; + // case 3: + // setIterationCount(); + // break; + // case 4: + // setActiveCameras(); + // break; + // case 5: + // if(!camerasConfigured) + // { + // prompt("You have not configured the cameras yet! Are you sure you would like to continue? (y/N): "); + // String input = inputScanner.nextLine().toLowerCase().trim(); + // if( input.isBlank() || input.charAt(0) != 'y' ) break; + // else + // ErrorLogging.logError("DEBUG: Potential for error: Un-initialised cameras."); + // } - serialsSet = true; - for(String cameraName : OpenCVFacade.getCameraNames()) - { - if(ConfigFacade.getValue(cameraName,ConfigProperties.ACTIVE) != 0 && - ConfigFacade.getSerial(cameraName) == null ) - serialsSet = false; - } - if(!serialsSet) - { - prompt("You have not set the serial numbers for your DUTs yet! Are you sure you would like to continue? (y/N): "); - String input = inputScanner.nextLine().toLowerCase().trim(); - if( input.isBlank() || input.charAt(0) != 'y' ) break; - else - ErrorLogging.logError("DEBUG: Potential for error: Un-initialised DUT Serial numbers."); - } + // serialsSet = true; + // for(String cameraName : OpenCVFacade.getCameraNames()) + // { + // if(ConfigFacade.getValue(cameraName,ConfigProperties.ACTIVE) != 0 && + // ConfigFacade.getSerial(cameraName) == null ) + // serialsSet = false; + // } + // if(!serialsSet) + // { + // prompt("You have not set the serial numbers for your DUTs yet! Are you sure you would like to continue? (y/N): "); + // String input = inputScanner.nextLine().toLowerCase().trim(); + // if( input.isBlank() || input.charAt(0) != 'y' ) break; + // else + // ErrorLogging.logError("DEBUG: Potential for error: Un-initialised DUT Serial numbers."); + // } - runTests(); - break; - case 6: - printHelp(); - break; - case 8: - break; - default: - //Input handling already done by inputFiltering() - } + // runTests(); + // break; + // case 6: + // printHelp(); + // break; + // case 8: + // break; + // default: + // //Input handling already done by inputFiltering() + // } - } while (userInput != mainMenuOptionCount); + //} while (userInput != mainMenuOptionCount); } //If anything ever goes wrong, catch the error and exit @@ -261,27 +257,6 @@ public class Cli println("======================================"); } - /** - * Predefined print statements for the movement submenu. - */ - //private static void printMovementMenu() - //{ - // println("\n\n"); - // println("===================================="); - // println("Movement Menu:"); - // println("------------------------------------"); - // println("Current Frequency: " + MovementFacade.getUserFrequency() + "KHz"); - // println("Current Motor Time-out: " + MovementFacade.getTimeout()); - // println("After " + (MovementFacade.getSlowFraction() * 100) + "% of the movement, motor speed will be " + MovementFacade.getSlowFactor() + "x slower."); - // println("------------------------------------"); - // println("1. Change Frequency"); - // println("2. Change Motor Time-out"); - // println("3. Change Slow-down Point"); - // println("4. Change Slow-down Amount"); - // println("5. Exit"); - // println("===================================="); - //} - /** * Pre-defined method for printing all available cameras in a menu */ @@ -367,97 +342,6 @@ public class Cli println("===================================="); } - - /** - * Function for testing movement, and modifying hardware values - */ - private static void testMovement() - { - //Loop to allow multiple changes to device GPIO settings - MovementFacade.calibrate(); - //do - //{ - // println("Testing movement..."); - // //MovementFacade.reset(); - // MovementFacade.FinalState downwardMove = MovementFacade.goDown(); - // switch(downwardMove) - // { - // case UNSAFE: - // ErrorLogging.logError("Movement warning!!! - Time-out too long, motor does not slow down before hitting limit switch. Consider setting this value to be lower."); - // break; - // case FAILED: - // ErrorLogging.logError("Movement warning!!! - Fixture did not hit lower limit switch. Consider changing frequency."); - // ErrorLogging.logError("Fixture movement configuration: Downward movement missed."); - // break; - // case SAFE: - // MovementFacade.FinalState returnMove = MovementFacade.goUp(); - // switch(returnMove) - // { - // case UNSAFE: - // ErrorLogging.logError("Movement warning!!! - Time-out too long, motor does not slow down before hitting limit switch. Consider setting this value to be lower."); - // break; - // case FAILED: - // ErrorLogging.logError("Movement warning!!! - Fixture did not hit upper limit switch. Consider changing frequency."); - // ErrorLogging.logError("Fixture movement configuration: Return movement missed."); - // break; - // case SAFE: - // } - // } - // //printMovementMenu(); - // userInput = (int)inputFiltering(inputScanner.nextLine()); - // switch (userInput) - // { - // /* - // * Menu options: - // * 1. Change Frequency - // * 2. Change Motor Time-out - // * 3. Change slow-down point - // * 4. Change slow-down amount - // * 5. Exit - // */ - // case 1: - // prompt("Input the desired frequency value (in KHz): "); - // int newFrequency = (int)inputFiltering(inputScanner.nextLine()); - // if (newFrequency != -1) - // { - // //MovementFacade.setFrequency(newFrequency); - // break; - // } - // case 2: - // prompt("Input the desired time-out (in seconds): "); - // double newTimeout = inputFiltering(inputScanner.nextLine()); - // if (newTimeout != -1) - // { - // //MovementFacade.setTimeout(newTimeout); - // break; - // } - // case 3: - // prompt("Input the desired percentage of travel to be slower: "); - // double newSlowFraction = inputFiltering(inputScanner.nextLine()); - // if(newSlowFraction != -1) - // { - // newSlowFraction = newSlowFraction / 100; - // MovementFacade.setSlowFraction(newSlowFraction); - // break; - // } - // case 4: - // prompt("Input the desired speed reduction factor: "); - // double newSpeedReduceFactor = inputFiltering(inputScanner.nextLine()); - // if(newSpeedReduceFactor != -1) - // { - // MovementFacade.setSlowFactor(newSpeedReduceFactor); - // break; - // } - // case movementMenuOptionCount: - // break; - // default: - // ErrorLogging.logError("User Input Error!!! - Invalid input."); - // } - //} - //while(userInput != movementMenuOptionCount); - //ConfigFacade.saveCurrentConfig(); - } - /** * Sub-function used to configure cameras. */ @@ -802,7 +686,9 @@ public class Cli */ private static void close() { + ErrorLogging.logError("DEBUG: ================="); ErrorLogging.logError("DEBUG: PROGRAM CLOSING."); + ErrorLogging.logError("DEBUG: ================="); if(inputScanner != null) inputScanner.close(); MovementFacade.closeGPIO(); ErrorLogging.logError("DEBUG: END OF PROGRAM."); @@ -852,13 +738,6 @@ public class Cli output = -1; } break; - case MOVEMENT: - if(output > movementMenuOptionCount) - { - invalidMovementMenuInput(); - output = -1; - } - break; case CAMERA: if(output > cameraMenuOptionCount) { @@ -881,14 +760,6 @@ public class Cli invalidMenuInput(mainMenuOptionCount); } - /** - * Prints a message when user inputs an invalid main menu value. - */ - private static void invalidMovementMenuInput() - { - invalidMenuInput(movementMenuOptionCount); - } - /** * Prints a message when user inputs an invalid main menu value. */ @@ -939,5 +810,5 @@ public class Cli /** * Enum of possible menus available */ - private enum Menus { MAIN,MOVEMENT,CAMERA,OTHER; } + private enum Menus { MAIN,CAMERA,OTHER; } } diff --git a/src/main/java/org/baxter/disco/ocr/ConfigFacade.java b/src/main/java/org/baxter/disco/ocr/ConfigFacade.java index 0ecb1f0..48ba6ef 100644 --- a/src/main/java/org/baxter/disco/ocr/ConfigFacade.java +++ b/src/main/java/org/baxter/disco/ocr/ConfigFacade.java @@ -11,11 +11,9 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.time.LocalDateTime; import java.util.ArrayList; -import java.util.Iterator; //Apache Commons Configuration imports import org.apache.commons.configuration2.INIConfiguration; -import org.apache.commons.configuration2.SubnodeConfiguration; import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder; import org.apache.commons.configuration2.builder.fluent.Parameters; @@ -280,6 +278,7 @@ public class ConfigFacade //********************************************** //SAVE AND LOAD SETTINGS //********************************************** + // /** * Save current config to a user-defined file location. @@ -436,22 +435,10 @@ public class ConfigFacade for(String sectionName : configSections) { Map savedSection = new HashMap<>(); - String subSectionPrefix = ""; for(String cameraName : cameraNames) { - if(sectionName.equals(cameraName)) - { - subSectionPrefix = cameraName; - break; - } - } - - //If an imported section fails, fallback to saving the default values to - //the given location - if(subSectionPrefix.equals("")) - { - ErrorLogging.logError("CONFIG LOAD ERROR!!! - Failed import from file. Setting default config."); - return saveDefaultConfig(filename); + if(!sectionName.equals(cameraName)) + { saveSingleDefault(cameraName); } } for(ConfigProperties configState : ConfigProperties.values()) @@ -485,4 +472,34 @@ public class ConfigFacade * @return true if loaded successfully, otherwise false */ public static boolean loadConfig() { return loadConfig(configFileLocation); } + + /** + * Save default values to a single camera's config. + * + * @param sectionName Name of the config section being saved to. + * + * @return false if error, else true + */ + private static boolean saveSingleDefault(String sectionName) + { + boolean output = false; + Map cameraConfig = new HashMap<>(); + for(ConfigProperties property : ConfigProperties.values()) + { + String propertyName = sectionName + "." + property.getConfig(); + double propertyValue = property.getDefaultValue(); + cameraConfig.put(property,propertyValue); + //ErrorLogging.logError("DEBUG: Attempting to save to config: "); + //ErrorLogging.logError("DEBUG: " + propertyName + ", " + propertyValue); + CONFIG_STORE.setProperty(propertyName,propertyValue); + } + configMap.put(sectionName,cameraConfig); + try + { + CONFIG_BUILDER.save(); + output = true; + } + catch(Exception e){ ErrorLogging.logError(e); } + return output; + } } diff --git a/src/main/java/org/baxter/disco/ocr/MovementFacade.java b/src/main/java/org/baxter/disco/ocr/MovementFacade.java index b6f4506..7642950 100644 --- a/src/main/java/org/baxter/disco/ocr/MovementFacade.java +++ b/src/main/java/org/baxter/disco/ocr/MovementFacade.java @@ -20,45 +20,19 @@ import com.pi4j.io.pwm.PwmType; * Currently missing Run switch compatibility. * * @author Blizzard Finnegan - * @version 2.4.0, 01 Mar. 2023 + * @version 3.0.0, 06 Mar. 2023 */ public class MovementFacade { - private static boolean exit = false; /** - * Constructor for MovementFacade. - * - * @param LOCK A Lock object, used for interactions with - * the physical lock switch on the fixture. + * Boolean used to communicate with runSwitchThread to gracefully exit. */ - //public MovementFacade(Lock LOCK) - //{ - // //ErrorLogging.logError("DEBUG: Starting lock thread..."); - // runSwitchThread = new Thread(() -> - // { - // boolean unlock = false; - // while(!exit) - // { - // if(runSwitch.isOn()) - // { - // ErrorLogging.logError("Run switch turned off!"); - // while(!LOCK.tryLock()) - // {} - // unlock = true; - // } - // else - // { - // //ErrorLogging.logError("Run switch on!"); - // if(unlock) - // { LOCK.unlock(); unlock = false; } - // } - // //try{ Thread.sleep(100); } catch(Exception e) { ErrorLogging.logError(e); } - // } - // }, "Run switch monitor."); - // runSwitchThread.start(); - // //ErrorLogging.logError("DEBUG: Lock thread started!"); - //} + private static boolean exit = false; + /** + * Thread that watches the physical Run switch on the device so that + * fixture movement can be stopped. + */ private static Thread runSwitchThread; /** @@ -74,11 +48,6 @@ public class MovementFacade */ private static final int PWM_FREQ_CONVERT = 19200; - /** - * Max allowed frequency by current fixture design. - */ - //private static int MAX_FREQUENCY = 175000; - /** * Max allowed speed by current fixture design. * Motor appears to start acting erratically over 192kHz. @@ -108,7 +77,14 @@ public class MovementFacade */ private static final int TRAVEL_DIST = 30; + /** + * What percentage of the travel to slow down the motor. + */ private static final double STEP_1 = 2/3; + + /** + * What percentage of the travel to slow down the motor farther. + */ private static final double STEP_2 = 5/6; /** @@ -116,6 +92,9 @@ public class MovementFacade */ private static double SPEED = MIN_SPEED; + /** + * Frequency fed to the PWM pin, which the motor controller converts into movement speed. + */ private static int FREQUENCY = (int)(SPEED * PWM_FREQ_CONVERT); /** @@ -254,7 +233,7 @@ public class MovementFacade if(unlock) { Cli.LOCK.unlock(); unlock = false; } } - //try{ Thread.sleep(100); } catch(Exception e) { ErrorLogging.logError(e); } + try{ Thread.sleep(100); } catch(Exception e) { ErrorLogging.logError(e); } } }, "Run switch monitor."); runSwitchThread.start(); @@ -273,11 +252,9 @@ public class MovementFacade motorDirection = outputBuilder("motorDirection", "Motor Direction", MOTOR_DIRECTION_ADDR); pistonActivate = outputBuilder("piston" , "Piston Activate", PISTON_ADDR); - //Initialise PWM object. This object is never used, - //as the PWM signal is simply a clock for the motor. + //Initialise PWM object. pwm = pwmBuilder("pwm","PWM Pin",PWM_PIN_ADDR); //pwm.on(DUTY_CYCLE, FREQUENCY); - } /** @@ -378,27 +355,26 @@ public class MovementFacade public static int resetArm() { int counter = 0; - //ErrorLogging.logError("Setting minimum frequency of PWM..."); - //ErrorLogging.logError("Minimum frequency: " + MIN_FREQUENCY); + ErrorLogging.logError("DEBUG: Setting minimum frequency of PWM..."); pwm.on(DUTY_CYCLE, MIN_FREQUENCY); if(upperLimit.isHigh()) { - //ErrorLogging.logError("Motor at highest point! Lowering to reset."); + ErrorLogging.logError("DEBUG: Motor at highest point! Lowering to reset."); motorDirection.low(); - //ErrorLogging.logError("Motor on!"); + ErrorLogging.logError("DEBUG: Motor offset on."); motorEnable.on(); try{ Thread.sleep(500); } catch (Exception e){ ErrorLogging.logError(e); } motorEnable.off(); - //ErrorLogging.logError("Motor off!"); + ErrorLogging.logError("DEBUG: Motor offset off."); } - //ErrorLogging.logError("Moving motor to highest point."); + ErrorLogging.logError("DEBUG: Moving motor to highest point."); motorDirection.high(); - //ErrorLogging.logError("Motor on!"); + ErrorLogging.logError("DEBUG: Motor return on."); motorEnable.on(); - //ErrorLogging.logError("Is the upper limit switch reached? " + upperLimit.isHigh()); + ErrorLogging.logError("DEBUG: Is the upper limit switch reached? " + upperLimit.isHigh()); while(!upperLimit.isHigh()) { try{ Thread.sleep(100); } @@ -406,7 +382,7 @@ public class MovementFacade counter++; } motorEnable.off(); - //ErrorLogging.logError("Motor returned after " + counter + " polls."); + ErrorLogging.logError("DEBUG: Motor returned after " + counter + " polls."); return counter; } @@ -418,10 +394,11 @@ public class MovementFacade ErrorLogging.logError("Initial Calibration reset."); resetArm(); ErrorLogging.logError("Coarse calibrating..."); - SPEED = calib(1, MAX_SPEED, 1); - ErrorLogging.logError("Coarse calibrating..."); + SPEED = calib(3, MAX_SPEED, 1); + ErrorLogging.logError("Fine calibrating..."); SPEED = calib(SPEED,(SPEED+1),0.1); - ErrorLogging.logError("Speed set to " + (SPEED - SPEED_BUFFER)); + ErrorLogging.logError("Calibration complete!"); + ErrorLogging.logError("DEBUG: Speed set to " + (SPEED - SPEED_BUFFER)); setSpeed(SPEED - SPEED_BUFFER); } @@ -436,39 +413,47 @@ public class MovementFacade */ private static double calib(double start, double max, double iterate) { - ErrorLogging.logError("Calibrating. Iterating from " + start + " to " + max + " in " + iterate + " steps."); + ErrorLogging.logError("DEBUG: Calibrating. Iterating from " + start + " to " + max + " in " + iterate + " steps."); + //start -= iterate; for(double i = start; i < max; i+=iterate) { - //ErrorLogging.logError("Testing speed " + i + "..."); + ErrorLogging.logError("DEBUG: Testing speed " + i + "..."); if(!setSpeed(i)) { - //ErrorLogging.logError("Speed set unsuccessfully! returning " + MIN_SPEED + "..."); + ErrorLogging.logError("DEBUG: Speed set unsuccessfully! returning " + MIN_SPEED + "..."); return MIN_SPEED; } - //ErrorLogging.logError("Motor travelling down."); + ErrorLogging.logError("DEBUG: Motor travelling down."); motorDirection.low(); - //ErrorLogging.logError("Motor on!"); + ErrorLogging.logError("DEBUG: Motor Frequency: " + FREQUENCY); + pwm.on(DUTY_CYCLE,FREQUENCY); + ErrorLogging.logError("DEBUG: Motor calibrate on."); motorEnable.on(); - for(int j = 0; j < 5; j++) + for(int j = 0; j < 20; j++) { try{ Thread.sleep(100); } catch (Exception e){ ErrorLogging.logError(e); } - if(lowerLimit.isHigh()) break; + if(lowerLimit.isHigh()) + { + ErrorLogging.logError("DEBUG: Breaking loop early!"); + break; + } } motorEnable.off(); - //ErrorLogging.logError("Motor off!"); + ErrorLogging.logError("DEBUG: Motor calibrate off."); if(upperLimit.isHigh()) { - ErrorLogging.logError("Motor faild to move! Returning " + (i - iterate)); + ErrorLogging.logError("DEBUG: Upper limit is high = " + upperLimit.isHigh()); + ErrorLogging.logError("DEBUG: Motor failed to move! Returning " + (i - iterate)); return i-iterate; } else { - //ErrorLogging.logError("Motor moved at speed " + i + ". Checking for errors."); - if(resetArm() < 10 && i > 1.0) + ErrorLogging.logError("DEBUG: Motor moved at speed " + i + ". Checking for errors."); + if(resetArm() < 10 && i > 3.0) { - ErrorLogging.logError("Motor failed to move! Returning " + (i - iterate)); + ErrorLogging.logError("DEBUG: Motor failed to move! Returning " + (i - iterate)); return i - iterate; } } @@ -496,6 +481,7 @@ public class MovementFacade } SPEED = newSpeed; FREQUENCY = (int)(SPEED * PWM_FREQ_CONVERT); + ErrorLogging.logError("DEBUG: Setting frequency to " + FREQUENCY); pwm.on(DUTY_CYCLE, FREQUENCY); return output; } @@ -504,11 +490,9 @@ public class MovementFacade * Internal function to send the fixture to a given limit switch. * * Detects if the limit switch is active before activating motor. - * - * Motor slows down after timeout is halfway through, to protect hardware. + * Motor movement is written to slow down at {@link #STEP_1} and {@link #STEP_2} * * @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 static FinalState gotoLimit(boolean moveUp) @@ -536,28 +520,28 @@ public class MovementFacade int POLL_COUNT = TRAVEL_TIME * TIME_CONVERSION; int VEL_STEP_1 = (int)(STEP_1 * POLL_COUNT); int VEL_STEP_2 = (int)(STEP_2 * POLL_COUNT); - //int mostlyThere = (int) (POLL_COUNT * slowFraction); - //int slowerSpeed = (int) (FREQUENCY / speedReduceFactor); - ErrorLogging.logError("Total Poll count: " + POLL_COUNT); - ErrorLogging.logError("Transition 1: " + VEL_STEP_1); - ErrorLogging.logError("Transition 2: " + VEL_STEP_2); - ErrorLogging.logError("Travel time: " + TRAVEL_TIME); - ErrorLogging.logError("Travel speed: " + SPEED); + ErrorLogging.logError("DEBUG: Total Poll count: " + POLL_COUNT); + ErrorLogging.logError("DEBUG: Transition 1: " + VEL_STEP_1); + ErrorLogging.logError("DEBUG: Transition 2: " + VEL_STEP_2); + ErrorLogging.logError("DEBUG: Travel time: " + TRAVEL_TIME); + ErrorLogging.logError("DEBUG: Travel speed: " + SPEED); + ErrorLogging.logError("DEBUG: STEP_1: " + STEP_1); + ErrorLogging.logError("DEBUG: STEP_2: " + STEP_2); motorEnable.on(); for(int i = 0; i < (POLL_COUNT);i++) { - ErrorLogging.logError("Iteration " + i); + ErrorLogging.logError("DEBUG: Iteration " + i); try{ Thread.sleep(POLL_WAIT); } catch(Exception e){ ErrorLogging.logError(e); } if(i >= VEL_STEP_1 && i < VEL_STEP_2) { output = FinalState.UNSAFE; - ErrorLogging.logError("Slow down!"); + ErrorLogging.logError("DEBUG: Slowing down."); pwm.on(DUTY_CYCLE, FREQUENCY / 2); } else if(i >= VEL_STEP_2) { - ErrorLogging.logError("Slow down more!"); + ErrorLogging.logError("DEBUG: Slowing down more."); pwm.on(DUTY_CYCLE, FREQUENCY / 4); output = FinalState.SAFE; } diff --git a/src/main/java/org/baxter/disco/ocr/OpenCVFacade.java b/src/main/java/org/baxter/disco/ocr/OpenCVFacade.java index f485954..b861e43 100644 --- a/src/main/java/org/baxter/disco/ocr/OpenCVFacade.java +++ b/src/main/java/org/baxter/disco/ocr/OpenCVFacade.java @@ -37,7 +37,7 @@ import java.util.List; * Performs image capture, as well as image manipulation. * * @author Blizzard Finnegan - * @version 2.0.1, 15 Feb. 2023 + * @version 2.1.0, 06 Mar. 2023 */ public class OpenCVFacade { @@ -57,28 +57,35 @@ public class OpenCVFacade * Width of the image created by the camera. * !!See camera documentation before modifying!! */ - private static final int IMG_WIDTH = 3264; - //Previously used code: - //private static final int IMG_WIDTH = 800; + private static final int IMG_WIDTH = 800; /** * Height of the image created by the camera. * !!See camera documentation before modifying!! */ - private static final int IMG_HEIGHT = 2448; - //Previously used code: - //private static final int IMG_HEIGHT = 600; + private static final int IMG_HEIGHT = 600; /** * FourCC code of the image created by the camera. * !!See camera documentation before modifying!! */ private static final String CAMERA_CODEC = "mjpg"; + /** + * Name of custom-created symlink for cameras. + * This configuration must be done manually on initial install. + */ + private static final String CAMERA_FILE_PREFIX = "video-cam-"; + //Initial Camera creation static { - //Pis should already be configured to create this symlink. - newCamera("left", "/dev/video-cam1"); - newCamera("right","/dev/video-cam2"); + File devDirectory = new File("/dev"); + for(File cameraFile : devDirectory.listFiles( + (file) -> { return file.getName().contains(CAMERA_FILE_PREFIX); })) + { + String cameraName = cameraFile.getName(). + substring(CAMERA_FILE_PREFIX.length()); + newCamera(cameraName, cameraFile.getAbsolutePath()); + } } /**