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>
|
||||
<artifactId>ocr</artifactId>
|
||||
<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>
|
||||
<organization>
|
||||
<name>Baxter International</name>
|
||||
|
|
2
pom.xml
2
pom.xml
|
@ -3,7 +3,7 @@
|
|||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.baxter.disco</groupId>
|
||||
<artifactId>ocr</artifactId>
|
||||
<version>4.3.5</version>
|
||||
<version>4.3.6</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>Disco OCR Accuracy Over Life Testing</name>
|
||||
<description>Testing Discos for long-term accuracy, using automated optical character recognition.</description>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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; }
|
||||
}
|
||||
|
|
|
@ -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<ConfigProperties,Double> 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<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.
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue