From 3ddb7b5f9dd2ca5282f826ce25bf8944bbc8ad9e Mon Sep 17 00:00:00 2001 From: edelmanjm Date: Wed, 28 Nov 2018 16:38:04 -0800 Subject: [PATCH 01/10] Create simple framework for direct motor control It's tested too --- .../testers/SimpleControllersTester.java | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 lib/src/main/java/org/team1540/rooster/testers/SimpleControllersTester.java diff --git a/lib/src/main/java/org/team1540/rooster/testers/SimpleControllersTester.java b/lib/src/main/java/org/team1540/rooster/testers/SimpleControllersTester.java new file mode 100644 index 00000000..2428f5e7 --- /dev/null +++ b/lib/src/main/java/org/team1540/rooster/testers/SimpleControllersTester.java @@ -0,0 +1,109 @@ +package org.team1540.rooster.testers; + +import com.ctre.phoenix.motorcontrol.ControlMode; +import edu.wpi.first.wpilibj.Joystick; +import edu.wpi.first.wpilibj.Sendable; +import edu.wpi.first.wpilibj.buttons.JoystickButton; +import edu.wpi.first.wpilibj.command.Command; +import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder; +import edu.wpi.first.wpilibj.smartdashboard.SendableChooser; +import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; +import java.util.NavigableMap; +import java.util.Optional; +import java.util.TreeMap; +import org.team1540.rooster.util.SimpleCommand; +import org.team1540.rooster.wrappers.ChickenController; + +public class SimpleControllersTester extends Command implements Sendable { + + private static final int DEFAULT_JOYSTICK_ID = 0; + private static final int DEFAULT_AXIS_ID = 5; + private static final int DEFAULT_NEXT_BUTTON_ID = 1; + private static final int DEFAULT_PREVIOUS_BUTTON_ID = 2; + + private Joystick joystick; + private int axisId; + + // Is the retrieval time poor, despite the need for a lot of retrievals? Yes. Are we ignoring that + // because the size of the map is small? Also yes. + private NavigableMap controllers = new TreeMap<>(); + + // Do not manually update either of these values. Instead, call setCurrentController() + private ChickenController currentController; + + private SendableChooser controllerChooser = new SendableChooser<>(); + + public SimpleControllersTester(ChickenController... controllers) { + this(new Joystick(DEFAULT_JOYSTICK_ID), DEFAULT_AXIS_ID, DEFAULT_NEXT_BUTTON_ID, + DEFAULT_PREVIOUS_BUTTON_ID, controllers); + } + + public SimpleControllersTester(Joystick joystick, int axisId, int nextButtonId, + int previousButtonId, + ChickenController... controllers) { + this.joystick = joystick; + this.axisId = axisId; + + // Make the buttons go the next and previous controller, or loop around if not available + new JoystickButton(this.joystick, nextButtonId).whenPressed(new SimpleCommand("Next " + + "controller ID", + () -> setCurrentController( + Optional.ofNullable(this.controllers.higherKey(this.currentController.getDeviceID())) + .orElse(this.controllers.firstKey())))); + new JoystickButton(this.joystick, previousButtonId).whenPressed(new SimpleCommand("Previous " + + "controller ID", + () -> setCurrentController( + Optional.ofNullable(this.controllers.lowerKey(this.currentController.getDeviceID())) + .orElse(this.controllers.lastKey())))); + + // Add a chooser that you can use to select the controller and initialize it to null, + // corresponding with buttons should be used + this.controllerChooser.addObject("Use buttons", null); + for (ChickenController controller : controllers) { + this.controllers.put(controller.getDeviceID(), controller); + this.controllerChooser.addObject(String.valueOf(controller.getDeviceID()), + controller.getDeviceID()); + } + + // Set the active controller to the first controller + setCurrentController(controllers[0].getDeviceID()); + + } + + @Override + protected void execute() { + if (controllerChooser.getSelected() != null) { + setCurrentController(controllerChooser.getSelected()); + } + currentController.set(ControlMode.PercentOutput, joystick.getRawAxis(axisId)); + } + + public void setCurrentController(int newId) { + if (currentController != null) { + currentController.set(0); + } + currentController = controllers.get(newId); + } + + @Override + protected boolean isFinished() { + return false; + } + + public SendableChooser getControllerChooser() { + return controllerChooser; + } + + @Override + public void initSendable(SendableBuilder builder) { + builder.addDoubleProperty("Controller ID", () -> this.currentController.getDeviceID(), + (id) -> setCurrentController((int) id)); + } + + public void addAllSendables() { + SmartDashboard.putData("ya", this); + SmartDashboard.putData("yeet", getControllerChooser()); + } + + +} From 9499e2f08812b29974e10124d232960963a5916a Mon Sep 17 00:00:00 2001 From: edelmanjm Date: Wed, 28 Nov 2018 16:38:47 -0800 Subject: [PATCH 02/10] Migrate realConstructor from separate function --- .../rooster/testers/AbstractTester.java | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/lib/src/main/java/org/team1540/rooster/testers/AbstractTester.java b/lib/src/main/java/org/team1540/rooster/testers/AbstractTester.java index 4b44c864..8bc5eecc 100644 --- a/lib/src/main/java/org/team1540/rooster/testers/AbstractTester.java +++ b/lib/src/main/java/org/team1540/rooster/testers/AbstractTester.java @@ -16,25 +16,24 @@ @SuppressWarnings({"unused", "UnstableApiUsage"}) public abstract class AbstractTester implements Tester { + private static float DEFAULT_LOG_TIME = 150; + private static int DEFAULT_UPDATE_DELAY = 2500; + /** * The maximum length of time for which we want to store the results. Note that this is just * used for estimating the queue depth based on the update delay, not actually checked against - * while running. + * while running. Defaults to 150 seconds. */ - private float logTime = 150; + private float logTime; - private int updateDelay = 2500; + private int updateDelay; private boolean running = true; - @SuppressWarnings("NullableProblems") @NotNull List itemsToTest; - @SuppressWarnings("NullableProblems") @NotNull private Function test; - @SuppressWarnings("NullableProblems") @NotNull private List> runConditions; - @SuppressWarnings("NullableProblems") @NotNull private Map> storedResults; @@ -48,7 +47,7 @@ public abstract class AbstractTester implements Tester { */ AbstractTester(@NotNull Function test, @NotNull List itemsToTest, @NotNull List> runConditions) { - realConstructor(test, itemsToTest, runConditions, (int) logTime / (updateDelay / 1000)); + this(test, itemsToTest, runConditions, (int) DEFAULT_LOG_TIME / (DEFAULT_UPDATE_DELAY / 1000)); } /** @@ -63,10 +62,10 @@ public abstract class AbstractTester implements Tester { */ AbstractTester(@NotNull Function test, @NotNull List itemsToTest, @NotNull List> runConditions, float logTime, int updateDelay) { + this(test, itemsToTest, runConditions, + (int) (logTime / ((float) updateDelay / 1000f))); this.logTime = logTime; this.updateDelay = updateDelay; - realConstructor(test, itemsToTest, runConditions, - (int) (logTime / ((float) updateDelay / 1000f))); } /** @@ -80,11 +79,6 @@ public abstract class AbstractTester implements Tester { */ AbstractTester(@NotNull Function test, @NotNull List itemsToTest, @NotNull List> runConditions, int queueDepth) { - realConstructor(test, itemsToTest, runConditions, queueDepth); - } - - private void realConstructor(@NotNull Function test, @NotNull List itemsToTest, - @NotNull List> runConditions, int queueDepth) { this.test = test; this.itemsToTest = itemsToTest; this.runConditions = runConditions; From e366aa6772a32f8faefea4fee8c0f0cdf870c401 Mon Sep 17 00:00:00 2001 From: edelmanjm Date: Wed, 28 Nov 2018 16:53:02 -0800 Subject: [PATCH 03/10] Migrate from ChickenController to IMotorController --- .../rooster/testers/SimpleControllersTester.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/src/main/java/org/team1540/rooster/testers/SimpleControllersTester.java b/lib/src/main/java/org/team1540/rooster/testers/SimpleControllersTester.java index 2428f5e7..9651632a 100644 --- a/lib/src/main/java/org/team1540/rooster/testers/SimpleControllersTester.java +++ b/lib/src/main/java/org/team1540/rooster/testers/SimpleControllersTester.java @@ -1,6 +1,7 @@ package org.team1540.rooster.testers; import com.ctre.phoenix.motorcontrol.ControlMode; +import com.ctre.phoenix.motorcontrol.IMotorController; import edu.wpi.first.wpilibj.Joystick; import edu.wpi.first.wpilibj.Sendable; import edu.wpi.first.wpilibj.buttons.JoystickButton; @@ -12,7 +13,6 @@ import java.util.Optional; import java.util.TreeMap; import org.team1540.rooster.util.SimpleCommand; -import org.team1540.rooster.wrappers.ChickenController; public class SimpleControllersTester extends Command implements Sendable { @@ -26,21 +26,21 @@ public class SimpleControllersTester extends Command implements Sendable { // Is the retrieval time poor, despite the need for a lot of retrievals? Yes. Are we ignoring that // because the size of the map is small? Also yes. - private NavigableMap controllers = new TreeMap<>(); + private NavigableMap controllers = new TreeMap<>(); // Do not manually update either of these values. Instead, call setCurrentController() - private ChickenController currentController; + private IMotorController currentController; private SendableChooser controllerChooser = new SendableChooser<>(); - public SimpleControllersTester(ChickenController... controllers) { + public SimpleControllersTester(IMotorController... controllers) { this(new Joystick(DEFAULT_JOYSTICK_ID), DEFAULT_AXIS_ID, DEFAULT_NEXT_BUTTON_ID, DEFAULT_PREVIOUS_BUTTON_ID, controllers); } public SimpleControllersTester(Joystick joystick, int axisId, int nextButtonId, int previousButtonId, - ChickenController... controllers) { + IMotorController... controllers) { this.joystick = joystick; this.axisId = axisId; @@ -59,7 +59,7 @@ public SimpleControllersTester(Joystick joystick, int axisId, int nextButtonId, // Add a chooser that you can use to select the controller and initialize it to null, // corresponding with buttons should be used this.controllerChooser.addObject("Use buttons", null); - for (ChickenController controller : controllers) { + for (IMotorController controller : controllers) { this.controllers.put(controller.getDeviceID(), controller); this.controllerChooser.addObject(String.valueOf(controller.getDeviceID()), controller.getDeviceID()); @@ -80,7 +80,7 @@ protected void execute() { public void setCurrentController(int newId) { if (currentController != null) { - currentController.set(0); + currentController.set(ControlMode.PercentOutput, 0); } currentController = controllers.get(newId); } From 4a70b481ea363ec36baa00e3441e9948e2175c19 Mon Sep 17 00:00:00 2001 From: edelmanjm Date: Wed, 28 Nov 2018 16:53:40 -0800 Subject: [PATCH 04/10] Suppress warnings --- .../org/team1540/rooster/testers/SimpleControllersTester.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/src/main/java/org/team1540/rooster/testers/SimpleControllersTester.java b/lib/src/main/java/org/team1540/rooster/testers/SimpleControllersTester.java index 9651632a..92a8d37b 100644 --- a/lib/src/main/java/org/team1540/rooster/testers/SimpleControllersTester.java +++ b/lib/src/main/java/org/team1540/rooster/testers/SimpleControllersTester.java @@ -38,6 +38,7 @@ public SimpleControllersTester(IMotorController... controllers) { DEFAULT_PREVIOUS_BUTTON_ID, controllers); } + @SuppressWarnings("WeakerAccess") public SimpleControllersTester(Joystick joystick, int axisId, int nextButtonId, int previousButtonId, IMotorController... controllers) { @@ -78,6 +79,7 @@ protected void execute() { currentController.set(ControlMode.PercentOutput, joystick.getRawAxis(axisId)); } + @SuppressWarnings("WeakerAccess") public void setCurrentController(int newId) { if (currentController != null) { currentController.set(ControlMode.PercentOutput, 0); @@ -90,6 +92,7 @@ protected boolean isFinished() { return false; } + @SuppressWarnings("WeakerAccess") public SendableChooser getControllerChooser() { return controllerChooser; } From ac00ec193d802c7242d9bd111fea208f5c186f54 Mon Sep 17 00:00:00 2001 From: edelmanjm Date: Wed, 28 Nov 2018 17:06:18 -0800 Subject: [PATCH 05/10] Update documentation --- .../testers/SimpleControllersTester.java | 52 +++++++++++++++++-- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/lib/src/main/java/org/team1540/rooster/testers/SimpleControllersTester.java b/lib/src/main/java/org/team1540/rooster/testers/SimpleControllersTester.java index 92a8d37b..bf469447 100644 --- a/lib/src/main/java/org/team1540/rooster/testers/SimpleControllersTester.java +++ b/lib/src/main/java/org/team1540/rooster/testers/SimpleControllersTester.java @@ -14,6 +14,12 @@ import java.util.TreeMap; import org.team1540.rooster.util.SimpleCommand; +/** + * A simple command for testing a series of {@link IMotorController}s. Simply add the + * controllers, specify control bindings or use the defaults, and you're ready! Select the motor in + * the SmartDashboard or move next/previous with buttons and control the percent output of the + * motor with a joystick axis. + */ public class SimpleControllersTester extends Command implements Sendable { private static final int DEFAULT_JOYSTICK_ID = 0; @@ -28,16 +34,32 @@ public class SimpleControllersTester extends Command implements Sendable { // because the size of the map is small? Also yes. private NavigableMap controllers = new TreeMap<>(); - // Do not manually update either of these values. Instead, call setCurrentController() + // Do not manually update this value. Instead, call setCurrentController() private IMotorController currentController; private SendableChooser controllerChooser = new SendableChooser<>(); + /** + * Construct a new instance with the default bindings on {@link Joystick} 0. On an Xbox + * controller, the right thumbstick y-axis controls {@link ControlMode}.PERCENT_OUTPUT, the A + * button goes to the next {@link IMotorController}, and the B button goes to the previous + * {@link IMotorController}. + * + * @param controllers The {@link IMotorController}s to test. + */ public SimpleControllersTester(IMotorController... controllers) { this(new Joystick(DEFAULT_JOYSTICK_ID), DEFAULT_AXIS_ID, DEFAULT_NEXT_BUTTON_ID, DEFAULT_PREVIOUS_BUTTON_ID, controllers); } + /** + * Construct a new instance with the specified bindings. + * @param joystick The joystick port to use. + * @param axisId The axis on the joystick to use. + * @param nextButtonId The button to use to proceed to the next {@link IMotorController}. + * @param previousButtonId The button to use to proceed to the nex {@link IMotorController}. + * @param controllers The {@link IMotorController}s to test. + */ @SuppressWarnings("WeakerAccess") public SimpleControllersTester(Joystick joystick, int axisId, int nextButtonId, int previousButtonId, @@ -71,6 +93,10 @@ public SimpleControllersTester(Joystick joystick, int axisId, int nextButtonId, } + /** + * Checks every tick if the chooser is set to a controller or to use buttons, then sets the + * output according to the value of the active joystick. + */ @Override protected void execute() { if (controllerChooser.getSelected() != null) { @@ -79,6 +105,10 @@ protected void execute() { currentController.set(ControlMode.PercentOutput, joystick.getRawAxis(axisId)); } + /** + * Updates the currently active {@link IMotorController}. + * @param newId The ID of the new {@link IMotorController}. + */ @SuppressWarnings("WeakerAccess") public void setCurrentController(int newId) { if (currentController != null) { @@ -87,25 +117,41 @@ public void setCurrentController(int newId) { currentController = controllers.get(newId); } + /** + * Prevents the command from finishing. + * @return false. + */ @Override protected boolean isFinished() { return false; } + /** + * Gets the chooser used for selecting the current {@link IMotorController}. + * @return A chooser. + */ @SuppressWarnings("WeakerAccess") public SendableChooser getControllerChooser() { return controllerChooser; } + /** + * Adds a single property showing the current active controller. + * @param builder The thing to add the things to. + */ @Override public void initSendable(SendableBuilder builder) { builder.addDoubleProperty("Controller ID", () -> this.currentController.getDeviceID(), (id) -> setCurrentController((int) id)); } + /** + * Add all the sendables to the {@link SmartDashboard}. Includes chooser for selecting the + * active {@link IMotorController} and information about the tester. + */ public void addAllSendables() { - SmartDashboard.putData("ya", this); - SmartDashboard.putData("yeet", getControllerChooser()); + SmartDashboard.putData("Controller tester info", this); + SmartDashboard.putData("Controller choose", getControllerChooser()); } From 9d31424440e87d2a5821d394d796e68873a8f6a6 Mon Sep 17 00:00:00 2001 From: edelmanjm Date: Wed, 28 Nov 2018 17:13:45 -0800 Subject: [PATCH 06/10] Migrate float to double --- .../main/java/org/team1540/rooster/testers/AbstractTester.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/main/java/org/team1540/rooster/testers/AbstractTester.java b/lib/src/main/java/org/team1540/rooster/testers/AbstractTester.java index 8bc5eecc..613c6972 100644 --- a/lib/src/main/java/org/team1540/rooster/testers/AbstractTester.java +++ b/lib/src/main/java/org/team1540/rooster/testers/AbstractTester.java @@ -24,7 +24,7 @@ public abstract class AbstractTester implements Tester { * used for estimating the queue depth based on the update delay, not actually checked against * while running. Defaults to 150 seconds. */ - private float logTime; + private double logTime; private int updateDelay; private boolean running = true; From bd92e00b397f9f5ec64a9b45f0b0da12f0b4ceb0 Mon Sep 17 00:00:00 2001 From: edelmanjm Date: Wed, 28 Nov 2018 17:14:02 -0800 Subject: [PATCH 07/10] Fix plural linking in Javadoc --- .../team1540/rooster/testers/SimpleControllersTester.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/src/main/java/org/team1540/rooster/testers/SimpleControllersTester.java b/lib/src/main/java/org/team1540/rooster/testers/SimpleControllersTester.java index bf469447..fed7c9de 100644 --- a/lib/src/main/java/org/team1540/rooster/testers/SimpleControllersTester.java +++ b/lib/src/main/java/org/team1540/rooster/testers/SimpleControllersTester.java @@ -15,7 +15,8 @@ import org.team1540.rooster.util.SimpleCommand; /** - * A simple command for testing a series of {@link IMotorController}s. Simply add the + * A simple command for testing a series of {@link IMotorController IMotorControllers}. Simply + * add the * controllers, specify control bindings or use the defaults, and you're ready! Select the motor in * the SmartDashboard or move next/previous with buttons and control the percent output of the * motor with a joystick axis. @@ -45,7 +46,7 @@ public class SimpleControllersTester extends Command implements Sendable { * button goes to the next {@link IMotorController}, and the B button goes to the previous * {@link IMotorController}. * - * @param controllers The {@link IMotorController}s to test. + * @param controllers The {@link IMotorController IMotorControllers} to test. */ public SimpleControllersTester(IMotorController... controllers) { this(new Joystick(DEFAULT_JOYSTICK_ID), DEFAULT_AXIS_ID, DEFAULT_NEXT_BUTTON_ID, @@ -58,7 +59,7 @@ public SimpleControllersTester(IMotorController... controllers) { * @param axisId The axis on the joystick to use. * @param nextButtonId The button to use to proceed to the next {@link IMotorController}. * @param previousButtonId The button to use to proceed to the nex {@link IMotorController}. - * @param controllers The {@link IMotorController}s to test. + * @param controllers The {@link IMotorController IMotorControllers} to test. */ @SuppressWarnings("WeakerAccess") public SimpleControllersTester(Joystick joystick, int axisId, int nextButtonId, From d8675a24aa9ff462b31d8b5b0b0add00f8f67e4c Mon Sep 17 00:00:00 2001 From: edelmanjm Date: Wed, 28 Nov 2018 17:16:07 -0800 Subject: [PATCH 08/10] Migrate field logTime to local variable --- .../org/team1540/rooster/testers/AbstractTester.java | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/lib/src/main/java/org/team1540/rooster/testers/AbstractTester.java b/lib/src/main/java/org/team1540/rooster/testers/AbstractTester.java index 613c6972..b6562d35 100644 --- a/lib/src/main/java/org/team1540/rooster/testers/AbstractTester.java +++ b/lib/src/main/java/org/team1540/rooster/testers/AbstractTester.java @@ -19,13 +19,6 @@ public abstract class AbstractTester implements Tester { private static float DEFAULT_LOG_TIME = 150; private static int DEFAULT_UPDATE_DELAY = 2500; - /** - * The maximum length of time for which we want to store the results. Note that this is just - * used for estimating the queue depth based on the update delay, not actually checked against - * while running. Defaults to 150 seconds. - */ - private double logTime; - private int updateDelay; private boolean running = true; @NotNull @@ -57,14 +50,15 @@ public abstract class AbstractTester implements Tester { * @param itemsToTest The items to apply the test to. * @param runConditions The conditions that must be met before the test will be executed on an * item. - * @param logTime The maximum length of time for which we want to store the results. + * @param logTime The maximum length of time for which we want to store the results. Note that + * this is just used for estimating the queue depth based on the update delay, not actually + * checked against while running. * @param updateDelay The delay between the test being run on the items. */ AbstractTester(@NotNull Function test, @NotNull List itemsToTest, @NotNull List> runConditions, float logTime, int updateDelay) { this(test, itemsToTest, runConditions, (int) (logTime / ((float) updateDelay / 1000f))); - this.logTime = logTime; this.updateDelay = updateDelay; } From 7b34ccd8672e1e1a60cc1662582dbae5bcbb4d48 Mon Sep 17 00:00:00 2001 From: edelmanjm Date: Wed, 28 Nov 2018 17:18:32 -0800 Subject: [PATCH 09/10] Add testing package to README --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 5a1cd765..039138b0 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,14 @@ A flexible, dynamic power management system. Uses a centralized `PowerManager` t A system to easily set tuning fields through WPILib `Preferences`. +#### Testing + +`org.team1540.rooster.testers` + +Various classes for testing common things. +- `BurnoutTester` for testing if motors are burned out. +- `SimpleControllersTester` for easily running motors. + #### Triggers `org.team1540.rooster.triggers` From 3de44f75de0871bf2bafd305aabe552e4b47e3b2 Mon Sep 17 00:00:00 2001 From: edelmanjm Date: Wed, 28 Nov 2018 17:18:51 -0800 Subject: [PATCH 10/10] Fix spacing in Javadoc --- .../team1540/rooster/testers/SimpleControllersTester.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/src/main/java/org/team1540/rooster/testers/SimpleControllersTester.java b/lib/src/main/java/org/team1540/rooster/testers/SimpleControllersTester.java index fed7c9de..e01226f7 100644 --- a/lib/src/main/java/org/team1540/rooster/testers/SimpleControllersTester.java +++ b/lib/src/main/java/org/team1540/rooster/testers/SimpleControllersTester.java @@ -16,10 +16,9 @@ /** * A simple command for testing a series of {@link IMotorController IMotorControllers}. Simply - * add the - * controllers, specify control bindings or use the defaults, and you're ready! Select the motor in - * the SmartDashboard or move next/previous with buttons and control the percent output of the - * motor with a joystick axis. + * add the controllers, specify control bindings or use the defaults, and you're ready! Select + * the motor in the SmartDashboard or move next/previous with buttons and control the percent + * output of the motor with a joystick axis. */ public class SimpleControllersTester extends Command implements Sendable {