From 6254977e16a45be487d7a2668e39668489f07e64 Mon Sep 17 00:00:00 2001 From: Unknown Date: Mon, 18 Mar 2019 20:30:37 -0500 Subject: [PATCH 1/7] Added new methods to RingBuffer Instance fields min and max also added --- .../src/main/java/frc/robot/RingBuffer.java | 70 ++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) 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..28a4696 100644 --- a/FRC-Robot-2019/src/main/java/frc/robot/RingBuffer.java +++ b/FRC-Robot-2019/src/main/java/frc/robot/RingBuffer.java @@ -12,6 +12,8 @@ public class RingBuffer { private double[] array; private int head = 0; private boolean wrapped = false; + private double max = Double.NEGATIVE_INFINITY; + private double min = Double.POSITIVE_INFINITY; /** * Creates a RingBuffer object. @@ -34,6 +36,10 @@ public void add(double value) { head = 0; wrapped = true; } + if (value > max) + max = value; + if (value < min) + min = value; } /** @@ -51,7 +57,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 +67,65 @@ public int getLength() { else return head; } + /** + * Gets the head of the RingBuffer. + * @return the head + */ + public int getHead() { + return head; + } + + /** + * Gets the minimum value of the RingBuffer. + * @return the minimum value in the RingBuffer + */ + public double min() { + return min; + } + + /** + * Gets the maximum value of the RingBuffer. + * @return the maximum value in the RingBuffer + */ + public double max() { + return max; + } + /** + * Gets the sum of all of the values in the RingBuffer. + * @return the sum of the values in the RingBuffer + */ + public double total() { + if (getLength() == 0) + return 0; + double 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 From e62b5c6d17b0d49ee7e7bfcb6ad565ce9d412d6d Mon Sep 17 00:00:00 2001 From: Unknown Date: Mon, 18 Mar 2019 20:42:46 -0500 Subject: [PATCH 2/7] Changed type of value held by RingBuffer from double to int Kept avg() and olympicAvg() return types as double --- .../src/main/java/frc/robot/RingBuffer.java | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) 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 28a4696..2f5e2db 100644 --- a/FRC-Robot-2019/src/main/java/frc/robot/RingBuffer.java +++ b/FRC-Robot-2019/src/main/java/frc/robot/RingBuffer.java @@ -1,7 +1,7 @@ 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 @@ -9,11 +9,11 @@ public class RingBuffer { // TODO: Use this class to replace Deques in other classes - private double[] array; + private int[] array; private int head = 0; private boolean wrapped = false; - private double max = Double.NEGATIVE_INFINITY; - private double min = Double.POSITIVE_INFINITY; + private int max = Integer.MIN_VALUE; + private int min = Integer.MAX_VALUE; /** * Creates a RingBuffer object. @@ -23,14 +23,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; @@ -79,7 +79,9 @@ public int getHead() { * Gets the minimum value of the RingBuffer. * @return the minimum value in the RingBuffer */ - public double min() { + public int min() { + if (getLength() == 0) + return 0; return min; } @@ -87,7 +89,9 @@ public double min() { * Gets the maximum value of the RingBuffer. * @return the maximum value in the RingBuffer */ - public double max() { + public int max() { + if (getLength() == 0) + return 0; return max; } @@ -95,10 +99,10 @@ public double max() { * Gets the sum of all of the values in the RingBuffer. * @return the sum of the values in the RingBuffer */ - public double total() { + public int total() { if (getLength() == 0) return 0; - double sum = 0; + int sum = 0; for (int i = 0; i <= getLength(); i++) { if (i >= getLength()) i = 0; From f372ac21c706d2343519d131f30127fcfb48a45b Mon Sep 17 00:00:00 2001 From: Unknown Date: Mon, 18 Mar 2019 20:53:36 -0500 Subject: [PATCH 3/7] Changed instances of Deque in SerialPortSubsystems to RingBuffer Changed some code in the process Not tested yet --- .../robot/subsystems/SerialPortSubsystem.java | 73 ++++--------------- 1 file changed, 13 insertions(+), 60 deletions(-) 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 From eebeb2fd53baea4990f485b436ab8c86623ec771 Mon Sep 17 00:00:00 2001 From: Unknown Date: Sat, 23 Mar 2019 09:30:41 -0500 Subject: [PATCH 4/7] Added calculate method Calculates and updates min and max values Automatically invoked by min and max methods if updated after last call of calculate method --- .../src/main/java/frc/robot/RingBuffer.java | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) 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 2f5e2db..5f8f805 100644 --- a/FRC-Robot-2019/src/main/java/frc/robot/RingBuffer.java +++ b/FRC-Robot-2019/src/main/java/frc/robot/RingBuffer.java @@ -7,13 +7,12 @@ * @author Kevin Li */ public class RingBuffer { - // TODO: Use this class to replace Deques in other classes - private int[] array; private int head = 0; private boolean wrapped = false; private int max = Integer.MIN_VALUE; private int min = Integer.MAX_VALUE; + private boolean justCalculated = false; /** * Creates a RingBuffer object. @@ -36,10 +35,6 @@ public void add(int value) { head = 0; wrapped = true; } - if (value > max) - max = value; - if (value < min) - min = value; } /** @@ -75,6 +70,21 @@ public int getHead() { return head; } + /** + * Calculates 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 calculate() { + for (int i = 0; i < getLength(); i++) { + if (max < array[i]) + max = array[i]; + if (min < array[i]) + min = array[i]; + } + justCalculated = true; + } + /** * Gets the minimum value of the RingBuffer. * @return the minimum value in the RingBuffer @@ -82,6 +92,8 @@ public int getHead() { public int min() { if (getLength() == 0) return 0; + if (!justCalculated) + calculate(); return min; } @@ -92,6 +104,8 @@ public int min() { public int max() { if (getLength() == 0) return 0; + if (!justCalculated) + calculate(); return max; } From 2aa1c3be0a16ddf115e44281d805d9b1d31c140c Mon Sep 17 00:00:00 2001 From: Unknown Date: Sat, 23 Mar 2019 10:09:40 -0500 Subject: [PATCH 5/7] Instance fields min and max start at 0 calculate() should now update properly justCalculated is true before adding any values --- .../src/main/java/frc/robot/RingBuffer.java | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) 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 5f8f805..8c30bb5 100644 --- a/FRC-Robot-2019/src/main/java/frc/robot/RingBuffer.java +++ b/FRC-Robot-2019/src/main/java/frc/robot/RingBuffer.java @@ -10,9 +10,9 @@ public class RingBuffer { private int[] array; private int head = 0; private boolean wrapped = false; - private int max = Integer.MIN_VALUE; - private int min = Integer.MAX_VALUE; - private boolean justCalculated = false; + private int max = 0; + private int min = 0; + private boolean justCalculated = true; /** * Creates a RingBuffer object. @@ -76,7 +76,9 @@ public int getHead() { * will automatically invoke this method, if necessary. */ public void calculate() { - for (int i = 0; i < getLength(); i++) { + max = array[0]; + min = array[0]; + for (int i = 1; i < getLength(); i++) { if (max < array[i]) max = array[i]; if (min < array[i]) @@ -90,8 +92,6 @@ public void calculate() { * @return the minimum value in the RingBuffer */ public int min() { - if (getLength() == 0) - return 0; if (!justCalculated) calculate(); return min; @@ -102,8 +102,6 @@ public int min() { * @return the maximum value in the RingBuffer */ public int max() { - if (getLength() == 0) - return 0; if (!justCalculated) calculate(); return max; @@ -114,8 +112,6 @@ public int max() { * @return the sum of the values in the RingBuffer */ public int total() { - if (getLength() == 0) - return 0; int sum = 0; for (int i = 0; i <= getLength(); i++) { if (i >= getLength()) From 1d1284b74c2099b9c9e9ed808b60955ead45afea Mon Sep 17 00:00:00 2001 From: Unknown Date: Sat, 23 Mar 2019 10:12:36 -0500 Subject: [PATCH 6/7] Changed method calculate() to compute() Changed instance field justCalculated to justComputed --- .../src/main/java/frc/robot/RingBuffer.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) 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 8c30bb5..d0e8b00 100644 --- a/FRC-Robot-2019/src/main/java/frc/robot/RingBuffer.java +++ b/FRC-Robot-2019/src/main/java/frc/robot/RingBuffer.java @@ -12,7 +12,7 @@ public class RingBuffer { private boolean wrapped = false; private int max = 0; private int min = 0; - private boolean justCalculated = true; + private boolean justComputed = true; /** * Creates a RingBuffer object. @@ -71,11 +71,11 @@ public int getHead() { } /** - * Calculates and updates the minimum and maximum of all values in the RingBuffer. + * 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 calculate() { + public void compute() { max = array[0]; min = array[0]; for (int i = 1; i < getLength(); i++) { @@ -84,7 +84,7 @@ public void calculate() { if (min < array[i]) min = array[i]; } - justCalculated = true; + justComputed = true; } /** @@ -92,8 +92,8 @@ public void calculate() { * @return the minimum value in the RingBuffer */ public int min() { - if (!justCalculated) - calculate(); + if (!justComputed) + compute(); return min; } @@ -102,8 +102,8 @@ public int min() { * @return the maximum value in the RingBuffer */ public int max() { - if (!justCalculated) - calculate(); + if (!justComputed) + compute(); return max; } From ec77553bc8c39ad7fa3e40f9c2926f71d4c3f0b8 Mon Sep 17 00:00:00 2001 From: Unknown Date: Sat, 23 Mar 2019 11:30:05 -0500 Subject: [PATCH 7/7] Added documentation to RingBuffer instance fields --- .../src/main/java/frc/robot/RingBuffer.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) 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 d0e8b00..2529508 100644 --- a/FRC-Robot-2019/src/main/java/frc/robot/RingBuffer.java +++ b/FRC-Robot-2019/src/main/java/frc/robot/RingBuffer.java @@ -7,11 +7,31 @@ * @author Kevin Li */ public class RingBuffer { + /** + * 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; /**