From 080eb885e51825ec52c4b2a3f8ff44e7e5b1f3f9 Mon Sep 17 00:00:00 2001 From: Zachary Robinson Date: Fri, 26 Jan 2018 17:57:07 -0800 Subject: [PATCH 1/4] Create SimpleLoopCommand --- .../team1540/base/util/SimpleLoopCommand.java | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/main/java/org/team1540/base/util/SimpleLoopCommand.java diff --git a/src/main/java/org/team1540/base/util/SimpleLoopCommand.java b/src/main/java/org/team1540/base/util/SimpleLoopCommand.java new file mode 100644 index 00000000..35e2da94 --- /dev/null +++ b/src/main/java/org/team1540/base/util/SimpleLoopCommand.java @@ -0,0 +1,52 @@ +package org.team1540.base.util; + +import edu.wpi.first.wpilibj.Sendable; +import edu.wpi.first.wpilibj.command.Command; +import edu.wpi.first.wpilibj.command.Subsystem; +import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; + +/** + * A simple way to construct a {@link Command} which executes every tick.

To create a {@code + * SimpleLoopCommand} easily, simply pass it a no-argument lambda containing the code you would like + * to execute. For example, to create a {@link Command} that requires the {@code Robot.shifter} + * {@link Subsystem}, simply write: + *

+ *   Command shift = new SimpleLoopCommand(() -> Robot.shifter.shift(), Robot.shifter);
+ * 
+ * + * Multiple {@code Subystems} can be added onto the end of the constructor to add multiple + * requirements.

This can be used to quickly and easily put a button on the + * SmartDashboard/Shuffleboard to run some code. Use {@link SmartDashboard#putData(Sendable)} to + * pass it a newly created instance of this class. + */ +public class SimpleLoopCommand extends Command { + + private Executable executable; + + /** + * Creates a new {@code SimpleLoopCommand}. + * + * @param name The name of the commmand. This is required to avoid everything being called + * SimpleCommand. + * @param action The code to run when the command executes. + * @param requirements The {@link Subsystem Subsystems} required by the command (if any). + */ + public SimpleLoopCommand(String name, Executable action, Subsystem... requirements) { + super(name); + executable = action; + + for (Subsystem requirement : requirements) { + requires(requirement); // java_irl + } + } + + @Override + protected void execute() { + executable.execute(); + } + + @Override + protected boolean isFinished() { + return false; + } +} From 4af1c3d5aa7490d212382ceabf4980a5a828bc71 Mon Sep 17 00:00:00 2001 From: Zachary Robinson Date: Fri, 26 Jan 2018 18:06:48 -0800 Subject: [PATCH 2/4] Remove AdjustableManager manual update requirement Now creates a command that loops, and works as long as you're calling Scheduler.getInstance.run(). --- .../base/adjustables/AdjustableManager.java | 75 ++++++++++++------- .../base/testing/AdjustableTestRobot.java | 2 - 2 files changed, 50 insertions(+), 27 deletions(-) diff --git a/src/main/java/org/team1540/base/adjustables/AdjustableManager.java b/src/main/java/org/team1540/base/adjustables/AdjustableManager.java index 429c7b70..a36ff9c2 100644 --- a/src/main/java/org/team1540/base/adjustables/AdjustableManager.java +++ b/src/main/java/org/team1540/base/adjustables/AdjustableManager.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import java.util.LinkedList; import java.util.List; +import org.team1540.base.util.SimpleLoopCommand; /** * Class to manage creating and updating adjustables (tunables and telemetry values.) Add an object @@ -19,6 +20,12 @@ public class AdjustableManager { private List tunables = new LinkedList<>(); private List telemetry = new LinkedList<>(); + private boolean enabled = true; + + private AdjustableManager() { + new SimpleLoopCommand("AdjustableManager Update", this::run).start(); + } + public static AdjustableManager getInstance() { return instance; } @@ -95,40 +102,49 @@ public void add(Object object) { } } - /** - * Updates adjustable values. This method should be called in {@code robotPeriodic()} in your main - * {@code Robot} class. - */ - public void update() { - synchronized (lock) { - // Update tunables - for (TunableField tf : tunables) { - try { - if (!SmartDashboard.containsKey(tf.label)) { - //noinspection unchecked - tf.type.putFunction.put(tf.label, tf.field.get(tf.obj)); - } else { - //noinspection unchecked - tf.field.set(tf.obj, tf.type.getFunction.get(tf.label, tf.field.get(tf.obj))); + private void run() { + if (enabled) { + synchronized (lock) { + // Update tunables + for (TunableField tf : tunables) { + try { + if (!SmartDashboard.containsKey(tf.label)) { + //noinspection unchecked + tf.type.putFunction.put(tf.label, tf.field.get(tf.obj)); + } else { + //noinspection unchecked + tf.field.set(tf.obj, tf.type.getFunction.get(tf.label, tf.field.get(tf.obj))); + } + } catch (IllegalAccessException e) { + DriverStation.reportError(e.getMessage(), true); } - } catch (IllegalAccessException e) { - DriverStation.reportError(e.getMessage(), true); } - } - // Update telemetry - for (TelemetryField tf : telemetry) { - try { - //noinspection unchecked - tf.type.putFunction.put(tf.label, tf.field.get(tf.obj)); - } catch (IllegalAccessException e) { - DriverStation.reportError(e.toString(), true); + // Update telemetry + for (TelemetryField tf : telemetry) { + try { + //noinspection unchecked + tf.type.putFunction.put(tf.label, tf.field.get(tf.obj)); + } catch (IllegalAccessException e) { + DriverStation.reportError(e.toString(), true); + } } } } } + /** + * Updates adjustable values. This method should be called in {@code robotPeriodic()} in your main + * {@code Robot} class. + * + * @deprecated No longer necessary; now updates automatically. + */ + public void update() { + run(); + } + private static class TunableField { + Object obj; Field field; TunableType type; @@ -143,6 +159,7 @@ public TunableField(Object obj, Field field, TunableType type, String label) { } private static class TelemetryField { + Object obj; Field field; TelemetryType type; @@ -155,4 +172,12 @@ public TelemetryField(Object obj, Field field, TelemetryType type, String label) this.label = label; } } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } } diff --git a/src/main/java/org/team1540/base/testing/AdjustableTestRobot.java b/src/main/java/org/team1540/base/testing/AdjustableTestRobot.java index 58b5e43d..7c023e7a 100644 --- a/src/main/java/org/team1540/base/testing/AdjustableTestRobot.java +++ b/src/main/java/org/team1540/base/testing/AdjustableTestRobot.java @@ -44,7 +44,5 @@ public void robotPeriodic() { iTimes2 = i * 2; stringPlusChickens = string + "Chickens"; notB = !b; - - AdjustableManager.getInstance().update(); } } From 0737d28ca28b0ef22c0f346cc431e7cda03d2b2a Mon Sep 17 00:00:00 2001 From: Zachary Robinson Date: Fri, 26 Jan 2018 18:09:38 -0800 Subject: [PATCH 3/4] Update WPILib version --- .idea/modules/ROOSTER_main.iml | 2 +- .idea/modules/ROOSTER_test.iml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.idea/modules/ROOSTER_main.iml b/.idea/modules/ROOSTER_main.iml index 2e72f755..a413baf4 100644 --- a/.idea/modules/ROOSTER_main.iml +++ b/.idea/modules/ROOSTER_main.iml @@ -9,7 +9,7 @@ - + diff --git a/.idea/modules/ROOSTER_test.iml b/.idea/modules/ROOSTER_test.iml index 18441e97..fec6dec3 100644 --- a/.idea/modules/ROOSTER_test.iml +++ b/.idea/modules/ROOSTER_test.iml @@ -10,7 +10,7 @@ - + From ae229b918a66bf1de4e25c8d42ba34cc17737dbd Mon Sep 17 00:00:00 2001 From: Zachary Robinson Date: Fri, 26 Jan 2018 18:13:23 -0800 Subject: [PATCH 4/4] Add scheduler updates --- .../java/org/team1540/base/testing/AdjustableTestRobot.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/org/team1540/base/testing/AdjustableTestRobot.java b/src/main/java/org/team1540/base/testing/AdjustableTestRobot.java index 7c023e7a..8c05dba2 100644 --- a/src/main/java/org/team1540/base/testing/AdjustableTestRobot.java +++ b/src/main/java/org/team1540/base/testing/AdjustableTestRobot.java @@ -3,6 +3,7 @@ import edu.wpi.first.wpilibj.IterativeRobot; import edu.wpi.first.wpilibj.Sendable; import edu.wpi.first.wpilibj.Solenoid; +import edu.wpi.first.wpilibj.command.Scheduler; import org.team1540.base.adjustables.AdjustableManager; import org.team1540.base.adjustables.Telemetry; import org.team1540.base.adjustables.Tunable; @@ -44,5 +45,6 @@ public void robotPeriodic() { iTimes2 = i * 2; stringPlusChickens = string + "Chickens"; notB = !b; + Scheduler.getInstance().run(); } }