diff --git a/FRC-Robot-2019/src/main/java/frc/robot/RingBuffer.java b/FRC-Robot-2019/src/main/java/frc/robot/RingBuffer.java
index 9a0a277..2529508 100644
--- a/FRC-Robot-2019/src/main/java/frc/robot/RingBuffer.java
+++ b/FRC-Robot-2019/src/main/java/frc/robot/RingBuffer.java
@@ -1,17 +1,38 @@
package frc.robot;
/**
- * A RingBuffer object is essentially a double array with a head.
+ * A RingBuffer object is essentially an integer array with a head.
* The head increments every time a new value is incremented.
*
* @author Kevin Li
*/
public class RingBuffer {
- // TODO: Use this class to replace Deques in other classes
-
- private double[] array;
+ /**
+ * The array in which the values are stored
+ */
+ private int[] array;
+ /**
+ * The "beginning" of the RingBuffer.
+ */
private int head = 0;
+ /**
+ * Whether or not the RingBuffer has wrapped all the way to the beginning of the array.
+ * Used to figure the length of the RingBuffer.
+ */
private boolean wrapped = false;
+ /**
+ * The maximum value of the RingBuffer.
+ */
+ private int max = 0;
+ /**
+ * The minimum value of the RingBuffer.
+ */
+ private int min = 0;
+ /**
+ * Whether or not the maximum and minimum values are updated.
+ * Opposite of whether or not compute() is nesessary.
+ */
+ private boolean justComputed = true;
/**
* Creates a RingBuffer object.
@@ -21,14 +42,14 @@ public class RingBuffer {
public RingBuffer(int length) {
if (length <= 0)
throw new IllegalArgumentException("Length must be positive.");
- array = new double[length];
+ array = new int[length];
}
/**
* Inserts a value to the RingBuffer at index head.
* @param value the value to be inserted into the RingBuffer
*/
- public void add(double value) {
+ public void add(int value) {
array[head++] = value;
if (head >= array.length) {
head = 0;
@@ -51,7 +72,9 @@ public double get(int index) {
}
/**
- * Gets the length of the RingBuffer. //TODO: Change documentation
+ * Gets the length of the RingBuffer.
+ * If the array has wrapped, the full length of the array is returned.
+ * Otherwise, the value of the head is returned.
* @return the length of the RingBuffer
*/
public int getLength() {
@@ -59,5 +82,84 @@ public int getLength() {
else return head;
}
+ /**
+ * Gets the head of the RingBuffer.
+ * @return the head
+ */
+ public int getHead() {
+ return head;
+ }
+
+ /**
+ * Computes and updates the minimum and maximum of all values in the RingBuffer.
+ * Using the min or max method (or any method that in any way invokes those methods - e.g. avg)
+ * will automatically invoke this method, if necessary.
+ */
+ public void compute() {
+ max = array[0];
+ min = array[0];
+ for (int i = 1; i < getLength(); i++) {
+ if (max < array[i])
+ max = array[i];
+ if (min < array[i])
+ min = array[i];
+ }
+ justComputed = true;
+ }
+ /**
+ * Gets the minimum value of the RingBuffer.
+ * @return the minimum value in the RingBuffer
+ */
+ public int min() {
+ if (!justComputed)
+ compute();
+ return min;
+ }
+
+ /**
+ * Gets the maximum value of the RingBuffer.
+ * @return the maximum value in the RingBuffer
+ */
+ public int max() {
+ if (!justComputed)
+ compute();
+ return max;
+ }
+
+ /**
+ * Gets the sum of all of the values in the RingBuffer.
+ * @return the sum of the values in the RingBuffer
+ */
+ public int total() {
+ int sum = 0;
+ for (int i = 0; i <= getLength(); i++) {
+ if (i >= getLength())
+ i = 0;
+ sum += array[i];
+ }
+ return sum;
+ }
+
+ /**
+ * Gets the mean of all values in the RingBuffer.
+ * @return the average of the values in the RingBuffer
+ */
+ public double avg() {
+ if (getLength() == 0)
+ return 0;
+ else
+ return total() / getLength();
+ }
+
+ /**
+ * Gets the mean of all values in the RingBuffer (ignoring the minimum and maximum).
+ * @return the average of the values in the RingBuffer, ignoring the minimum and maximum
+ */
+ public double olympicAvg() {
+ if (getLength() <= 2)
+ return 0;
+ else
+ return (total() - min() - max()) / (getLength() - 2);
+ }
}
\ No newline at end of file
diff --git a/FRC-Robot-2019/src/main/java/frc/robot/subsystems/SerialPortSubsystem.java b/FRC-Robot-2019/src/main/java/frc/robot/subsystems/SerialPortSubsystem.java
index 48e7e8a..97f7384 100644
--- a/FRC-Robot-2019/src/main/java/frc/robot/subsystems/SerialPortSubsystem.java
+++ b/FRC-Robot-2019/src/main/java/frc/robot/subsystems/SerialPortSubsystem.java
@@ -5,9 +5,8 @@
import edu.wpi.first.hal.util.UncleanStatusException;
import java.lang.StringBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
+import frc.robot.RingBuffer;
import frc.robot.RobotMap;
-import java.util.ArrayDeque;
-import java.util.Deque;
import java.util.ArrayList;
//Listens on USB Serial port for LIDAR distance data from the arduino
@@ -15,7 +14,7 @@
public class SerialPortSubsystem extends Subsystem {
private int[] distanceArray = new int[4];
-private ArrayList distanceAvgArray;
+private ArrayList distanceAvgArray;
private StringBuilder serialResults = new StringBuilder();
private SerialPort arduinoSerial;
private boolean serialExists = true;
@@ -31,11 +30,11 @@ public SerialPortSubsystem() {
}
logTimer = System.currentTimeMillis();
- distanceAvgArray = new ArrayList(); //4 elements, each is a Deque for 10 elements of distance
- distanceAvgArray.add(0, new ArrayDeque());
- distanceAvgArray.add(1, new ArrayDeque());
- distanceAvgArray.add(2, new ArrayDeque());
- distanceAvgArray.add(3, new ArrayDeque());
+ distanceAvgArray = new ArrayList(); //4 elements, each is a RingBuffer for 10 elements of distance
+ distanceAvgArray.add(0, new RingBuffer(10));
+ distanceAvgArray.add(1, new RingBuffer(10));
+ distanceAvgArray.add(2, new RingBuffer(10));
+ distanceAvgArray.add(3, new RingBuffer(10));
}
@@ -58,65 +57,23 @@ public int getDistance(int sensor) { //return last distance measure for LIDAR se
public Integer getDistanceAvg(int sensor) { //return olympic average of last 10 readings of LIDAR sensor
- Deque tempDeque = distanceAvgArray.get(sensor-1);
- Integer[] tempArray = tempDeque.toArray(new Integer[0]); //switch from ArrayDeque to actual array so we can get each element
- Integer average = 0;
- Integer sum = 0;
- Integer max = 0;
- Integer min = 10000;
+ RingBuffer tempRingBuffer = distanceAvgArray.get(sensor-1);
if (!serialExists)
return 0;
- else {
- for (int i = 0; i max)
- {
- max = tempArray[i];
- }
- if(tempArray[i] < min)
- {
- min = tempArray[i];
- }
- sum = sum + tempArray[i];
- }
- if ((distanceAvgArray.get(sensor-1).size()-2)!=0) {
- average = (sum-max-min) / (distanceAvgArray.get(sensor-1).size()-2); //return average, not including max or min reading (olympic)
- return average;
- }
- else return 0;
- }
+ else
+ return (int) tempRingBuffer.olympicAvg();
}
public Boolean isReliable(int sensor, double percent){ //check sensor to see if last 10 measurements are within a certain deviation
- Integer max = 0;
- Integer min = 10000;
- Deque tempDeque = distanceAvgArray.get(sensor-1);
- Integer[] tempArray = tempDeque.toArray(new Integer[0]);
+ RingBuffer tempRingBuffer = distanceAvgArray.get(sensor-1);
if (!serialExists)
return false;
else {
- for (int i = 0; i max)
- {
- max = tempArray[i];
- }
- if(tempArray[i] < min)
- {
- min = tempArray[i];
- }
- }
-
- if(max != 0)
+ if(tempRingBuffer.max() > 0)
{
- if(min/max >= percent)
- {
- return true;
- }
- else
- {
- return false;
- }
+ return (tempRingBuffer.max() / tempRingBuffer.min() >= percent);
}
else
{
@@ -251,9 +208,5 @@ public void processMessage(StringBuilder serialResults){
distanceArray[sensor-1]=distance;//set read distance to correct LIDAR based on read sensor ID
distanceAvgArray.get(sensor-1).add(distance);//add to rolling average array
- if(distanceAvgArray.get(sensor-1).size() > 10)//keep most recent 10 valuse in array
- {
- distanceAvgArray.get(sensor-1).remove(); //remove oldest reading (queue)
- }
}
}
\ No newline at end of file