Skip to content

Commit

Permalink
Merge pull request #31 from flamingchickens1540/adjustable-manager
Browse files Browse the repository at this point in the history
Improve AdjustableManager
  • Loading branch information
RobinsonZ authored Jan 27, 2018
2 parents f0f54bc + ae229b9 commit 9c18212
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 29 deletions.
2 changes: 1 addition & 1 deletion .idea/modules/ROOSTER_main.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/modules/ROOSTER_test.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

75 changes: 50 additions & 25 deletions src/main/java/org/team1540/base/adjustables/AdjustableManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -19,6 +20,12 @@ public class AdjustableManager {
private List<TunableField> tunables = new LinkedList<>();
private List<TelemetryField> telemetry = new LinkedList<>();

private boolean enabled = true;

private AdjustableManager() {
new SimpleLoopCommand("AdjustableManager Update", this::run).start();
}

public static AdjustableManager getInstance() {
return instance;
}
Expand Down Expand Up @@ -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;
Expand All @@ -143,6 +159,7 @@ public TunableField(Object obj, Field field, TunableType type, String label) {
}

private static class TelemetryField {

Object obj;
Field field;
TelemetryType type;
Expand All @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -44,7 +45,6 @@ public void robotPeriodic() {
iTimes2 = i * 2;
stringPlusChickens = string + "Chickens";
notB = !b;

AdjustableManager.getInstance().update();
Scheduler.getInstance().run();
}
}
52 changes: 52 additions & 0 deletions src/main/java/org/team1540/base/util/SimpleLoopCommand.java
Original file line number Diff line number Diff line change
@@ -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. <p> 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:
* <pre>
* Command shift = new SimpleLoopCommand(() -&gt; Robot.shifter.shift(), Robot.shifter);
* </pre>
*
* Multiple {@code Subystems} can be added onto the end of the constructor to add multiple
* requirements. <p> 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;
}
}

0 comments on commit 9c18212

Please sign in to comment.