[build] Enable spotbugs (#3601)

Benign spotbugs warnings were suppressed, and all others were fixed. Bug
descriptions are documented here:
https://spotbugs.readthedocs.io/en/stable/bugDescriptions.html

Co-authored-by: Austin Shalit <austinshalit@gmail.com>
This commit is contained in:
Tyler Veness
2021-09-24 16:04:02 -07:00
committed by GitHub
parent b65fce86bf
commit 95dd20a151
73 changed files with 356 additions and 558 deletions

View File

@@ -38,23 +38,14 @@ class ControlAffinePlantInversionFeedforwardTest {
@SuppressWarnings("ParameterName")
protected Matrix<N2, N1> getDynamics(Matrix<N2, N1> x, Matrix<N1, N1> u) {
var result = new Matrix<>(Nat.N2(), Nat.N1());
result =
Matrix.mat(Nat.N2(), Nat.N2())
.fill(1.000, 0, 0, 1.000)
.times(x)
.plus(VecBuilder.fill(0, 1).times(u));
return result;
return Matrix.mat(Nat.N2(), Nat.N2())
.fill(1.000, 0, 0, 1.000)
.times(x)
.plus(VecBuilder.fill(0, 1).times(u));
}
@SuppressWarnings("ParameterName")
protected Matrix<N2, N1> getStateDynamics(Matrix<N2, N1> x) {
var result = new Matrix<>(Nat.N2(), Nat.N1());
result = Matrix.mat(Nat.N2(), Nat.N2()).fill(1.000, 0, 0, 1.000).times(x);
return result;
return Matrix.mat(Nat.N2(), Nat.N2()).fill(1.000, 0, 0, 1.000).times(x);
}
}

View File

@@ -30,7 +30,8 @@ class HolonomicDriveControllerTest {
new HolonomicDriveController(
new PIDController(1.0, 0.0, 0.0),
new PIDController(1.0, 0.0, 0.0),
new ProfiledPIDController(1.0, 0.0, 0.0, new TrapezoidProfile.Constraints(6.28, 3.14)));
new ProfiledPIDController(
1.0, 0.0, 0.0, new TrapezoidProfile.Constraints(2.0 * Math.PI, Math.PI)));
Pose2d robotPose = new Pose2d(2.7, 23.0, Rotation2d.fromDegrees(0.0));
List<Pose2d> waypoints = new ArrayList<>();

View File

@@ -7,52 +7,27 @@ package edu.wpi.first.math.controller;
import static org.junit.jupiter.api.Assertions.assertEquals;
import edu.wpi.first.math.VecBuilder;
import edu.wpi.first.math.numbers.N1;
import edu.wpi.first.math.numbers.N2;
import edu.wpi.first.math.system.LinearSystem;
import edu.wpi.first.math.system.plant.DCMotor;
import edu.wpi.first.math.system.plant.LinearSystemId;
import org.junit.jupiter.api.Test;
public class LinearQuadraticRegulatorTest {
public static LinearSystem<N2, N1, N1> elevatorPlant;
static LinearSystem<N2, N1, N1> armPlant;
static {
createArm();
createElevator();
}
@Test
@SuppressWarnings("LocalVariableName")
public static void createArm() {
var motors = DCMotor.getVex775Pro(2);
var m = 4.0;
var r = 0.4;
var J = 1d / 3d * m * r * r;
var G = 100.0;
armPlant = LinearSystemId.createSingleJointedArmSystem(motors, J, G);
}
@SuppressWarnings("LocalVariableName")
public static void createElevator() {
public void testLQROnElevator() {
var motors = DCMotor.getVex775Pro(2);
var m = 5.0;
var r = 0.0181864;
var G = 1.0;
elevatorPlant = LinearSystemId.createElevatorSystem(motors, m, r, G);
}
@Test
@SuppressWarnings("LocalVariableName")
public void testLQROnElevator() {
var plant = LinearSystemId.createElevatorSystem(motors, m, r, G);
var qElms = VecBuilder.fill(0.02, 0.4);
var rElms = VecBuilder.fill(12.0);
var dt = 0.00505;
var controller = new LinearQuadraticRegulator<>(elevatorPlant, qElms, rElms, dt);
var controller = new LinearQuadraticRegulator<>(plant, qElms, rElms, dt);
var k = controller.getK();

View File

@@ -18,8 +18,6 @@ import edu.wpi.first.math.system.LinearSystemLoop;
import edu.wpi.first.math.system.plant.DCMotor;
import edu.wpi.first.math.system.plant.LinearSystemId;
import edu.wpi.first.math.trajectory.TrapezoidProfile;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.junit.jupiter.api.Test;
@@ -103,12 +101,6 @@ public class LinearSystemLoopTest {
loop.setNextR(references);
List<Double> timeData = new ArrayList<>();
List<Double> xHat = new ArrayList<>();
List<Double> volt = new ArrayList<>();
List<Double> reference = new ArrayList<>();
List<Double> error = new ArrayList<>();
var time = 0.0;
while (time < 10) {
if (time > 10) {
@@ -128,27 +120,9 @@ public class LinearSystemLoopTest {
assertTrue(u >= -12.1 && u <= 12.1, "U out of bounds! Got " + u);
xHat.add(loop.getXHat(0) / 2d / Math.PI * 60);
volt.add(u);
timeData.add(time);
reference.add(references.get(0, 0) / 2d / Math.PI * 60);
error.add(loop.getError(0) / 2d / Math.PI * 60);
time += kDt;
}
// XYChart bigChart = new XYChartBuilder().build();
// bigChart.addSeries("Xhat, RPM", timeData, xHat);
// bigChart.addSeries("Reference, RPM", timeData, reference);
// bigChart.addSeries("Error, RPM", timeData, error);
// XYChart smolChart = new XYChartBuilder().build();
// smolChart.addSeries("Volts, V", timeData, volt);
// try {
// new SwingWrapper<>(List.of(bigChart, smolChart)).displayChartMatrix();
// Thread.sleep(10000000);
// } catch (InterruptedException e) { e.printStackTrace(); }
assertEquals(0.0, loop.getError(0), 0.1);
}
}

View File

@@ -22,7 +22,6 @@ import edu.wpi.first.math.system.NumericalJacobian;
import edu.wpi.first.math.system.plant.DCMotor;
import edu.wpi.first.math.trajectory.TrajectoryConfig;
import edu.wpi.first.math.trajectory.TrajectoryGenerator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.jupiter.api.Test;
@@ -127,12 +126,6 @@ public class ExtendedKalmanFilterTest {
Matrix<N5, N1> nextR = new Matrix<>(Nat.N5(), Nat.N1());
Matrix<N2, N1> u = new Matrix<>(Nat.N2(), Nat.N1());
List<Double> trajXs = new ArrayList<>();
List<Double> trajYs = new ArrayList<>();
List<Double> observerXs = new ArrayList<>();
List<Double> observerYs = new ArrayList<>();
var B =
NumericalJacobian.numericalJacobianU(
Nat.N5(),
@@ -177,12 +170,6 @@ public class ExtendedKalmanFilterTest {
ExtendedKalmanFilterTest::getDynamics, groundTruthX, u, dtSeconds);
r = nextR;
trajXs.add(ref.poseMeters.getTranslation().getX());
trajYs.add(ref.poseMeters.getTranslation().getY());
observerXs.add(observer.getXhat().get(0, 0));
observerYs.add(observer.getXhat().get(1, 0));
}
var localY = getLocalMeasurementModel(observer.getXhat(), u);
@@ -192,22 +179,6 @@ public class ExtendedKalmanFilterTest {
var R = StateSpaceUtil.makeCostMatrix(VecBuilder.fill(0.01, 0.01, 0.0001, 0.5, 0.5));
observer.correct(Nat.N5(), u, globalY, ExtendedKalmanFilterTest::getGlobalMeasurementModel, R);
// var chartBuilder = new XYChartBuilder();
// chartBuilder.title = "The Magic of Sensor Fusion, now with a "
// + observer.getClass().getSimpleName();
// var xyPosChart = chartBuilder.build();
//
// xyPosChart.setXAxisTitle("X pos, meters");
// xyPosChart.setYAxisTitle("Y pos, meters");
// xyPosChart.addSeries("Trajectory", trajXs, trajYs);
// xyPosChart.addSeries("xHat", observerXs, observerYs);
// new SwingWrapper<>(xyPosChart).displayChart();
// try {
// Thread.sleep(1000000000);
// } catch (InterruptedException ex) {
// ex.printStackTrace();
// }
var finalPosition = trajectory.sample(trajectory.getTotalTimeSeconds());
assertEquals(finalPosition.poseMeters.getTranslation().getX(), observer.getXhat(0), 1.0);
assertEquals(finalPosition.poseMeters.getTranslation().getY(), observer.getXhat(1), 1.0);

View File

@@ -21,7 +21,6 @@ import edu.wpi.first.math.system.plant.DCMotor;
import edu.wpi.first.math.system.plant.LinearSystemId;
import edu.wpi.first.math.trajectory.TrajectoryConfig;
import edu.wpi.first.math.trajectory.TrajectoryGenerator;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.junit.jupiter.api.Test;
@@ -84,11 +83,6 @@ public class KalmanFilterTest {
VecBuilder.fill(2, 2, 2), // measurement weights
0.020);
List<Double> xhatsX = new ArrayList<>();
List<Double> measurementsX = new ArrayList<>();
List<Double> xhatsY = new ArrayList<>();
List<Double> measurementsY = new ArrayList<>();
Matrix<N3, N1> measurement;
for (int i = 0; i < 100; i++) {
// the robot is at [0, 0, 0] so we just park here
@@ -98,21 +92,8 @@ public class KalmanFilterTest {
// we continue to not accelerate
filter.predict(VecBuilder.fill(0.0, 0.0, 0.0), 0.020);
measurementsX.add(measurement.get(0, 0));
measurementsY.add(measurement.get(1, 0));
xhatsX.add(filter.getXhat(0));
xhatsY.add(filter.getXhat(1));
}
// var chart = new XYChartBuilder().build();
// chart.addSeries("Xhat, x/y", xhatsX, xhatsY);
// chart.addSeries("Measured position, x/y", measurementsX, measurementsY);
// try {
// new SwingWrapper<>(chart).displayChart();
// Thread.sleep(10000000);
// } catch (Exception ign) {
// }
assertEquals(0.0, filter.getXhat(0), 0.3);
assertEquals(0.0, filter.getXhat(0), 0.3);
}
@@ -131,11 +112,6 @@ public class KalmanFilterTest {
VecBuilder.fill(4, 4, 4), // measurement weights
0.020);
List<Double> xhatsX = new ArrayList<>();
List<Double> measurementsX = new ArrayList<>();
List<Double> xhatsY = new ArrayList<>();
List<Double> measurementsY = new ArrayList<>();
// we set the velocity of the robot so that it's moving forward slowly
filter.setXhat(0, 0.5);
filter.setXhat(1, 0.5);
@@ -153,21 +129,8 @@ public class KalmanFilterTest {
// we continue to not accelerate
filter.predict(VecBuilder.fill(0.0, 0.0, 0.0), 0.020);
measurementsX.add(measurement.get(0, 0));
measurementsY.add(measurement.get(1, 0));
xhatsX.add(filter.getXhat(0));
xhatsY.add(filter.getXhat(1));
}
// var chart = new XYChartBuilder().build();
// chart.addSeries("Xhat, x/y", xhatsX, xhatsY);
// chart.addSeries("Measured position, x/y", measurementsX, measurementsY);
// try {
// new SwingWrapper<>(chart).displayChart();
// Thread.sleep(10000000);
// } catch (Exception ign) {}
assertEquals(0.0, filter.getXhat(0), 0.2);
assertEquals(0.0, filter.getXhat(1), 0.2);
}
@@ -187,11 +150,6 @@ public class KalmanFilterTest {
VecBuilder.fill(4, 4, 4), // measurement weights
0.020);
List<Double> xhatsX = new ArrayList<>();
List<Double> measurementsX = new ArrayList<>();
List<Double> xhatsY = new ArrayList<>();
List<Double> measurementsY = new ArrayList<>();
var trajectory =
TrajectoryGenerator.generateTrajectory(
List.of(new Pose2d(0, 0, new Rotation2d()), new Pose2d(5, 5, new Rotation2d())),
@@ -218,23 +176,9 @@ public class KalmanFilterTest {
filter.correct(u, measurement);
filter.predict(u, 0.020);
measurementsX.add(measurement.get(0, 0));
measurementsY.add(measurement.get(1, 0));
xhatsX.add(filter.getXhat(0));
xhatsY.add(filter.getXhat(1));
time += 0.020;
}
// var chart = new XYChartBuilder().build();
// chart.addSeries("Xhat, x/y", xhatsX, xhatsY);
// chart.addSeries("Measured position, x/y", measurementsX, measurementsY);
// try {
// new SwingWrapper<>(chart).displayChart();
// Thread.sleep(10000000);
// } catch (Exception ign) {
// }
assertEquals(
trajectory.sample(trajectory.getTotalTimeSeconds()).poseMeters.getTranslation().getX(),
filter.getXhat(0),

View File

@@ -25,7 +25,6 @@ import edu.wpi.first.math.system.plant.DCMotor;
import edu.wpi.first.math.system.plant.LinearSystemId;
import edu.wpi.first.math.trajectory.TrajectoryConfig;
import edu.wpi.first.math.trajectory.TrajectoryGenerator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.jupiter.api.Test;
@@ -109,22 +108,6 @@ public class UnscentedKalmanFilterTest {
double dtSeconds = 0.00505;
double rbMeters = 0.8382 / 2.0; // Robot radius
List<Double> trajXs = new ArrayList<>();
List<Double> trajYs = new ArrayList<>();
List<Double> observerXs = new ArrayList<>();
List<Double> observerYs = new ArrayList<>();
List<Double> observerC = new ArrayList<>();
List<Double> observerS = new ArrayList<>();
List<Double> observervl = new ArrayList<>();
List<Double> observervr = new ArrayList<>();
List<Double> inputVl = new ArrayList<>();
List<Double> inputVr = new ArrayList<>();
List<Double> timeData = new ArrayList<>();
List<Matrix<?, ?>> rdots = new ArrayList<>();
UnscentedKalmanFilter<N6, N2, N4> observer =
new UnscentedKalmanFilter<>(
Nat.N6(),
@@ -190,25 +173,6 @@ public class UnscentedKalmanFilterTest {
var rdot = nextR.minus(r).div(dtSeconds);
u = new Matrix<>(B.solve(rdot.minus(getDynamics(r, new Matrix<>(Nat.N2(), Nat.N1())))));
rdots.add(rdot);
trajXs.add(ref.poseMeters.getTranslation().getX());
trajYs.add(ref.poseMeters.getTranslation().getY());
observerXs.add(observer.getXhat().get(0, 0));
observerYs.add(observer.getXhat().get(1, 0));
observerC.add(observer.getXhat(2));
observerS.add(observer.getXhat(3));
observervl.add(observer.getXhat(4));
observervr.add(observer.getXhat(5));
inputVl.add(u.get(0, 0));
inputVr.add(u.get(1, 0));
timeData.add(i * dtSeconds);
r = nextR;
observer.predict(u, dtSeconds);
trueXhat =
@@ -233,53 +197,6 @@ public class UnscentedKalmanFilterTest {
final var finalPosition = trajectory.sample(trajectory.getTotalTimeSeconds());
// var chartBuilder = new XYChartBuilder();
// chartBuilder.title = "The Magic of Sensor Fusion, now with a "
// + observer.getClass().getSimpleName();
// var xyPosChart = chartBuilder.build();
// xyPosChart.setXAxisTitle("X pos, meters");
// xyPosChart.setYAxisTitle("Y pos, meters");
// xyPosChart.addSeries("Trajectory", trajXs, trajYs);
// xyPosChart.addSeries("xHat", observerXs, observerYs);
// var stateChart = new XYChartBuilder()
// .title("States (x-hat)").build();
// stateChart.addSeries("Cos", timeData, observerC);
// stateChart.addSeries("Sin", timeData, observerS);
// stateChart.addSeries("vl, m/s", timeData, observervl);
// stateChart.addSeries("vr, m/s", timeData, observervr);
// var inputChart = new XYChartBuilder().title("Inputs").build();
// inputChart.addSeries("Left voltage", timeData, inputVl);
// inputChart.addSeries("Right voltage", timeData, inputVr);
// var rdotChart = new XYChartBuilder().title("Rdot").build();
// rdotChart.addSeries("xdot, or vx", timeData, rdots.stream().map(it -> it.get(0, 0))
// .collect(Collectors.toList()));
// rdotChart.addSeries("ydot, or vy", timeData, rdots.stream().map(it -> it.get(1, 0))
// .collect(Collectors.toList()));
// rdotChart.addSeries("cos dot", timeData, rdots.stream().map(it -> it.get(2, 0))
// .collect(Collectors.toList()));
// rdotChart.addSeries("sin dot", timeData, rdots.stream().map(it -> it.get(3, 0))
// .collect(Collectors.toList()));
// rdotChart.addSeries("vl dot, or al", timeData, rdots.stream().map(it -> it.get(4, 0))
// .collect(Collectors.toList()));
// rdotChart.addSeries("vr dot, or ar", timeData, rdots.stream().map(it -> it.get(5, 0))
// .collect(Collectors.toList()));
// List<XYChart> charts = new ArrayList<>();
// charts.add(xyPosChart);
// charts.add(stateChart);
// charts.add(inputChart);
// charts.add(rdotChart);
// new SwingWrapper<>(charts).displayChartMatrix();
// try {
// Thread.sleep(1000000000);
// } catch (InterruptedException ex) {
// ex.printStackTrace();
// }
assertEquals(finalPosition.poseMeters.getTranslation().getX(), observer.getXhat(0), 0.25);
assertEquals(finalPosition.poseMeters.getTranslation().getY(), observer.getXhat(1), 0.25);
assertEquals(finalPosition.poseMeters.getRotation().getRadians(), observer.getXhat(2), 1.0);
@@ -302,12 +219,6 @@ public class UnscentedKalmanFilterTest {
VecBuilder.fill(1.0),
dt);
var time = new ArrayList<Double>();
var refData = new ArrayList<Double>();
var xhat = new ArrayList<Double>();
var udata = new ArrayList<Double>();
var xdotData = new ArrayList<Double>();
var discABPair = Discretization.discretizeAB(plant.getA(), plant.getB(), dt);
var discA = discABPair.getFirst();
var discB = discABPair.getSecond();
@@ -315,36 +226,12 @@ public class UnscentedKalmanFilterTest {
Matrix<N1, N1> ref = VecBuilder.fill(100);
Matrix<N1, N1> u = VecBuilder.fill(0);
Matrix<N1, N1> xdot;
for (int i = 0; i < (2.0 / dt); i++) {
observer.predict(u, dt);
u = discB.solve(ref.minus(discA.times(ref)));
xdot = plant.getA().times(observer.getXhat()).plus(plant.getB().times(u));
time.add(i * dt);
refData.add(ref.get(0, 0));
xhat.add(observer.getXhat(0));
udata.add(u.get(0, 0));
xdotData.add(xdot.get(0, 0));
}
// var chartBuilder = new XYChartBuilder();
// chartBuilder.title = "The Magic of Sensor Fusion";
// var chart = chartBuilder.build();
// chart.addSeries("Ref", time, refData);
// chart.addSeries("xHat", time, xhat);
// chart.addSeries("input", time, udata);
//// chart.addSeries("xdot", time, xdotData);
// new SwingWrapper<>(chart).displayChart();
// try {
// Thread.sleep(1000000000);
// } catch (InterruptedException e) {
// }
assertEquals(ref.get(0, 0), observer.getXhat(0), 5);
}