Version bump
- Update all classes to more verbosely log what's going on. - Update readme and udev rule for automatic camera checking - Add dependency-checking plugin to pom.xml - Add GPIO check on initialisation, and override to not drive GPIO if not plugged in - Continue updating functions to be closer and more accurate to documentation
This commit is contained in:
parent
65eaec4035
commit
5796163068
11 changed files with 294 additions and 117 deletions
|
@ -1,2 +1,2 @@
|
||||||
##EXAMPLE: ACTION=="add", KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", SUBSYSTEMS=="usb", ENV{ID_PATH}=="platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.4:1.0", SYMLINK+="video-cam1"
|
##EXAMPLE: ACTION=="add", KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", SUBSYSTEMS=="usb", ENV{ID_PATH}=="platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.4:1.0", SYMLINK+="video-cam-left"
|
||||||
ACTION=="add", KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", SUBSYSTEMS=="usb", ENV{ID_PATH}=="fillerText", SYMLINK+="video-cam1"
|
ACTION=="add", KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", SUBSYSTEMS=="usb", ENV{ID_PATH}=="fillerText", SYMLINK+="video-cam-left"
|
||||||
|
|
|
@ -94,7 +94,7 @@ ls /dev/video-*
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
The project is then built from source, and the output final binary (located in `target/discoTesting.jar`) is copied to the Raspberry Pi for use.
|
The project is then built from source, and the output final binary (located in `target/discoTesting-[version].jar`) is copied to the Raspberry Pi for use.
|
||||||
|
|
||||||
This project requires use of `udev` rules to ensure that cameras are in the proper location, by default. This can be modified in this project (camera initialisation is done in the initialisation of `OpenCVFacade`).
|
This project requires use of `udev` rules to ensure that cameras are in the proper location, by default. This can be modified in this project (camera initialisation is done in the initialisation of `OpenCVFacade`).
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<groupId>org.baxter.disco</groupId>
|
<groupId>org.baxter.disco</groupId>
|
||||||
<artifactId>ocr</artifactId>
|
<artifactId>ocr</artifactId>
|
||||||
<name>Disco OCR Accuracy Over Life Testing</name>
|
<name>Disco OCR Accuracy Over Life Testing</name>
|
||||||
<version>4.3.7</version>
|
<version>4.3.8</version>
|
||||||
<description>Testing Discos for long-term accuracy, using automated optical character recognition.</description>
|
<description>Testing Discos for long-term accuracy, using automated optical character recognition.</description>
|
||||||
<organization>
|
<organization>
|
||||||
<name>Baxter International</name>
|
<name>Baxter International</name>
|
||||||
|
@ -26,11 +26,6 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-project-info-reports-plugin</artifactId>
|
<artifactId>maven-project-info-reports-plugin</artifactId>
|
||||||
<version>3.0.0</version>
|
<version>3.0.0</version>
|
||||||
<configuration>
|
|
||||||
<suppressionFiles>
|
|
||||||
<suppressionFile>./dependency-check-suppressions.xml</suppressionFile>
|
|
||||||
</suppressionFiles>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-javadoc-plugin</artifactId>
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
@ -100,6 +95,9 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-javadoc-plugin</artifactId>
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
<version>3.4.1</version>
|
<version>3.4.1</version>
|
||||||
|
<configuration>
|
||||||
|
<show>private</show>
|
||||||
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</reporting>
|
</reporting>
|
||||||
|
|
10
pom.xml
10
pom.xml
|
@ -3,7 +3,7 @@
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.baxter.disco</groupId>
|
<groupId>org.baxter.disco</groupId>
|
||||||
<artifactId>ocr</artifactId>
|
<artifactId>ocr</artifactId>
|
||||||
<version>4.3.7</version>
|
<version>4.3.8</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<name>Disco OCR Accuracy Over Life Testing</name>
|
<name>Disco OCR Accuracy Over Life Testing</name>
|
||||||
<description>Testing Discos for long-term accuracy, using automated optical character recognition.</description>
|
<description>Testing Discos for long-term accuracy, using automated optical character recognition.</description>
|
||||||
|
@ -106,11 +106,11 @@
|
||||||
<groupId>org.owasp</groupId>
|
<groupId>org.owasp</groupId>
|
||||||
<artifactId>dependency-check-maven</artifactId>
|
<artifactId>dependency-check-maven</artifactId>
|
||||||
<version>8.1.2</version>
|
<version>8.1.2</version>
|
||||||
<configuration>
|
<!--<configuration>
|
||||||
<suppressionFiles>
|
<suppressionFiles>
|
||||||
<suppressionFile>dependency-check-suppressions.xml</suppressionFile>
|
<suppressionFile>dependency-check-suppressions.xml</suppressionFile>
|
||||||
</suppressionFiles>
|
</suppressionFiles>
|
||||||
</configuration>
|
</configuration>-->
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
@ -192,9 +192,9 @@
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-javadoc-plugin</artifactId>
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
<version>3.4.1</version>
|
<version>3.4.1</version>
|
||||||
<!--<configuration>
|
<configuration>
|
||||||
<show>private</show>
|
<show>private</show>
|
||||||
</configuration>-->
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</reporting>
|
</reporting>
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
#! /usr/bin/env sh
|
#! /usr/bin/env sh
|
||||||
sudo java -jar discoTesting-4.3.7.jar 2>/dev/null
|
sudo java -jar discoTesting-4.3.8.jar 2>/dev/null
|
||||||
|
|
|
@ -25,7 +25,7 @@ public class Cli
|
||||||
/**
|
/**
|
||||||
* Complete build version number
|
* Complete build version number
|
||||||
*/
|
*/
|
||||||
private static final String version = "4.3.7";
|
private static final String version = "4.3.8";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Currently saved iteration count.
|
* Currently saved iteration count.
|
||||||
|
@ -50,6 +50,11 @@ public class Cli
|
||||||
*/
|
*/
|
||||||
private static boolean camerasConfigured = false;
|
private static boolean camerasConfigured = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether GPIO is safe to use
|
||||||
|
*/
|
||||||
|
private static boolean safeGPIO = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of options currently available in the main menu.
|
* Number of options currently available in the main menu.
|
||||||
*/
|
*/
|
||||||
|
@ -85,7 +90,31 @@ public class Cli
|
||||||
|
|
||||||
ErrorLogging.logError("Calibrating motor movement. ");
|
ErrorLogging.logError("Calibrating motor movement. ");
|
||||||
ErrorLogging.logError("The piston will fire momentarily when the motor calibration is complete.");
|
ErrorLogging.logError("The piston will fire momentarily when the motor calibration is complete.");
|
||||||
MovementFacade.pressButton();
|
|
||||||
|
boolean testedGPIO = false;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
MovementFacade.init();
|
||||||
|
ErrorLogging.logError("Motor movement successfully calibrated!");
|
||||||
|
testedGPIO = true;
|
||||||
|
safeGPIO = true;
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
ErrorLogging.logError(e);
|
||||||
|
ErrorLogging.logError("GPIO initialisation error! Please check GPIO connections.");
|
||||||
|
println("");
|
||||||
|
prompt("Press enter to try again.");
|
||||||
|
String userInputString = inputScanner.nextLine();
|
||||||
|
if(userInputString.length() > 0)
|
||||||
|
{
|
||||||
|
testedGPIO = userInputString.contains("override");
|
||||||
|
ErrorLogging.logError("DEBUG: WARNING! - User override of GPIO check.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}while(!testedGPIO);
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -188,6 +217,7 @@ public class Cli
|
||||||
*/
|
*/
|
||||||
private static void printHelp()
|
private static void printHelp()
|
||||||
{
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: User asked for help at main menu.");
|
||||||
println("\n\n");
|
println("\n\n");
|
||||||
println("========================================");
|
println("========================================");
|
||||||
println("Explanations:");
|
println("Explanations:");
|
||||||
|
@ -348,6 +378,7 @@ public class Cli
|
||||||
*/
|
*/
|
||||||
private static void printCameraConfigHelpMenu()
|
private static void printCameraConfigHelpMenu()
|
||||||
{
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: User asked for help at camera config menu.");
|
||||||
println("\n\n");
|
println("\n\n");
|
||||||
println("============================================================");
|
println("============================================================");
|
||||||
println("Camera Config Menu options:");
|
println("Camera Config Menu options:");
|
||||||
|
@ -389,10 +420,11 @@ public class Cli
|
||||||
*/
|
*/
|
||||||
private static void configureCameras()
|
private static void configureCameras()
|
||||||
{
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: Configuing cameras...");
|
||||||
List<String> cameraList = new ArrayList<>(OpenCVFacade.getCameraNames());
|
List<String> cameraList = new ArrayList<>(OpenCVFacade.getCameraNames());
|
||||||
|
|
||||||
//Always wake the camera, to ensure that the image is useful
|
//Always wake the camera, to ensure that the image is useful
|
||||||
MovementFacade.iterationMovement(true);
|
if(safeGPIO) MovementFacade.iterationMovement(true);
|
||||||
double tesseractValue = 0.0;
|
double tesseractValue = 0.0;
|
||||||
|
|
||||||
do
|
do
|
||||||
|
@ -414,11 +446,14 @@ public class Cli
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
//Press button twice, to make sure the DUT is awake
|
if(safeGPIO)
|
||||||
MovementFacade.pressButton();
|
{
|
||||||
try{ Thread.sleep(2000); } catch(Exception e){ ErrorLogging.logError(e); }
|
//Press button twice, to make sure the DUT is awake
|
||||||
MovementFacade.pressButton();
|
MovementFacade.pressButton();
|
||||||
try{ Thread.sleep(2000); } catch(Exception e){ ErrorLogging.logError(e); }
|
try{ Thread.sleep(2000); } catch(Exception e){ ErrorLogging.logError(e); }
|
||||||
|
MovementFacade.pressButton();
|
||||||
|
try{ Thread.sleep(2000); } catch(Exception e){ ErrorLogging.logError(e); }
|
||||||
|
}
|
||||||
|
|
||||||
File image = OpenCVFacade.showImage(cameraName);
|
File image = OpenCVFacade.showImage(cameraName);
|
||||||
tesseractValue = TesseractFacade.imageToDouble(image);
|
tesseractValue = TesseractFacade.imageToDouble(image);
|
||||||
|
@ -497,6 +532,7 @@ public class Cli
|
||||||
*/
|
*/
|
||||||
private static void setDUTSerials()
|
private static void setDUTSerials()
|
||||||
{
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: Setting DUT serials...");
|
||||||
List<String> cameraList = new ArrayList<>(OpenCVFacade.getCameraNames());
|
List<String> cameraList = new ArrayList<>(OpenCVFacade.getCameraNames());
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -534,6 +570,7 @@ public class Cli
|
||||||
input = (int)inputFiltering(inputScanner.nextLine());
|
input = (int)inputFiltering(inputScanner.nextLine());
|
||||||
} while(input == -1);
|
} while(input == -1);
|
||||||
iterationCount = input;
|
iterationCount = input;
|
||||||
|
ErrorLogging.logError("DEBUG: Iteration count modified! Iteration count is now: " + iterationCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -541,6 +578,7 @@ public class Cli
|
||||||
*/
|
*/
|
||||||
private static void setActiveCameras()
|
private static void setActiveCameras()
|
||||||
{
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: User modified active cameras.");
|
||||||
List<String> cameraList = new ArrayList<>(OpenCVFacade.getCameraNames());
|
List<String> cameraList = new ArrayList<>(OpenCVFacade.getCameraNames());
|
||||||
|
|
||||||
do
|
do
|
||||||
|
@ -564,6 +602,13 @@ public class Cli
|
||||||
ConfigFacade.setValue(cameraName,ConfigProperties.ACTIVE,newValue);
|
ConfigFacade.setValue(cameraName,ConfigProperties.ACTIVE,newValue);
|
||||||
|
|
||||||
} while(true);
|
} while(true);
|
||||||
|
ErrorLogging.logError("DEBUG: Currently active cameras:");
|
||||||
|
for(String camera : OpenCVFacade.getCameraNames())
|
||||||
|
{
|
||||||
|
if(ConfigFacade.getValue(camera,ConfigProperties.ACTIVE) != 0)
|
||||||
|
ErrorLogging.logError("DEBUG: - " + camera);
|
||||||
|
}
|
||||||
|
ErrorLogging.logError("DEBUG:");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -594,8 +639,11 @@ public class Cli
|
||||||
|
|
||||||
//Wake the device, then wait to ensure they're awake before continuing
|
//Wake the device, then wait to ensure they're awake before continuing
|
||||||
ErrorLogging.logError("DEBUG: Waking devices...");
|
ErrorLogging.logError("DEBUG: Waking devices...");
|
||||||
MovementFacade.pressButton();
|
if(safeGPIO)
|
||||||
try{ Thread.sleep(2000); } catch(Exception e){ ErrorLogging.logError(e); }
|
{
|
||||||
|
MovementFacade.pressButton();
|
||||||
|
try{ Thread.sleep(2000); } catch(Exception e){ ErrorLogging.logError(e); }
|
||||||
|
}
|
||||||
|
|
||||||
Map<File,Double> resultMap = new HashMap<>();
|
Map<File,Double> resultMap = new HashMap<>();
|
||||||
Map<String,File> cameraToFile = new HashMap<>();
|
Map<String,File> cameraToFile = new HashMap<>();
|
||||||
|
@ -623,12 +671,15 @@ public class Cli
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
fail = false;
|
fail = false;
|
||||||
while(!LOCK.tryLock()) {}
|
if(safeGPIO)
|
||||||
MovementFacade.iterationMovement(prime);
|
{
|
||||||
LOCK.unlock();
|
while(!LOCK.tryLock()) {}
|
||||||
|
MovementFacade.iterationMovement(prime);
|
||||||
|
LOCK.unlock();
|
||||||
|
|
||||||
//Wait for the DUT to display an image
|
//Wait for the DUT to display an image
|
||||||
try{ Thread.sleep(2000); } catch(Exception e){ ErrorLogging.logError(e); }
|
try{ Thread.sleep(2000); } catch(Exception e){ ErrorLogging.logError(e); }
|
||||||
|
}
|
||||||
|
|
||||||
for(String cameraName : cameraList)
|
for(String cameraName : cameraList)
|
||||||
{
|
{
|
||||||
|
@ -692,7 +743,7 @@ public class Cli
|
||||||
ErrorLogging.logError("DEBUG: PROGRAM CLOSING.");
|
ErrorLogging.logError("DEBUG: PROGRAM CLOSING.");
|
||||||
ErrorLogging.logError("DEBUG: =================");
|
ErrorLogging.logError("DEBUG: =================");
|
||||||
if(inputScanner != null) inputScanner.close();
|
if(inputScanner != null) inputScanner.close();
|
||||||
MovementFacade.closeGPIO();
|
if(safeGPIO) MovementFacade.closeGPIO();
|
||||||
ErrorLogging.logError("DEBUG: END OF PROGRAM.");
|
ErrorLogging.logError("DEBUG: END OF PROGRAM.");
|
||||||
ErrorLogging.closeLogs();
|
ErrorLogging.closeLogs();
|
||||||
println("The program has exited successfully. Please press Ctrl-c to return to the terminal prompt.");
|
println("The program has exited successfully. Please press Ctrl-c to return to the terminal prompt.");
|
||||||
|
|
|
@ -148,6 +148,7 @@ public class ConfigFacade
|
||||||
*/
|
*/
|
||||||
public static double getValue(String cameraName, ConfigProperties property)
|
public static double getValue(String cameraName, ConfigProperties property)
|
||||||
{
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: Getting " + property.getConfig() + " for " + cameraName + "camera...");
|
||||||
double output = 0.0;
|
double output = 0.0;
|
||||||
if(!CONFIG_MAP.keySet().contains(cameraName))
|
if(!CONFIG_MAP.keySet().contains(cameraName))
|
||||||
{
|
{
|
||||||
|
@ -163,7 +164,7 @@ public class ConfigFacade
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called to force early calling of the static block
|
* Initialises ConfigFacade and OpenCVFacade values
|
||||||
*/
|
*/
|
||||||
public static void init() {}
|
public static void init() {}
|
||||||
|
|
||||||
|
@ -182,12 +183,18 @@ public class ConfigFacade
|
||||||
*/
|
*/
|
||||||
public static boolean setOutputSaveLocation(String path)
|
public static boolean setOutputSaveLocation(String path)
|
||||||
{
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: Output save location modified!");
|
||||||
boolean output = false;
|
boolean output = false;
|
||||||
if(Files.exists(Paths.get(path)))
|
if(Files.exists(Paths.get(path)))
|
||||||
{
|
{
|
||||||
outputSaveLocation = path;
|
outputSaveLocation = path;
|
||||||
|
ErrorLogging.logError("DEBUG: New output save location: " + outputSaveLocation);
|
||||||
output = true;
|
output = true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: Output save location modification failed.");
|
||||||
|
}
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,12 +213,18 @@ public class ConfigFacade
|
||||||
*/
|
*/
|
||||||
public static boolean setImgSaveLocation(String path)
|
public static boolean setImgSaveLocation(String path)
|
||||||
{
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: Image save location modified!");
|
||||||
boolean output = false;
|
boolean output = false;
|
||||||
if(Files.exists(Paths.get(path)))
|
if(Files.exists(Paths.get(path)))
|
||||||
{
|
{
|
||||||
imageSaveLocation = path;
|
imageSaveLocation = path;
|
||||||
|
ErrorLogging.logError("DEBUG: New image save location: " + outputSaveLocation);
|
||||||
output = true;
|
output = true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: Output save location modification failed.");
|
||||||
|
}
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,6 +238,7 @@ public class ConfigFacade
|
||||||
*/
|
*/
|
||||||
public static boolean setValue(String cameraName, ConfigProperties property, double propertyValue)
|
public static boolean setValue(String cameraName, ConfigProperties property, double propertyValue)
|
||||||
{
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: Setting " + property.getConfig() + " to " + propertyValue + "for " + cameraName);
|
||||||
boolean output = false;
|
boolean output = false;
|
||||||
|
|
||||||
List<String> activeCameras = new ArrayList<>(OpenCVFacade.getCameraNames());
|
List<String> activeCameras = new ArrayList<>(OpenCVFacade.getCameraNames());
|
||||||
|
@ -278,6 +292,7 @@ public class ConfigFacade
|
||||||
*/
|
*/
|
||||||
public static boolean saveDefaultConfig(String filename)
|
public static boolean saveDefaultConfig(String filename)
|
||||||
{
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: Saving default config to " + filename);
|
||||||
boolean output = false;
|
boolean output = false;
|
||||||
Set<String> cameraNames = OpenCVFacade.getCameraNames();
|
Set<String> cameraNames = OpenCVFacade.getCameraNames();
|
||||||
|
|
||||||
|
@ -335,6 +350,7 @@ public class ConfigFacade
|
||||||
*/
|
*/
|
||||||
public static boolean saveCurrentConfig(String filename)
|
public static boolean saveCurrentConfig(String filename)
|
||||||
{
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: Saving current config to " + filename);
|
||||||
boolean output = false;
|
boolean output = false;
|
||||||
|
|
||||||
//Get a list of all cameras
|
//Get a list of all cameras
|
||||||
|
@ -379,6 +395,7 @@ public class ConfigFacade
|
||||||
*/
|
*/
|
||||||
public static boolean loadConfig(String filename)
|
public static boolean loadConfig(String filename)
|
||||||
{
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: Attempting to load config from " + filename);
|
||||||
//Check if the current CONFIG_MAP is empty
|
//Check if the current CONFIG_MAP is empty
|
||||||
boolean emptyMap = CONFIG_MAP.keySet().size() == 0;
|
boolean emptyMap = CONFIG_MAP.keySet().size() == 0;
|
||||||
boolean output = false;
|
boolean output = false;
|
||||||
|
@ -386,7 +403,14 @@ public class ConfigFacade
|
||||||
//If the config file we're trying to load from doesn't exist, failover to saving
|
//If the config file we're trying to load from doesn't exist, failover to saving
|
||||||
//the default values to a new file with that name
|
//the default values to a new file with that name
|
||||||
File file = new File(filename);
|
File file = new File(filename);
|
||||||
try{ if(file.createNewFile()) return saveDefaultConfig(); }
|
try
|
||||||
|
{
|
||||||
|
if(file.createNewFile())
|
||||||
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: Listed file does not exist!");
|
||||||
|
return saveDefaultConfig();
|
||||||
|
}
|
||||||
|
}
|
||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
{
|
{
|
||||||
ErrorLogging.logError(e);
|
ErrorLogging.logError(e);
|
||||||
|
@ -461,6 +485,7 @@ public class ConfigFacade
|
||||||
*/
|
*/
|
||||||
private static boolean saveSingleDefault(String sectionName)
|
private static boolean saveSingleDefault(String sectionName)
|
||||||
{
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: Section unsuccessfully imported! Saving defaults to " + sectionName);
|
||||||
boolean output = false;
|
boolean output = false;
|
||||||
Map<ConfigProperties,Double> cameraConfig = new HashMap<>();
|
Map<ConfigProperties,Double> cameraConfig = new HashMap<>();
|
||||||
for(ConfigProperties property : ConfigProperties.values())
|
for(ConfigProperties property : ConfigProperties.values())
|
||||||
|
|
|
@ -91,6 +91,7 @@ public class DataSaving
|
||||||
*/
|
*/
|
||||||
public static boolean initWorkbook(String filename, int camCount, double targetTemp, double failRange)
|
public static boolean initWorkbook(String filename, int camCount, double targetTemp, double failRange)
|
||||||
{
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: Initialising workbook...");
|
||||||
DataSaving.targetTemp = targetTemp;
|
DataSaving.targetTemp = targetTemp;
|
||||||
DataSaving.failRange = failRange;
|
DataSaving.failRange = failRange;
|
||||||
boolean output = false;
|
boolean output = false;
|
||||||
|
@ -148,8 +149,15 @@ public class DataSaving
|
||||||
passPercentCell.setCellValue("Pass %");
|
passPercentCell.setCellValue("Pass %");
|
||||||
|
|
||||||
try (FileOutputStream outputStream = new FileOutputStream(outputFile))
|
try (FileOutputStream outputStream = new FileOutputStream(outputFile))
|
||||||
{ outputWorkbook.write(outputStream); }
|
{
|
||||||
catch(Exception e) {ErrorLogging.logError(e);}
|
outputWorkbook.write(outputStream);
|
||||||
|
ErrorLogging.logError("DEBUG: Initialising workbook completed successfully.");
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: Workbook save failed!");
|
||||||
|
ErrorLogging.logError(e);
|
||||||
|
}
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
@ -161,6 +169,7 @@ public class DataSaving
|
||||||
*/
|
*/
|
||||||
private static void updateFormulas(int cameraCount)
|
private static void updateFormulas(int cameraCount)
|
||||||
{
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: Updating formulas in Excel sheet...");
|
||||||
int rowIndex = 0;
|
int rowIndex = 0;
|
||||||
FormulaEvaluator formulaEvaluator = outputWorkbook.getCreationHelper().createFormulaEvaluator();
|
FormulaEvaluator formulaEvaluator = outputWorkbook.getCreationHelper().createFormulaEvaluator();
|
||||||
int lastColumnOfData = outputSheet.getRow(rowIndex).getLastCellNum();
|
int lastColumnOfData = outputSheet.getRow(rowIndex).getLastCellNum();
|
||||||
|
@ -224,6 +233,7 @@ public class DataSaving
|
||||||
*/
|
*/
|
||||||
public static boolean writeValues(int cycle, Map<File,Double> inputMap, Map<String,File> cameraToFile)
|
public static boolean writeValues(int cycle, Map<File,Double> inputMap, Map<String,File> cameraToFile)
|
||||||
{
|
{
|
||||||
|
ErrorLogging.logError("Writing values for " + cycle + " cycle to worksheet.");
|
||||||
boolean output = false;
|
boolean output = false;
|
||||||
int cellnum = 0;
|
int cellnum = 0;
|
||||||
int startingRow = outputSheet.getLastRowNum();
|
int startingRow = outputSheet.getLastRowNum();
|
||||||
|
@ -283,8 +293,16 @@ public class DataSaving
|
||||||
row.createCell(cellnum++);
|
row.createCell(cellnum++);
|
||||||
}
|
}
|
||||||
try (FileOutputStream outputStream = new FileOutputStream(outputFile))
|
try (FileOutputStream outputStream = new FileOutputStream(outputFile))
|
||||||
{ outputWorkbook.write(outputStream); output = true; }
|
{
|
||||||
catch(Exception e) {ErrorLogging.logError(e);}
|
outputWorkbook.write(outputStream);
|
||||||
|
output = true;
|
||||||
|
ErrorLogging.logError("DEBUG: Writing values to Excel sheet was successful.");
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: Writing values to Excel sheet failed!");
|
||||||
|
ErrorLogging.logError(e);
|
||||||
|
}
|
||||||
updateFormulas(cameraNames.size());
|
updateFormulas(cameraNames.size());
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,11 +39,24 @@ public class MovementFacade
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Amount of distance to travel.
|
* Amount of distance to travel.
|
||||||
* Measured in... seemingly arbitrary units? Not sure on the math here.
|
* Measured in polls (~10ms intervals currently)
|
||||||
* Set in {@link #findDistance()}
|
* Set in {@link #findDistance()}
|
||||||
*/
|
*/
|
||||||
private static double TRAVEL_DIST;
|
private static double TRAVEL_DIST;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How many milliseconds to wait before polling the GPIO
|
||||||
|
*/
|
||||||
|
private static final int POLL_WAIT = 10;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How many polls before assuming bad GPIO connection.
|
||||||
|
* Fixture movement takes approximately 2.5s, or 250 polls.
|
||||||
|
* Double this to account for errors, or slower fixtures.
|
||||||
|
*/
|
||||||
|
private static final int TIMEOUT = 500;
|
||||||
|
|
||||||
|
|
||||||
//PWM Addresses
|
//PWM Addresses
|
||||||
//All addresses are in BCM format.
|
//All addresses are in BCM format.
|
||||||
|
|
||||||
|
@ -77,11 +90,6 @@ public class MovementFacade
|
||||||
*/
|
*/
|
||||||
private static final int LOWER_LIMIT_ADDR = 24;
|
private static final int LOWER_LIMIT_ADDR = 24;
|
||||||
|
|
||||||
/**
|
|
||||||
* How many milliseconds to wait before polling the GPIO
|
|
||||||
*/
|
|
||||||
private static final int POLL_WAIT = 10;
|
|
||||||
|
|
||||||
//Pi GPIO pin objects
|
//Pi GPIO pin objects
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -149,8 +157,32 @@ public class MovementFacade
|
||||||
*/
|
*/
|
||||||
private static Context pi4j;
|
private static Context pi4j;
|
||||||
|
|
||||||
static
|
public static void init() throws Exception
|
||||||
{
|
{
|
||||||
|
pi4j = Pi4J.newAutoContext();
|
||||||
|
|
||||||
|
ErrorLogging.logError("DEBUG: Opening input GPIO pins...");
|
||||||
|
upperLimit = inputBuilder(UPPER_LIMIT_ADDR);
|
||||||
|
lowerLimit = inputBuilder(LOWER_LIMIT_ADDR);
|
||||||
|
runSwitch = inputBuilder(RUN_SWITCH_ADDR);
|
||||||
|
|
||||||
|
ErrorLogging.logError("DEBUG: Opening output GPIO pins...");
|
||||||
|
motorEnable = outputBuilder(MOTOR_ENABLE_ADDR);
|
||||||
|
motorDirection = outputBuilder(MOTOR_DIRECTION_ADDR);
|
||||||
|
pistonActivate = outputBuilder(PISTON_ADDR);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
findDistance();
|
||||||
|
pressButton();
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
ErrorLogging.logError(e);
|
||||||
|
pi4j.shutdown();
|
||||||
|
throw new Exception("GPIO init error!!! Check GPIO connections.");
|
||||||
|
}
|
||||||
|
|
||||||
ErrorLogging.logError("DEBUG: Starting lock thread...");
|
ErrorLogging.logError("DEBUG: Starting lock thread...");
|
||||||
runSwitchThread = new Thread(() ->
|
runSwitchThread = new Thread(() ->
|
||||||
{
|
{
|
||||||
|
@ -175,17 +207,6 @@ public class MovementFacade
|
||||||
}, "Run switch monitor.");
|
}, "Run switch monitor.");
|
||||||
runSwitchThread.start();
|
runSwitchThread.start();
|
||||||
|
|
||||||
pi4j = Pi4J.newAutoContext();
|
|
||||||
|
|
||||||
upperLimit = inputBuilder(UPPER_LIMIT_ADDR);
|
|
||||||
lowerLimit = inputBuilder(LOWER_LIMIT_ADDR);
|
|
||||||
runSwitch = inputBuilder(RUN_SWITCH_ADDR);
|
|
||||||
|
|
||||||
motorEnable = outputBuilder(MOTOR_ENABLE_ADDR);
|
|
||||||
motorDirection = outputBuilder(MOTOR_DIRECTION_ADDR);
|
|
||||||
pistonActivate = outputBuilder(PISTON_ADDR);
|
|
||||||
|
|
||||||
findDistance();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -230,27 +251,23 @@ public class MovementFacade
|
||||||
public static int resetArm()
|
public static int resetArm()
|
||||||
{
|
{
|
||||||
ErrorLogging.logError("DEBUG: --------------------------------------");
|
ErrorLogging.logError("DEBUG: --------------------------------------");
|
||||||
|
ErrorLogging.logError("DEBUG: Resetting arm...");
|
||||||
int counter;
|
int counter;
|
||||||
ErrorLogging.logError("DEBUG: Setting minimum frequency of PWM...");
|
|
||||||
if(upperLimit.isHigh())
|
if(upperLimit.isHigh())
|
||||||
{
|
{
|
||||||
ErrorLogging.logError("DEBUG: Motor at highest point! Lowering to reset.");
|
ErrorLogging.logError("DEBUG: Motor at highest point! Lowering to reset.");
|
||||||
motorDirection.low();
|
motorDirectionDown();
|
||||||
ErrorLogging.logError("DEBUG: Motor offset on.");
|
motorOn();
|
||||||
motorEnable.on();
|
|
||||||
try{ Thread.sleep(500); }
|
try{ Thread.sleep(500); }
|
||||||
catch (Exception e){ ErrorLogging.logError(e); }
|
catch (Exception e){ ErrorLogging.logError(e); }
|
||||||
motorEnable.off();
|
motorOff();
|
||||||
ErrorLogging.logError("DEBUG: Motor offset off.");
|
|
||||||
}
|
}
|
||||||
ErrorLogging.logError("DEBUG: Moving motor to highest point.");
|
ErrorLogging.logError("DEBUG: Moving motor to highest point.");
|
||||||
motorDirection.high();
|
motorDirectionUp();
|
||||||
|
|
||||||
ErrorLogging.logError("DEBUG: Motor return on.");
|
motorOn();
|
||||||
motorEnable.on();
|
|
||||||
|
|
||||||
ErrorLogging.logError("DEBUG: Is the upper limit switch reached? " + upperLimit.isHigh());
|
for(counter = 0; counter < TIMEOUT; counter++)
|
||||||
for(counter = 0; counter < Integer.MAX_VALUE; counter++)
|
|
||||||
{
|
{
|
||||||
try{ Thread.sleep(POLL_WAIT); } catch(Exception e){ ErrorLogging.logError(e); }
|
try{ Thread.sleep(POLL_WAIT); } catch(Exception e){ ErrorLogging.logError(e); }
|
||||||
if(upperLimit.isOn())
|
if(upperLimit.isOn())
|
||||||
|
@ -259,23 +276,33 @@ public class MovementFacade
|
||||||
if(upperLimit.isOn()) break;
|
if(upperLimit.isOn()) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
motorEnable.off();
|
motorOff();
|
||||||
ErrorLogging.logError("DEBUG: Motor returned after " + counter + " polls.");
|
if(counter < TIMEOUT)
|
||||||
ErrorLogging.logError("DEBUG: --------------------------------------");
|
{
|
||||||
return counter;
|
ErrorLogging.logError("DEBUG: Motor returned after " + counter + " polls.");
|
||||||
|
ErrorLogging.logError("DEBUG: --------------------------------------");
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: No motor return after 30 seconds.");
|
||||||
|
ErrorLogging.logError("DEBUG: --------------------------------------");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to programmatically find the distance between the upper and lower limit switches.
|
* Used to programmatically find the distance between the upper and lower limit switches.
|
||||||
*/
|
*/
|
||||||
private static void findDistance()
|
private static void findDistance() throws Exception
|
||||||
{
|
{
|
||||||
resetArm();
|
ErrorLogging.logError("DEBUG: Measuring travel time to buttons...");
|
||||||
|
int safeGPIO = resetArm();
|
||||||
|
if(safeGPIO < 0) throw new Exception("Failed GPIO initialisation!");
|
||||||
int downTravelCounter = 0;
|
int downTravelCounter = 0;
|
||||||
int upTravelCounter = 0;
|
int upTravelCounter = 0;
|
||||||
//pwm.on(DUTY_CYCLE, MIN_FREQUENCY);
|
motorDirectionDown();
|
||||||
motorDirection.low();
|
motorOn();
|
||||||
motorEnable.on();
|
|
||||||
for(downTravelCounter = 0; downTravelCounter < Integer.MAX_VALUE; downTravelCounter++)
|
for(downTravelCounter = 0; downTravelCounter < Integer.MAX_VALUE; downTravelCounter++)
|
||||||
{
|
{
|
||||||
try{ Thread.sleep(POLL_WAIT); } catch(Exception e){ ErrorLogging.logError(e); }
|
try{ Thread.sleep(POLL_WAIT); } catch(Exception e){ ErrorLogging.logError(e); }
|
||||||
|
@ -285,13 +312,13 @@ public class MovementFacade
|
||||||
if(lowerLimit.isOn()) break;
|
if(lowerLimit.isOn()) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
motorEnable.off();
|
motorOff();
|
||||||
if(lowerLimit.isOff()) ErrorLogging.logError("DEBUG: False positive on findDistance down!");
|
if(lowerLimit.isOff()) ErrorLogging.logError("DEBUG: False positive on findDistance down!");
|
||||||
|
|
||||||
ErrorLogging.logError("DEBUG: Down travel count: " + downTravelCounter);
|
ErrorLogging.logError("DEBUG: Down travel count: " + downTravelCounter);
|
||||||
|
|
||||||
motorDirection.high();
|
motorDirectionUp();
|
||||||
motorEnable.on();
|
motorOn();
|
||||||
for(upTravelCounter = 0; upTravelCounter < Integer.MAX_VALUE; upTravelCounter++)
|
for(upTravelCounter = 0; upTravelCounter < Integer.MAX_VALUE; upTravelCounter++)
|
||||||
{
|
{
|
||||||
try{ Thread.sleep(POLL_WAIT); } catch(Exception e){ ErrorLogging.logError(e); }
|
try{ Thread.sleep(POLL_WAIT); } catch(Exception e){ ErrorLogging.logError(e); }
|
||||||
|
@ -301,7 +328,7 @@ public class MovementFacade
|
||||||
if(upperLimit.isOn()) break;
|
if(upperLimit.isOn()) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
motorEnable.off();
|
motorOff();
|
||||||
if(upperLimit.isOff()) ErrorLogging.logError("DEBUG: False positive on findDistance up!");
|
if(upperLimit.isOff()) ErrorLogging.logError("DEBUG: False positive on findDistance up!");
|
||||||
|
|
||||||
ErrorLogging.logError("DEBUG: Up travel count: " + downTravelCounter);
|
ErrorLogging.logError("DEBUG: Up travel count: " + downTravelCounter);
|
||||||
|
@ -327,15 +354,13 @@ public class MovementFacade
|
||||||
DigitalInput limitSense;
|
DigitalInput limitSense;
|
||||||
if(moveUp)
|
if(moveUp)
|
||||||
{
|
{
|
||||||
motorDirection.high();
|
motorDirectionUp();
|
||||||
limitSense = upperLimit;
|
limitSense = upperLimit;
|
||||||
ErrorLogging.logError("DEBUG: Sending fixture up...");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
motorDirection.low();
|
motorDirectionDown();
|
||||||
limitSense = lowerLimit;
|
limitSense = lowerLimit;
|
||||||
ErrorLogging.logError("DEBUG: Sending fixture down...");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(limitSense.isOn()) return FinalState.SAFE;
|
if(limitSense.isOn()) return FinalState.SAFE;
|
||||||
|
@ -346,17 +371,17 @@ public class MovementFacade
|
||||||
ErrorLogging.logError("DEBUG: Travel time: " + totalPollCount);
|
ErrorLogging.logError("DEBUG: Travel time: " + totalPollCount);
|
||||||
ErrorLogging.logError("DEBUG: High speed poll count: " + highSpeedPolls);
|
ErrorLogging.logError("DEBUG: High speed poll count: " + highSpeedPolls);
|
||||||
ErrorLogging.logError("DEBUG: =============================");
|
ErrorLogging.logError("DEBUG: =============================");
|
||||||
motorEnable.on();
|
motorOn();
|
||||||
for(int i = 0; i < highSpeedPolls; i++)
|
for(int i = 0; i < highSpeedPolls; i++)
|
||||||
{
|
{
|
||||||
try{ Thread.sleep(POLL_WAIT); } catch(Exception e){ ErrorLogging.logError(e); }
|
try{ Thread.sleep(POLL_WAIT); } catch(Exception e){ ErrorLogging.logError(e); }
|
||||||
if(limitSense.isOn())
|
if(limitSense.isOn())
|
||||||
{
|
{
|
||||||
motorEnable.off();
|
motorOff();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
motorEnable.off();
|
motorOff();
|
||||||
|
|
||||||
output = (limitSense.isOn() ? FinalState.UNSAFE : FinalState.SAFE);
|
output = (limitSense.isOn() ? FinalState.UNSAFE : FinalState.SAFE);
|
||||||
|
|
||||||
|
@ -417,6 +442,33 @@ public class MovementFacade
|
||||||
pressButton();
|
pressButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void motorOn()
|
||||||
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: Motor on.");
|
||||||
|
motorEnable.on();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void motorOff()
|
||||||
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: Motor off.");
|
||||||
|
motorEnable.off();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void motorDirectionUp()
|
||||||
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: Motor travelling up.");
|
||||||
|
motorDirection.high();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void motorDirectionDown()
|
||||||
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: Motor travelling down.");
|
||||||
|
motorDirection.low();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Possible states for motor control movement.
|
||||||
|
*/
|
||||||
public enum FinalState
|
public enum FinalState
|
||||||
{ UNSAFE, SAFE, FAILED; }
|
{ UNSAFE, SAFE, FAILED; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -155,6 +156,7 @@ public class OpenCVFacade
|
||||||
*/
|
*/
|
||||||
private static Mat takePicture(String cameraName)
|
private static Mat takePicture(String cameraName)
|
||||||
{
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: Taking picture...");
|
||||||
Mat output = null;
|
Mat output = null;
|
||||||
Frame temp = null;
|
Frame temp = null;
|
||||||
|
|
||||||
|
@ -162,12 +164,16 @@ public class OpenCVFacade
|
||||||
{
|
{
|
||||||
try{ temp = cameraMap.get(cameraName).grab(); }
|
try{ temp = cameraMap.get(cameraName).grab(); }
|
||||||
catch(Exception e) { ErrorLogging.logError(e); }
|
catch(Exception e) { ErrorLogging.logError(e); }
|
||||||
}
|
|
||||||
|
|
||||||
//Convert to grayscale
|
//Convert to grayscale
|
||||||
Mat in = MAT_CONVERTER.convertToMat(temp);
|
Mat in = MAT_CONVERTER.convertToMat(temp);
|
||||||
output = MAT_CONVERTER.convertToMat(temp);
|
output = MAT_CONVERTER.convertToMat(temp);
|
||||||
cvtColor(in,output,CV_BGR2GRAY);
|
cvtColor(in,output,CV_BGR2GRAY);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: Invalid camera!");
|
||||||
|
}
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
@ -181,6 +187,7 @@ public class OpenCVFacade
|
||||||
*/
|
*/
|
||||||
public static File showImage(String cameraName)
|
public static File showImage(String cameraName)
|
||||||
{
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: Showing preview...");
|
||||||
File imageLocation = completeProcess(cameraName,ConfigFacade.getImgSaveLocation() + "/config");
|
File imageLocation = completeProcess(cameraName,ConfigFacade.getImgSaveLocation() + "/config");
|
||||||
if(imageLocation == null) return null;
|
if(imageLocation == null) return null;
|
||||||
Frame outputImage = MAT_CONVERTER.convert(imread(imageLocation.getAbsolutePath()));
|
Frame outputImage = MAT_CONVERTER.convert(imread(imageLocation.getAbsolutePath()));
|
||||||
|
@ -213,6 +220,7 @@ public class OpenCVFacade
|
||||||
*/
|
*/
|
||||||
private static List<Mat> takeBurst(String cameraName, int frameCount)
|
private static List<Mat> takeBurst(String cameraName, int frameCount)
|
||||||
{
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: Taking burst of " + frameCount + " images...");
|
||||||
List<Mat> output = null;
|
List<Mat> output = null;
|
||||||
if(getCameraNames().contains(cameraName))
|
if(getCameraNames().contains(cameraName))
|
||||||
{
|
{
|
||||||
|
@ -222,6 +230,10 @@ public class OpenCVFacade
|
||||||
output.add(takePicture(cameraName));
|
output.add(takePicture(cameraName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: Invalid camera!");
|
||||||
|
}
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,21 +245,25 @@ public class OpenCVFacade
|
||||||
public static void setCrop(String cameraName)
|
public static void setCrop(String cameraName)
|
||||||
{
|
{
|
||||||
Mat uncroppedImage = takePicture(cameraName);
|
Mat uncroppedImage = takePicture(cameraName);
|
||||||
Rect roi = selectROI("Pick Crop Location", uncroppedImage);
|
if(uncroppedImage != null)
|
||||||
if(roi.x() == 0 && roi.y() == 0 && roi.width() == 0 && roi.height() == 0)
|
|
||||||
{
|
{
|
||||||
ErrorLogging.logError("Crop error! - Invalid crop selection.");
|
ErrorLogging.logError("DEBUG: Allowing user to modify crop.");
|
||||||
ErrorLogging.logError("If the crop region did not have a box indicating is location, please restart the program.");
|
Rect roi = selectROI("Pick Crop Location", uncroppedImage);
|
||||||
ConfigFacade.setValue(cameraName,ConfigProperties.CROP_X,ConfigProperties.CROP_X.getDefaultValue());
|
if(roi.x() == 0 && roi.y() == 0 && roi.width() == 0 && roi.height() == 0)
|
||||||
ConfigFacade.setValue(cameraName,ConfigProperties.CROP_Y,ConfigProperties.CROP_Y.getDefaultValue());
|
{
|
||||||
ConfigFacade.setValue(cameraName,ConfigProperties.CROP_W,ConfigProperties.CROP_W.getDefaultValue());
|
ErrorLogging.logError("Crop error! - Invalid crop selection.");
|
||||||
ConfigFacade.setValue(cameraName,ConfigProperties.CROP_H,ConfigProperties.CROP_H.getDefaultValue());
|
ErrorLogging.logError("If the crop region did not have a box indicating is location, please restart the program.");
|
||||||
return;
|
ConfigFacade.setValue(cameraName,ConfigProperties.CROP_X,ConfigProperties.CROP_X.getDefaultValue());
|
||||||
|
ConfigFacade.setValue(cameraName,ConfigProperties.CROP_Y,ConfigProperties.CROP_Y.getDefaultValue());
|
||||||
|
ConfigFacade.setValue(cameraName,ConfigProperties.CROP_W,ConfigProperties.CROP_W.getDefaultValue());
|
||||||
|
ConfigFacade.setValue(cameraName,ConfigProperties.CROP_H,ConfigProperties.CROP_H.getDefaultValue());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ConfigFacade.setValue(cameraName,ConfigProperties.CROP_X, roi.x());
|
||||||
|
ConfigFacade.setValue(cameraName,ConfigProperties.CROP_Y, roi.y());
|
||||||
|
ConfigFacade.setValue(cameraName,ConfigProperties.CROP_W, roi.width());
|
||||||
|
ConfigFacade.setValue(cameraName,ConfigProperties.CROP_H, roi.height());
|
||||||
}
|
}
|
||||||
ConfigFacade.setValue(cameraName,ConfigProperties.CROP_X, roi.x());
|
|
||||||
ConfigFacade.setValue(cameraName,ConfigProperties.CROP_Y, roi.y());
|
|
||||||
ConfigFacade.setValue(cameraName,ConfigProperties.CROP_W, roi.width());
|
|
||||||
ConfigFacade.setValue(cameraName,ConfigProperties.CROP_H, roi.height());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -322,6 +338,7 @@ public class OpenCVFacade
|
||||||
*/
|
*/
|
||||||
private static File saveImage(Mat image, String fileLocation, String cameraName)
|
private static File saveImage(Mat image, String fileLocation, String cameraName)
|
||||||
{
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: Saving image from " + cameraName + " to " + fileLocation);
|
||||||
File output = null;
|
File output = null;
|
||||||
IplImage temp = MAT_CONVERTER.convertToIplImage(MAT_CONVERTER.convert(image));
|
IplImage temp = MAT_CONVERTER.convertToIplImage(MAT_CONVERTER.convert(image));
|
||||||
fileLocation = fileLocation + "/" + ErrorLogging.fileDatetime.format(LocalDateTime.now()) + "-" + cameraName + ".png";
|
fileLocation = fileLocation + "/" + ErrorLogging.fileDatetime.format(LocalDateTime.now()) + "-" + cameraName + ".png";
|
||||||
|
@ -337,30 +354,21 @@ public class OpenCVFacade
|
||||||
* from {@link ConfigFacade}.
|
* from {@link ConfigFacade}.
|
||||||
*
|
*
|
||||||
* @param images List of images to be composed
|
* @param images List of images to be composed
|
||||||
* @param threshold Whether to put the image through a binary threshold
|
|
||||||
* @param crop Whether to crop the image
|
|
||||||
* @param cameraName Name of the camera the images came from (used to determine crop sizing and threshold value)
|
|
||||||
*
|
|
||||||
* @return A single image, found by boolean AND-ing together all parsed images.
|
* @return A single image, found by boolean AND-ing together all parsed images.
|
||||||
*/
|
*/
|
||||||
private static Mat compose(List<Mat> images, boolean threshold,
|
private static Mat compose(List<Mat> images)
|
||||||
boolean crop, String cameraName)
|
|
||||||
{
|
{
|
||||||
ErrorLogging.logError("DEBUG: Attempting to compose " + images.size() + " images...");
|
ErrorLogging.logError("DEBUG: Attempting to compose " + images.size() + " images...");
|
||||||
Mat output = null;
|
Mat output = null;
|
||||||
int iterationCount = 1;
|
|
||||||
for(Mat image : images)
|
for(Mat image : images)
|
||||||
{
|
{
|
||||||
Mat processedImage = image.clone();
|
Mat processedImage = image.clone();
|
||||||
image.copyTo(processedImage);
|
image.copyTo(processedImage);
|
||||||
if(crop) processedImage = crop(processedImage,cameraName);
|
|
||||||
if(threshold) processedImage = thresholdImage(processedImage,cameraName);
|
|
||||||
|
|
||||||
if(iterationCount == 1) output = processedImage.clone();
|
if(output == null) output = processedImage.clone();
|
||||||
|
|
||||||
bitwise_and((iterationCount == 1 ? processedImage : output),processedImage, output);
|
bitwise_and(output,processedImage, output);
|
||||||
|
|
||||||
iterationCount++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(output != null) ErrorLogging.logError("DEBUG: Compositing successful!");
|
if(output != null) ErrorLogging.logError("DEBUG: Compositing successful!");
|
||||||
|
@ -391,8 +399,32 @@ public class OpenCVFacade
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
List<Mat> imageList = takeBurst(cameraName, compositeFrames);
|
List<Mat> imageList = takeBurst(cameraName, compositeFrames);
|
||||||
|
List<Mat> processedImageList = new ArrayList<>();
|
||||||
|
|
||||||
Mat finalImage = compose(imageList, threshold, crop, cameraName);
|
Mat finalImage = null;
|
||||||
|
if(crop) ErrorLogging.logError("Cropping is enabled.");
|
||||||
|
if(threshold) ErrorLogging.logError("Thresholding is enabled.");
|
||||||
|
for(Mat image : imageList)
|
||||||
|
{
|
||||||
|
Mat processedImage = image.clone();
|
||||||
|
image.copyTo(processedImage);
|
||||||
|
|
||||||
|
if(crop)
|
||||||
|
processedImage = crop(processedImage,cameraName);
|
||||||
|
|
||||||
|
if(threshold)
|
||||||
|
processedImage = thresholdImage(processedImage,cameraName);
|
||||||
|
|
||||||
|
if(finalImage == null)
|
||||||
|
finalImage = processedImage.clone();
|
||||||
|
|
||||||
|
processedImageList.add(processedImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(compositeFrames > 1)
|
||||||
|
finalImage = compose(processedImageList);
|
||||||
|
|
||||||
|
//Mat finalImage = compose(imageList, threshold, crop, cameraName);
|
||||||
output = saveImage(finalImage, saveLocation,cameraName);
|
output = saveImage(finalImage, saveLocation,cameraName);
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,6 +101,7 @@ public class TesseractFacade
|
||||||
else ErrorLogging.logError("OCR ERROR!!! - OCR output is not a Double.");
|
else ErrorLogging.logError("OCR ERROR!!! - OCR output is not a Double.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else { ErrorLogging.logError("OCR Failed to retrieve information!"); }
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue