Remove hardcoded camera locations
also: - Temporarily comment out CLI menu to make movement testing faster - remove movement from config
This commit is contained in:
parent
fb79023fd4
commit
cd0be06a9f
7 changed files with 179 additions and 300 deletions
|
@ -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.5</version>
|
<version>4.3.6</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>
|
||||||
|
|
2
pom.xml
2
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.5</version>
|
<version>4.3.6</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>
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
#! /usr/bin/env sh
|
#! /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
|
||||||
|
|
|
@ -18,14 +18,14 @@ import java.util.concurrent.locks.ReentrantLock;
|
||||||
* classes).
|
* classes).
|
||||||
*
|
*
|
||||||
* @author Blizzard Finnegan
|
* @author Blizzard Finnegan
|
||||||
* @version 1.6.1, 10 Feb. 2023
|
* @version 1.7.0, 06 Mar. 2023
|
||||||
*/
|
*/
|
||||||
public class Cli
|
public class Cli
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Complete build version number
|
* Complete build version number
|
||||||
*/
|
*/
|
||||||
private static final String version = "4.3.5";
|
private static final String version = "4.3.6";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Currently saved iteration count.
|
* Currently saved iteration count.
|
||||||
|
@ -55,11 +55,6 @@ public class Cli
|
||||||
*/
|
*/
|
||||||
private static final int mainMenuOptionCount = 7;
|
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.
|
* Number of options currently available in the camera configuration sub-menu.
|
||||||
*/
|
*/
|
||||||
|
@ -90,70 +85,71 @@ public class Cli
|
||||||
|
|
||||||
ConfigFacade.init();
|
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();
|
MovementFacade.calibrate();
|
||||||
|
|
||||||
do
|
//do
|
||||||
{
|
//{
|
||||||
printMainMenu();
|
// printMainMenu();
|
||||||
userInput = (int)inputFiltering(inputScanner.nextLine());
|
// userInput = (int)inputFiltering(inputScanner.nextLine());
|
||||||
|
|
||||||
switch (userInput)
|
// switch (userInput)
|
||||||
{
|
// {
|
||||||
case 1:
|
// case 1:
|
||||||
println("Setting up cameras...");
|
// println("Setting up cameras...");
|
||||||
println("This may take a moment...");
|
// println("This may take a moment...");
|
||||||
configureCameras();
|
// configureCameras();
|
||||||
camerasConfigured = true;
|
// camerasConfigured = true;
|
||||||
break;
|
// break;
|
||||||
case 2:
|
// case 2:
|
||||||
setDUTSerials();
|
// setDUTSerials();
|
||||||
break;
|
// break;
|
||||||
case 3:
|
// case 3:
|
||||||
setIterationCount();
|
// setIterationCount();
|
||||||
break;
|
// break;
|
||||||
case 4:
|
// case 4:
|
||||||
setActiveCameras();
|
// setActiveCameras();
|
||||||
break;
|
// break;
|
||||||
case 5:
|
// case 5:
|
||||||
if(!camerasConfigured)
|
// if(!camerasConfigured)
|
||||||
{
|
// {
|
||||||
prompt("You have not configured the cameras yet! Are you sure you would like to continue? (y/N): ");
|
// prompt("You have not configured the cameras yet! Are you sure you would like to continue? (y/N): ");
|
||||||
String input = inputScanner.nextLine().toLowerCase().trim();
|
// String input = inputScanner.nextLine().toLowerCase().trim();
|
||||||
if( input.isBlank() || input.charAt(0) != 'y' ) break;
|
// if( input.isBlank() || input.charAt(0) != 'y' ) break;
|
||||||
else
|
// else
|
||||||
ErrorLogging.logError("DEBUG: Potential for error: Un-initialised cameras.");
|
// ErrorLogging.logError("DEBUG: Potential for error: Un-initialised cameras.");
|
||||||
}
|
// }
|
||||||
|
|
||||||
serialsSet = true;
|
// serialsSet = true;
|
||||||
for(String cameraName : OpenCVFacade.getCameraNames())
|
// for(String cameraName : OpenCVFacade.getCameraNames())
|
||||||
{
|
// {
|
||||||
if(ConfigFacade.getValue(cameraName,ConfigProperties.ACTIVE) != 0 &&
|
// if(ConfigFacade.getValue(cameraName,ConfigProperties.ACTIVE) != 0 &&
|
||||||
ConfigFacade.getSerial(cameraName) == null )
|
// ConfigFacade.getSerial(cameraName) == null )
|
||||||
serialsSet = false;
|
// serialsSet = false;
|
||||||
}
|
// }
|
||||||
if(!serialsSet)
|
// if(!serialsSet)
|
||||||
{
|
// {
|
||||||
prompt("You have not set the serial numbers for your DUTs yet! Are you sure you would like to continue? (y/N): ");
|
// 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();
|
// String input = inputScanner.nextLine().toLowerCase().trim();
|
||||||
if( input.isBlank() || input.charAt(0) != 'y' ) break;
|
// if( input.isBlank() || input.charAt(0) != 'y' ) break;
|
||||||
else
|
// else
|
||||||
ErrorLogging.logError("DEBUG: Potential for error: Un-initialised DUT Serial numbers.");
|
// ErrorLogging.logError("DEBUG: Potential for error: Un-initialised DUT Serial numbers.");
|
||||||
}
|
// }
|
||||||
|
|
||||||
runTests();
|
// runTests();
|
||||||
break;
|
// break;
|
||||||
case 6:
|
// case 6:
|
||||||
printHelp();
|
// printHelp();
|
||||||
break;
|
// break;
|
||||||
case 8:
|
// case 8:
|
||||||
break;
|
// break;
|
||||||
default:
|
// default:
|
||||||
//Input handling already done by inputFiltering()
|
// //Input handling already done by inputFiltering()
|
||||||
}
|
// }
|
||||||
|
|
||||||
} while (userInput != mainMenuOptionCount);
|
//} while (userInput != mainMenuOptionCount);
|
||||||
|
|
||||||
}
|
}
|
||||||
//If anything ever goes wrong, catch the error and exit
|
//If anything ever goes wrong, catch the error and exit
|
||||||
|
@ -261,27 +257,6 @@ public class Cli
|
||||||
println("======================================");
|
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
|
* Pre-defined method for printing all available cameras in a menu
|
||||||
*/
|
*/
|
||||||
|
@ -367,97 +342,6 @@ public class Cli
|
||||||
println("====================================");
|
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.
|
* Sub-function used to configure cameras.
|
||||||
*/
|
*/
|
||||||
|
@ -802,7 +686,9 @@ public class Cli
|
||||||
*/
|
*/
|
||||||
private static void close()
|
private static void close()
|
||||||
{
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: =================");
|
||||||
ErrorLogging.logError("DEBUG: PROGRAM CLOSING.");
|
ErrorLogging.logError("DEBUG: PROGRAM CLOSING.");
|
||||||
|
ErrorLogging.logError("DEBUG: =================");
|
||||||
if(inputScanner != null) inputScanner.close();
|
if(inputScanner != null) inputScanner.close();
|
||||||
MovementFacade.closeGPIO();
|
MovementFacade.closeGPIO();
|
||||||
ErrorLogging.logError("DEBUG: END OF PROGRAM.");
|
ErrorLogging.logError("DEBUG: END OF PROGRAM.");
|
||||||
|
@ -852,13 +738,6 @@ public class Cli
|
||||||
output = -1;
|
output = -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MOVEMENT:
|
|
||||||
if(output > movementMenuOptionCount)
|
|
||||||
{
|
|
||||||
invalidMovementMenuInput();
|
|
||||||
output = -1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CAMERA:
|
case CAMERA:
|
||||||
if(output > cameraMenuOptionCount)
|
if(output > cameraMenuOptionCount)
|
||||||
{
|
{
|
||||||
|
@ -881,14 +760,6 @@ public class Cli
|
||||||
invalidMenuInput(mainMenuOptionCount);
|
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.
|
* Prints a message when user inputs an invalid main menu value.
|
||||||
*/
|
*/
|
||||||
|
@ -939,5 +810,5 @@ public class Cli
|
||||||
/**
|
/**
|
||||||
* Enum of possible menus available
|
* Enum of possible menus available
|
||||||
*/
|
*/
|
||||||
private enum Menus { MAIN,MOVEMENT,CAMERA,OTHER; }
|
private enum Menus { MAIN,CAMERA,OTHER; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,11 +11,9 @@ import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
//Apache Commons Configuration imports
|
//Apache Commons Configuration imports
|
||||||
import org.apache.commons.configuration2.INIConfiguration;
|
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.FileBasedConfigurationBuilder;
|
||||||
import org.apache.commons.configuration2.builder.fluent.Parameters;
|
import org.apache.commons.configuration2.builder.fluent.Parameters;
|
||||||
|
|
||||||
|
@ -280,6 +278,7 @@ public class ConfigFacade
|
||||||
//**********************************************
|
//**********************************************
|
||||||
//SAVE AND LOAD SETTINGS
|
//SAVE AND LOAD SETTINGS
|
||||||
//**********************************************
|
//**********************************************
|
||||||
|
//
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save current config to a user-defined file location.
|
* Save current config to a user-defined file location.
|
||||||
|
@ -436,22 +435,10 @@ public class ConfigFacade
|
||||||
for(String sectionName : configSections)
|
for(String sectionName : configSections)
|
||||||
{
|
{
|
||||||
Map<ConfigProperties,Double> savedSection = new HashMap<>();
|
Map<ConfigProperties,Double> savedSection = new HashMap<>();
|
||||||
String subSectionPrefix = "";
|
|
||||||
for(String cameraName : cameraNames)
|
for(String cameraName : cameraNames)
|
||||||
{
|
{
|
||||||
if(sectionName.equals(cameraName))
|
if(!sectionName.equals(cameraName))
|
||||||
{
|
{ saveSingleDefault(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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(ConfigProperties configState : ConfigProperties.values())
|
for(ConfigProperties configState : ConfigProperties.values())
|
||||||
|
@ -485,4 +472,34 @@ public class ConfigFacade
|
||||||
* @return true if loaded successfully, otherwise false
|
* @return true if loaded successfully, otherwise false
|
||||||
*/
|
*/
|
||||||
public static boolean loadConfig() { return loadConfig(configFileLocation); }
|
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<ConfigProperties,Double> 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,45 +20,19 @@ import com.pi4j.io.pwm.PwmType;
|
||||||
* Currently missing Run switch compatibility.
|
* Currently missing Run switch compatibility.
|
||||||
*
|
*
|
||||||
* @author Blizzard Finnegan
|
* @author Blizzard Finnegan
|
||||||
* @version 2.4.0, 01 Mar. 2023
|
* @version 3.0.0, 06 Mar. 2023
|
||||||
*/
|
*/
|
||||||
public class MovementFacade
|
public class MovementFacade
|
||||||
{
|
{
|
||||||
private static boolean exit = false;
|
|
||||||
/**
|
/**
|
||||||
* Constructor for MovementFacade.
|
* Boolean used to communicate with runSwitchThread to gracefully exit.
|
||||||
*
|
|
||||||
* @param LOCK A Lock object, used for interactions with
|
|
||||||
* the physical lock switch on the fixture.
|
|
||||||
*/
|
*/
|
||||||
//public MovementFacade(Lock LOCK)
|
private static boolean exit = false;
|
||||||
//{
|
|
||||||
// //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!");
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thread that watches the physical Run switch on the device so that
|
||||||
|
* fixture movement can be stopped.
|
||||||
|
*/
|
||||||
private static Thread runSwitchThread;
|
private static Thread runSwitchThread;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -74,11 +48,6 @@ public class MovementFacade
|
||||||
*/
|
*/
|
||||||
private static final int PWM_FREQ_CONVERT = 19200;
|
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.
|
* Max allowed speed by current fixture design.
|
||||||
* Motor appears to start acting erratically over 192kHz.
|
* Motor appears to start acting erratically over 192kHz.
|
||||||
|
@ -108,7 +77,14 @@ public class MovementFacade
|
||||||
*/
|
*/
|
||||||
private static final int TRAVEL_DIST = 30;
|
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;
|
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;
|
private static final double STEP_2 = 5/6;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -116,6 +92,9 @@ public class MovementFacade
|
||||||
*/
|
*/
|
||||||
private static double SPEED = MIN_SPEED;
|
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);
|
private static int FREQUENCY = (int)(SPEED * PWM_FREQ_CONVERT);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -254,7 +233,7 @@ public class MovementFacade
|
||||||
if(unlock)
|
if(unlock)
|
||||||
{ Cli.LOCK.unlock(); unlock = false; }
|
{ 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.");
|
}, "Run switch monitor.");
|
||||||
runSwitchThread.start();
|
runSwitchThread.start();
|
||||||
|
@ -273,11 +252,9 @@ public class MovementFacade
|
||||||
motorDirection = outputBuilder("motorDirection", "Motor Direction", MOTOR_DIRECTION_ADDR);
|
motorDirection = outputBuilder("motorDirection", "Motor Direction", MOTOR_DIRECTION_ADDR);
|
||||||
pistonActivate = outputBuilder("piston" , "Piston Activate", PISTON_ADDR);
|
pistonActivate = outputBuilder("piston" , "Piston Activate", PISTON_ADDR);
|
||||||
|
|
||||||
//Initialise PWM object. This object is never used,
|
//Initialise PWM object.
|
||||||
//as the PWM signal is simply a clock for the motor.
|
|
||||||
pwm = pwmBuilder("pwm","PWM Pin",PWM_PIN_ADDR);
|
pwm = pwmBuilder("pwm","PWM Pin",PWM_PIN_ADDR);
|
||||||
//pwm.on(DUTY_CYCLE, FREQUENCY);
|
//pwm.on(DUTY_CYCLE, FREQUENCY);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -378,27 +355,26 @@ public class MovementFacade
|
||||||
public static int resetArm()
|
public static int resetArm()
|
||||||
{
|
{
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
//ErrorLogging.logError("Setting minimum frequency of PWM...");
|
ErrorLogging.logError("DEBUG: Setting minimum frequency of PWM...");
|
||||||
//ErrorLogging.logError("Minimum frequency: " + MIN_FREQUENCY);
|
|
||||||
pwm.on(DUTY_CYCLE, MIN_FREQUENCY);
|
pwm.on(DUTY_CYCLE, MIN_FREQUENCY);
|
||||||
if(upperLimit.isHigh())
|
if(upperLimit.isHigh())
|
||||||
{
|
{
|
||||||
//ErrorLogging.logError("Motor at highest point! Lowering to reset.");
|
ErrorLogging.logError("DEBUG: Motor at highest point! Lowering to reset.");
|
||||||
motorDirection.low();
|
motorDirection.low();
|
||||||
//ErrorLogging.logError("Motor on!");
|
ErrorLogging.logError("DEBUG: Motor offset on.");
|
||||||
motorEnable.on();
|
motorEnable.on();
|
||||||
try{ Thread.sleep(500); }
|
try{ Thread.sleep(500); }
|
||||||
catch (Exception e){ ErrorLogging.logError(e); }
|
catch (Exception e){ ErrorLogging.logError(e); }
|
||||||
motorEnable.off();
|
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();
|
motorDirection.high();
|
||||||
|
|
||||||
//ErrorLogging.logError("Motor on!");
|
ErrorLogging.logError("DEBUG: Motor return on.");
|
||||||
motorEnable.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())
|
while(!upperLimit.isHigh())
|
||||||
{
|
{
|
||||||
try{ Thread.sleep(100); }
|
try{ Thread.sleep(100); }
|
||||||
|
@ -406,7 +382,7 @@ public class MovementFacade
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
motorEnable.off();
|
motorEnable.off();
|
||||||
//ErrorLogging.logError("Motor returned after " + counter + " polls.");
|
ErrorLogging.logError("DEBUG: Motor returned after " + counter + " polls.");
|
||||||
return counter;
|
return counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -418,10 +394,11 @@ public class MovementFacade
|
||||||
ErrorLogging.logError("Initial Calibration reset.");
|
ErrorLogging.logError("Initial Calibration reset.");
|
||||||
resetArm();
|
resetArm();
|
||||||
ErrorLogging.logError("Coarse calibrating...");
|
ErrorLogging.logError("Coarse calibrating...");
|
||||||
SPEED = calib(1, MAX_SPEED, 1);
|
SPEED = calib(3, MAX_SPEED, 1);
|
||||||
ErrorLogging.logError("Coarse calibrating...");
|
ErrorLogging.logError("Fine calibrating...");
|
||||||
SPEED = calib(SPEED,(SPEED+1),0.1);
|
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);
|
setSpeed(SPEED - SPEED_BUFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,39 +413,47 @@ public class MovementFacade
|
||||||
*/
|
*/
|
||||||
private static double calib(double start, double max, double iterate)
|
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)
|
for(double i = start; i < max; i+=iterate)
|
||||||
{
|
{
|
||||||
//ErrorLogging.logError("Testing speed " + i + "...");
|
ErrorLogging.logError("DEBUG: Testing speed " + i + "...");
|
||||||
if(!setSpeed(i))
|
if(!setSpeed(i))
|
||||||
{
|
{
|
||||||
//ErrorLogging.logError("Speed set unsuccessfully! returning " + MIN_SPEED + "...");
|
ErrorLogging.logError("DEBUG: Speed set unsuccessfully! returning " + MIN_SPEED + "...");
|
||||||
return MIN_SPEED;
|
return MIN_SPEED;
|
||||||
}
|
}
|
||||||
//ErrorLogging.logError("Motor travelling down.");
|
ErrorLogging.logError("DEBUG: Motor travelling down.");
|
||||||
motorDirection.low();
|
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();
|
motorEnable.on();
|
||||||
for(int j = 0; j < 5; j++)
|
for(int j = 0; j < 20; j++)
|
||||||
{
|
{
|
||||||
try{ Thread.sleep(100); }
|
try{ Thread.sleep(100); }
|
||||||
catch (Exception e){ ErrorLogging.logError(e); }
|
catch (Exception e){ ErrorLogging.logError(e); }
|
||||||
if(lowerLimit.isHigh()) break;
|
if(lowerLimit.isHigh())
|
||||||
|
{
|
||||||
|
ErrorLogging.logError("DEBUG: Breaking loop early!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
motorEnable.off();
|
motorEnable.off();
|
||||||
//ErrorLogging.logError("Motor off!");
|
ErrorLogging.logError("DEBUG: Motor calibrate off.");
|
||||||
if(upperLimit.isHigh())
|
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;
|
return i-iterate;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
//ErrorLogging.logError("Motor moved at speed " + i + ". Checking for errors.");
|
ErrorLogging.logError("DEBUG: Motor moved at speed " + i + ". Checking for errors.");
|
||||||
if(resetArm() < 10 && i > 1.0)
|
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;
|
return i - iterate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -496,6 +481,7 @@ public class MovementFacade
|
||||||
}
|
}
|
||||||
SPEED = newSpeed;
|
SPEED = newSpeed;
|
||||||
FREQUENCY = (int)(SPEED * PWM_FREQ_CONVERT);
|
FREQUENCY = (int)(SPEED * PWM_FREQ_CONVERT);
|
||||||
|
ErrorLogging.logError("DEBUG: Setting frequency to " + FREQUENCY);
|
||||||
pwm.on(DUTY_CYCLE, FREQUENCY);
|
pwm.on(DUTY_CYCLE, FREQUENCY);
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
@ -504,11 +490,9 @@ public class MovementFacade
|
||||||
* Internal function to send the fixture to a given limit switch.
|
* Internal function to send the fixture to a given limit switch.
|
||||||
*
|
*
|
||||||
* Detects if the limit switch is active before activating motor.
|
* Detects if the limit switch is active before activating motor.
|
||||||
*
|
* Motor movement is written to slow down at {@link #STEP_1} and {@link #STEP_2}
|
||||||
* 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 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
|
* @return true if movement was successful; otherwise false
|
||||||
*/
|
*/
|
||||||
private static FinalState gotoLimit(boolean moveUp)
|
private static FinalState gotoLimit(boolean moveUp)
|
||||||
|
@ -536,28 +520,28 @@ public class MovementFacade
|
||||||
int POLL_COUNT = TRAVEL_TIME * TIME_CONVERSION;
|
int POLL_COUNT = TRAVEL_TIME * TIME_CONVERSION;
|
||||||
int VEL_STEP_1 = (int)(STEP_1 * POLL_COUNT);
|
int VEL_STEP_1 = (int)(STEP_1 * POLL_COUNT);
|
||||||
int VEL_STEP_2 = (int)(STEP_2 * 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("DEBUG: Total Poll count: " + POLL_COUNT);
|
||||||
ErrorLogging.logError("Transition 1: " + VEL_STEP_1);
|
ErrorLogging.logError("DEBUG: Transition 1: " + VEL_STEP_1);
|
||||||
ErrorLogging.logError("Transition 2: " + VEL_STEP_2);
|
ErrorLogging.logError("DEBUG: Transition 2: " + VEL_STEP_2);
|
||||||
ErrorLogging.logError("Travel time: " + TRAVEL_TIME);
|
ErrorLogging.logError("DEBUG: Travel time: " + TRAVEL_TIME);
|
||||||
ErrorLogging.logError("Travel speed: " + SPEED);
|
ErrorLogging.logError("DEBUG: Travel speed: " + SPEED);
|
||||||
|
ErrorLogging.logError("DEBUG: STEP_1: " + STEP_1);
|
||||||
|
ErrorLogging.logError("DEBUG: STEP_2: " + STEP_2);
|
||||||
motorEnable.on();
|
motorEnable.on();
|
||||||
for(int i = 0; i < (POLL_COUNT);i++)
|
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); }
|
try{ Thread.sleep(POLL_WAIT); } catch(Exception e){ ErrorLogging.logError(e); }
|
||||||
if(i >= VEL_STEP_1 && i < VEL_STEP_2)
|
if(i >= VEL_STEP_1 && i < VEL_STEP_2)
|
||||||
{
|
{
|
||||||
output = FinalState.UNSAFE;
|
output = FinalState.UNSAFE;
|
||||||
ErrorLogging.logError("Slow down!");
|
ErrorLogging.logError("DEBUG: Slowing down.");
|
||||||
pwm.on(DUTY_CYCLE, FREQUENCY / 2);
|
pwm.on(DUTY_CYCLE, FREQUENCY / 2);
|
||||||
}
|
}
|
||||||
else if(i >= VEL_STEP_2)
|
else if(i >= VEL_STEP_2)
|
||||||
{
|
{
|
||||||
ErrorLogging.logError("Slow down more!");
|
ErrorLogging.logError("DEBUG: Slowing down more.");
|
||||||
pwm.on(DUTY_CYCLE, FREQUENCY / 4);
|
pwm.on(DUTY_CYCLE, FREQUENCY / 4);
|
||||||
output = FinalState.SAFE;
|
output = FinalState.SAFE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ import java.util.List;
|
||||||
* Performs image capture, as well as image manipulation.
|
* Performs image capture, as well as image manipulation.
|
||||||
*
|
*
|
||||||
* @author Blizzard Finnegan
|
* @author Blizzard Finnegan
|
||||||
* @version 2.0.1, 15 Feb. 2023
|
* @version 2.1.0, 06 Mar. 2023
|
||||||
*/
|
*/
|
||||||
public class OpenCVFacade
|
public class OpenCVFacade
|
||||||
{
|
{
|
||||||
|
@ -57,28 +57,35 @@ public class OpenCVFacade
|
||||||
* Width of the image created by the camera.
|
* Width of the image created by the camera.
|
||||||
* !!See camera documentation before modifying!!
|
* !!See camera documentation before modifying!!
|
||||||
*/
|
*/
|
||||||
private static final int IMG_WIDTH = 3264;
|
private static final int IMG_WIDTH = 800;
|
||||||
//Previously used code:
|
|
||||||
//private static final int IMG_WIDTH = 800;
|
|
||||||
/**
|
/**
|
||||||
* Height of the image created by the camera.
|
* Height of the image created by the camera.
|
||||||
* !!See camera documentation before modifying!!
|
* !!See camera documentation before modifying!!
|
||||||
*/
|
*/
|
||||||
private static final int IMG_HEIGHT = 2448;
|
private static final int IMG_HEIGHT = 600;
|
||||||
//Previously used code:
|
|
||||||
//private static final int IMG_HEIGHT = 600;
|
|
||||||
/**
|
/**
|
||||||
* FourCC code of the image created by the camera.
|
* FourCC code of the image created by the camera.
|
||||||
* !!See camera documentation before modifying!!
|
* !!See camera documentation before modifying!!
|
||||||
*/
|
*/
|
||||||
private static final String CAMERA_CODEC = "mjpg";
|
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
|
//Initial Camera creation
|
||||||
static
|
static
|
||||||
{
|
{
|
||||||
//Pis should already be configured to create this symlink.
|
File devDirectory = new File("/dev");
|
||||||
newCamera("left", "/dev/video-cam1");
|
for(File cameraFile : devDirectory.listFiles(
|
||||||
newCamera("right","/dev/video-cam2");
|
(file) -> { return file.getName().contains(CAMERA_FILE_PREFIX); }))
|
||||||
|
{
|
||||||
|
String cameraName = cameraFile.getName().
|
||||||
|
substring(CAMERA_FILE_PREFIX.length());
|
||||||
|
newCamera(cameraName, cameraFile.getAbsolutePath());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue