Add better motor movement safety

Motor now moves faster, but slows down when more than halfway through
timeout, so that limit switches aren't pushed as hard.
This commit is contained in:
Blizzard Finnegan 2023-02-28 11:26:54 -05:00
parent 99569154e9
commit 7b38d83366
No known key found for this signature in database
GPG key ID: DE547EDF547DDA49
6 changed files with 55 additions and 32 deletions

View file

@ -4,7 +4,7 @@
<groupId>org.baxter.disco</groupId>
<artifactId>ocr</artifactId>
<name>Disco OCR Accuracy Over Life Testing</name>
<version>4.3.3</version>
<version>4.3.4</version>
<description>Testing Discos for long-term accuracy, using automated optical character recognition.</description>
<organization>
<name>Baxter International</name>

View file

@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.baxter.disco</groupId>
<artifactId>ocr</artifactId>
<version>4.3.3</version>
<version>4.3.4</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>

View file

@ -1,2 +1,2 @@
#! /usr/bin/env sh
sudo java -jar discoTesting-4.3.3.jar 2>/dev/null
sudo java -jar discoTesting-4.3.4.jar 2>/dev/null

View file

@ -25,7 +25,7 @@ public class Cli
/**
* Complete build version number
*/
private static final String version = "4.3.3";
private static final String version = "4.3.4";
/**
* Currently saved iteration count.
@ -108,7 +108,7 @@ public class Cli
{
//Show the main menu, wait for user input
printMainMenu();
userInput = inputFiltering(inputScanner.nextLine());
userInput = (int)inputFiltering(inputScanner.nextLine());
//Perform action based on user input
switch (userInput)
@ -430,7 +430,7 @@ public class Cli
println("Testing movement...");
fixture.testMotions();
printMovementMenu();
userInput = inputFiltering(inputScanner.nextLine());
userInput = (int)inputFiltering(inputScanner.nextLine());
switch (userInput)
{
/*
@ -442,7 +442,7 @@ public class Cli
*/
case 1:
prompt("Input the desired duty cycle value: ");
int newDutyCycle = inputFiltering(inputScanner.nextLine());
int newDutyCycle = (int)inputFiltering(inputScanner.nextLine());
if (newDutyCycle != -1)
{
fixture.setDutyCycle(newDutyCycle);
@ -450,7 +450,7 @@ public class Cli
}
case 2:
prompt("Input the desired frequency value: ");
int newFrequency = inputFiltering(inputScanner.nextLine());
int newFrequency = (int)inputFiltering(inputScanner.nextLine());
if (newFrequency != -1)
{
fixture.setFrequency(newFrequency);
@ -458,7 +458,7 @@ public class Cli
}
case 3:
prompt("Input the desired time-out (in seconds): ");
int newTimeout = inputFiltering(inputScanner.nextLine());
double newTimeout = inputFiltering(inputScanner.nextLine());
if (newTimeout != -1)
{
fixture.setTimeout(newTimeout);
@ -496,7 +496,7 @@ public class Cli
do
{
prompt("Enter a camera number to configure: ");
userInput = inputFiltering(inputScanner.nextLine());
userInput = (int)inputFiltering(inputScanner.nextLine());
userInput--;
} while (cameraList.size() < userInput && userInput < 0);
@ -527,7 +527,7 @@ public class Cli
//list configurable settings
printCameraConfigMenu(cameraName,tesseractValue);
userInput = inputFiltering(inputScanner.nextLine(),Menus.CAMERA);
userInput = (int)inputFiltering(inputScanner.nextLine(),Menus.CAMERA);
switch (userInput)
{
case 1:
@ -573,7 +573,7 @@ public class Cli
//Prompt is in int, as the ultimate values are cast
//to int anyways, a decimal would be confusing
(int)ConfigFacade.getValue(cameraName,modifiedProperty) + "): ");
userInput = inputFiltering(inputScanner.nextLine());
userInput = (int)inputFiltering(inputScanner.nextLine());
ConfigFacade.setValue(cameraName,modifiedProperty,userInput);
}
@ -607,7 +607,7 @@ public class Cli
do
{
prompt("Enter the camera you wish to set the serial of: ");
userInput = inputFiltering(inputScanner.nextLine());
userInput = (int)inputFiltering(inputScanner.nextLine());
//Compensate for off-by-one errors
userInput--;
} while (cameraList.size() < userInput || userInput < 0);
@ -634,7 +634,7 @@ public class Cli
do
{
prompt("Input the number of test iterations to complete: ");
input = inputFiltering(inputScanner.nextLine());
input = (int)inputFiltering(inputScanner.nextLine());
} while(input == -1);
iterationCount = input;
}
@ -659,7 +659,7 @@ public class Cli
do
{
prompt("Enter the camera you wish to toggle: ");
userInput = inputFiltering(inputScanner.nextLine());
userInput = (int)inputFiltering(inputScanner.nextLine());
userInput--;
} while (cameraList.size() < userInput || userInput < 0);
@ -830,7 +830,7 @@ public class Cli
*
* @param input The unparsed user input, directly from the {@link Scanner}
*/
private static int inputFiltering(String input)
private static double inputFiltering(String input)
{ return inputFiltering(input, Menus.OTHER); }
/**
@ -841,18 +841,18 @@ public class Cli
*
* @return The parsed value from the user. Returns -1 upon any error.
*/
private static int inputFiltering(String input, Menus menu)
private static double inputFiltering(String input, Menus menu)
{
int output = -1;
double output = -1;
input.trim();
try(Scanner sc = new Scanner(input))
{
if(!sc.hasNextInt())
if(!sc.hasNextDouble())
{
invalidInput();
return output;
}
output = sc.nextInt();
output = sc.nextDouble();
if(output < 0)
{
negativeInput();

View file

@ -23,7 +23,7 @@ import com.pi4j.io.pwm.PwmType;
* Currently missing Run switch compatibility.
*
* @author Blizzard Finnegan
* @version 2.2.0, 06 Feb. 2023
* @version 2.3.0, 27 Feb. 2023
*/
public class MovementFacade
{
@ -68,7 +68,7 @@ public class MovementFacade
/**
* PWM Frequency
*/
private static int FREQUENCY = 70000;
private static int FREQUENCY = 75000;
/**
* PWM Duty Cycle
@ -78,7 +78,7 @@ public class MovementFacade
/**
* Number of seconds to wait before timing out a fixture movement.
*/
private static int TIME_OUT = 3;
private static double TIME_OUT = 2.5;
//PWM Addresses
//All addresses are in BCM format.
@ -118,6 +118,17 @@ public class MovementFacade
*/
private static final int LOWER_LIMIT_ADDR = 24;
/**
* How many milliseconds to wait before polling the GPIO
*/
private static final int POLL_WAIT = 20;
/**
* How many times to poll the GPIO during a movement call.
* The 1000/POLL_WAIT in this definition is converting poll-times to polls-per-second.
*/
private static double POLL_COUNT = TIME_OUT * (1000 / POLL_WAIT);
//Pi GPIO pin objects
/**
@ -332,7 +343,7 @@ public class MovementFacade
*
* @return True if the value was set successfully; otherwise false.
*/
public boolean setTimeout(int newTimeout)
public boolean setTimeout(double newTimeout)
{
boolean output = false;
if(newTimeout < 0)
@ -342,6 +353,7 @@ public class MovementFacade
else
{
TIME_OUT = newTimeout;
POLL_COUNT = TIME_OUT * ( 1000 / POLL_WAIT );
output = true;
}
return output;
@ -352,7 +364,7 @@ public class MovementFacade
*
* @return The current timeout.
*/
public int getTimeout() { return TIME_OUT; }
public double getTimeout() { return TIME_OUT; }
/**
* Setter for the fixture's PWM frequency.
@ -391,7 +403,7 @@ public class MovementFacade
* @param timeout How long (in seconds) to wait before timing out.
* @return true if movement was successful; otherwise false
*/
private boolean gotoLimit(boolean moveUp, int timeout)
private boolean gotoLimit(boolean moveUp, double timeout)
{
boolean output = false;
DigitalInput limitSense;
@ -408,16 +420,22 @@ public class MovementFacade
ErrorLogging.logError("DEBUG: Sending fixture down...");
}
double mostlyThere = (POLL_COUNT * 2) / 3;
int slowerSpeed = FREQUENCY / 4;
motorEnable.on();
for(int i = 0; i < (timeout * 20);i++)
for(int i = 0; i < (POLL_COUNT);i++)
{
try{ Thread.sleep(50); } catch(Exception e) {ErrorLogging.logError(e);};
try{ Thread.sleep(POLL_WAIT); } catch(Exception e) {ErrorLogging.logError(e);};
output = limitSense.isHigh();
if(output) break;
else if(i >= mostlyThere)
{ pwm.on(DUTY_CYCLE, slowerSpeed); continue; }
}
if(output == false)
ErrorLogging.logError("FIXTURE MOVEMENT ERROR! - Motor movement timed out!");
motorEnable.off();
pwm.on(DUTY_CYCLE, FREQUENCY);
return output;
}
@ -427,7 +445,7 @@ public class MovementFacade
* @param timeout How long (in seconds) to wait before timing out.
* @return true if movement was successful; otherwise false
*/
public boolean goDown(int timeout) { return gotoLimit(false, timeout); }
public boolean goDown(double timeout) { return gotoLimit(false, timeout); }
/**
* Send the fixture to the upper limit switch.
@ -435,7 +453,7 @@ public class MovementFacade
* @param timeout How long (in seconds) to wait before timing out.
* @return true if movement was successful; otherwise false
*/
public boolean goUp(int timeout) { return gotoLimit(true, timeout); }
public boolean goUp(double timeout) { return gotoLimit(true, timeout); }
/**
* Send the fixture to the lower limit switch.

View file

@ -20,7 +20,7 @@ import org.bytedeco.tesseract.TessBaseAPI;
* information for this specific testing aparatus.
*
* @author Blizzard Finnegan
* @version 2.1.0, 06 Feb. 2023
* @version 2.2.0, 27 Feb. 2023
*/
public class TesseractFacade
{
@ -79,7 +79,12 @@ public class TesseractFacade
{
ErrorLogging.logError("OCR WARNING - OCR output is too high for DUT, attempting to adjust...");
output = output / 10;
if(output >= 200)
if(output >= 300)
{
output = output / 10;
ErrorLogging.logError("OCR output saved, as value appears to be real. Value needs to be verified.");
}
else if(output >= 200)
ErrorLogging.logError("OCR WARNING - OCR output is too high for DUT, potential misread.");
else
ErrorLogging.logError("OCR output successfully adjusted. Disregard warning.");