From e2bf787705acce2f764565e983cae04fd282d278 Mon Sep 17 00:00:00 2001 From: Debajit Ghosh Date: Sun, 10 Mar 2024 09:24:46 -0700 Subject: [PATCH 01/15] rename OICondition to Condition, since this class is within OIFragment. --- .../com/team766/framework/OIFragment.java | 20 +++++++++---------- .../com/team766/robot/common/DriverOI.java | 4 ++-- .../java/com/team766/robot/reva/BoxOpOI.java | 12 +++++------ .../java/com/team766/robot/reva/DebugOI.java | 20 +++++++++---------- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/main/java/com/team766/framework/OIFragment.java b/src/main/java/com/team766/framework/OIFragment.java index db7af9c4f..2cdd337b3 100644 --- a/src/main/java/com/team766/framework/OIFragment.java +++ b/src/main/java/com/team766/framework/OIFragment.java @@ -5,24 +5,24 @@ import java.util.function.BooleanSupplier; /** - * Fragment of an OI, with facilities to make it easy to set up {@link OICondition}s for usage in the fragment's + * Fragment of an OI, with facilities to make it easy to set up {@link Condition}s for usage in the fragment's * {@link #handleOI} method. * * The overall OI for a robot will contain a set of fragments, typically one per set of controls (eg, driver, boxop, debug), * and it will call {@link #runOI(Context)} once per its own loop. During each call to {@link #runOI}, the fragment - * will evaluate any {@link OICondition}s that were created for this fragment. This simplifies OI logic that checks if a + * will evaluate any {@link Condition}s that were created for this fragment. This simplifies OI logic that checks if a * specific condition is currently triggering (eg pressing or holding down a joystick button) or if a condition that had been triggering * in a previous iteration of the OI loop is no longer triggering in this iteration. */ public abstract class OIFragment extends LoggingBase { - protected class OICondition { + protected class Condition { private final BooleanSupplier condition; private boolean triggering = false; private boolean newlyTriggering = false; private boolean finishedTriggering = false; - public OICondition(BooleanSupplier condition) { + public Condition(BooleanSupplier condition) { this.condition = condition; register(this); } @@ -53,7 +53,7 @@ public boolean isFinishedTriggering() { } private final String name; - private final List conditions = new LinkedList(); + private final List conditions = new LinkedList(); /** * Creates a new OIFragment. @@ -67,7 +67,7 @@ public final String getName() { return name; } - private void register(OICondition condition) { + private void register(Condition condition) { conditions.add(condition); } @@ -79,10 +79,10 @@ protected void handlePre() {} /** * OIFragments must override this method to implement their OI logic. Typically called via the overall - * OI's loop, once per iteration through the loop. Can use any {@link OICondition}s - * they have set up to simplify checking if the {@link OICondition} is {@link OICondition#isTriggering()}, + * OI's loop, once per iteration through the loop. Can use any {@link Condition}s + * they have set up to simplify checking if the {@link Condition} is {@link Condition#isTriggering()}, * or, if it had been triggering in a previous iteration of the loop, if it is now - * {@link OICondition#isFinishedTriggering()}. + * {@link Condition#isFinishedTriggering()}. * * @param context The {@link Context} running the OI. */ @@ -100,7 +100,7 @@ protected void handlePost() {} */ public final void runOI(Context context) { handlePre(); - for (OICondition condition : conditions) { + for (Condition condition : conditions) { condition.evaluate(); } handleOI(context); diff --git a/src/main/java/com/team766/robot/common/DriverOI.java b/src/main/java/com/team766/robot/common/DriverOI.java index e06be0fba..fe4540946 100644 --- a/src/main/java/com/team766/robot/common/DriverOI.java +++ b/src/main/java/com/team766/robot/common/DriverOI.java @@ -19,7 +19,7 @@ public class DriverOI extends OIFragment { protected double leftJoystickY = 0; protected boolean isCross = false; - private final OICondition movingJoysticks; + private final Condition movingJoysticks; public DriverOI(Drive drive, JoystickReader leftJoystick, JoystickReader rightJoystick) { super("DriverOI"); @@ -28,7 +28,7 @@ public DriverOI(Drive drive, JoystickReader leftJoystick, JoystickReader rightJo this.rightJoystick = rightJoystick; movingJoysticks = - new OICondition( + new Condition( () -> !isCross && Math.abs(leftJoystickX) diff --git a/src/main/java/com/team766/robot/reva/BoxOpOI.java b/src/main/java/com/team766/robot/reva/BoxOpOI.java index 92d940cf4..56517d60d 100644 --- a/src/main/java/com/team766/robot/reva/BoxOpOI.java +++ b/src/main/java/com/team766/robot/reva/BoxOpOI.java @@ -19,9 +19,9 @@ public class BoxOpOI extends OIFragment { private final Shooter shooter; private final Climber climber; - private final OICondition shooterShoot; - private final OICondition intakeOut; - private final OICondition intakeIn; + private final Condition shooterShoot; + private final Condition intakeOut; + private final Condition intakeIn; public BoxOpOI( JoystickReader gamepad, @@ -36,9 +36,9 @@ public BoxOpOI( this.shooter = shooter; this.climber = climber; - shooterShoot = new OICondition(() -> gamepad.getAxis(InputConstants.XBOX_RT) > 0); - intakeOut = new OICondition(() -> gamepad.getButton(InputConstants.XBOX_RB)); - intakeIn = new OICondition(() -> gamepad.getButton(InputConstants.XBOX_LB)); + shooterShoot = new Condition(() -> gamepad.getAxis(InputConstants.XBOX_RT) > 0); + intakeOut = new Condition(() -> gamepad.getButton(InputConstants.XBOX_RB)); + intakeIn = new Condition(() -> gamepad.getButton(InputConstants.XBOX_LB)); } @Override diff --git a/src/main/java/com/team766/robot/reva/DebugOI.java b/src/main/java/com/team766/robot/reva/DebugOI.java index 702482816..0c8896a02 100644 --- a/src/main/java/com/team766/robot/reva/DebugOI.java +++ b/src/main/java/com/team766/robot/reva/DebugOI.java @@ -39,11 +39,11 @@ public class DebugOI extends OIFragment { private final Climber climber; private final Intake intake; private final Shooter shooter; - private final OICondition controlShoulder; - private final OICondition controlClimber; - private final OICondition controlShooter; - private final OICondition intakeIn; - private final OICondition intakeOut; + private final Condition controlShoulder; + private final Condition controlClimber; + private final Condition controlShooter; + private final Condition intakeIn; + private final Condition intakeOut; public DebugOI( JoystickReader macropad, @@ -59,11 +59,11 @@ public DebugOI( this.shooter = shooter; controlShoulder = - new OICondition(() -> macropad.getButton(InputConstants.CONTROL_SHOULDER)); - controlClimber = new OICondition(() -> macropad.getButton(InputConstants.CONTROL_CLIMBER)); - controlShooter = new OICondition(() -> macropad.getButton(InputConstants.CONTROL_SHOOTER)); - intakeIn = new OICondition(() -> macropad.getButton(InputConstants.INTAKE_IN)); - intakeOut = new OICondition(() -> macropad.getButton(InputConstants.INTAKE_OUT)); + new Condition(() -> macropad.getButton(InputConstants.CONTROL_SHOULDER)); + controlClimber = new Condition(() -> macropad.getButton(InputConstants.CONTROL_CLIMBER)); + controlShooter = new Condition(() -> macropad.getButton(InputConstants.CONTROL_SHOOTER)); + intakeIn = new Condition(() -> macropad.getButton(InputConstants.INTAKE_IN)); + intakeOut = new Condition(() -> macropad.getButton(InputConstants.INTAKE_OUT)); } @Override From 22476ed9801183a55574a3228616e36ad40e070f Mon Sep 17 00:00:00 2001 From: Debajit Ghosh Date: Sun, 10 Mar 2024 09:26:08 -0700 Subject: [PATCH 02/15] added comment to Math.interpolate javadoc --- src/main/java/com/team766/math/Math.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/team766/math/Math.java b/src/main/java/com/team766/math/Math.java index 8270533d4..7f6bce485 100644 --- a/src/main/java/com/team766/math/Math.java +++ b/src/main/java/com/team766/math/Math.java @@ -29,6 +29,7 @@ public static double normalizeAngleDegrees(double angle) { /** * Performs simple linear interpolation (as described in * https://en.wikipedia.org/wiki/Linear_interpolation) of data in an array of type T. + * NOTE: the data array must be sorted by x, from lowest to highest. * * The x values (eg measured data and target data point) should be available via a getter in T. * The y values (what this interpolates from measured data) should be available via a getter in T. From 31007cba43a69aca5c2a4b2f8fa2d7afd9e0228e Mon Sep 17 00:00:00 2001 From: Debajit Ghosh Date: Sun, 10 Mar 2024 09:50:08 -0700 Subject: [PATCH 03/15] add example DriverOI that uses OI fragments and conditions --- .../com/team766/framework/OIFragment.java | 2 + src/main/java/com/team766/math/Math.java | 2 +- .../com/team766/robot/example/DriverOI.java | 38 +++++++++++++++++++ .../java/com/team766/robot/example/OI.java | 20 +++++----- .../java/com/team766/robot/reva/DebugOI.java | 3 +- 5 files changed, 53 insertions(+), 12 deletions(-) create mode 100644 src/main/java/com/team766/robot/example/DriverOI.java diff --git a/src/main/java/com/team766/framework/OIFragment.java b/src/main/java/com/team766/framework/OIFragment.java index 2cdd337b3..c9f042829 100644 --- a/src/main/java/com/team766/framework/OIFragment.java +++ b/src/main/java/com/team766/framework/OIFragment.java @@ -1,5 +1,6 @@ package com.team766.framework; +import com.team766.logging.Category; import java.util.LinkedList; import java.util.List; import java.util.function.BooleanSupplier; @@ -60,6 +61,7 @@ public boolean isFinishedTriggering() { * @param name The name of this part of the OI (eg, "BoxOpOI"). Used for logging. */ public OIFragment(String name) { + loggerCategory = Category.OPERATOR_INTERFACE; this.name = name; } diff --git a/src/main/java/com/team766/math/Math.java b/src/main/java/com/team766/math/Math.java index 7f6bce485..8a475412d 100644 --- a/src/main/java/com/team766/math/Math.java +++ b/src/main/java/com/team766/math/Math.java @@ -39,7 +39,7 @@ public static double normalizeAngleDegrees(double angle) { * public record Data(double x, double y); * ... * Data[] data = new Data[] { new Data(0.0, 1.0), new Data(1.0, 32.0), ... }; - * Math.interpolate(data, 0.5, Data::x, Data::y); + * double interpolatedY = Math.interpolate(data, 0.5, Data::x, Data::y); * * * @param The class containing the x and y data. diff --git a/src/main/java/com/team766/robot/example/DriverOI.java b/src/main/java/com/team766/robot/example/DriverOI.java new file mode 100644 index 000000000..fd4468290 --- /dev/null +++ b/src/main/java/com/team766/robot/example/DriverOI.java @@ -0,0 +1,38 @@ +package com.team766.robot.example; + +import com.team766.framework.Context; +import com.team766.framework.OIFragment; +import com.team766.hal.JoystickReader; +import com.team766.robot.example.procedures.*; + +public class DriverOI extends OIFragment { + private final JoystickReader leftJoystick; + + // add mechanisms here + + // add any conditions (joystick inputs, etc) + Condition button0; + Condition moveJoystick; + + // add any mechanisms to the constructor arguments as well + public DriverOI(JoystickReader leftJoystick) { + super("DriverOI"); + this.leftJoystick = leftJoystick; + + button0 = new Condition(() -> leftJoystick.getButton(0)); + moveJoystick = new Condition(() -> leftJoystick.getAxis(0) > 0); + } + + @Override + protected void handleOI(Context context) { + if (button0.isNewlyTriggering()) { + // handle button press + } else if (button0.isFinishedTriggering()) { + // handle button release + } + + if (moveJoystick.isTriggering()) { + // handle joystick movement + } + } +} diff --git a/src/main/java/com/team766/robot/example/OI.java b/src/main/java/com/team766/robot/example/OI.java index ba3a45ee4..ca16c6f25 100644 --- a/src/main/java/com/team766/robot/example/OI.java +++ b/src/main/java/com/team766/robot/example/OI.java @@ -5,23 +5,25 @@ import com.team766.hal.JoystickReader; import com.team766.hal.RobotProvider; import com.team766.logging.Category; -import com.team766.robot.example.procedures.*; /** * This class is the glue that binds the controls on the physical operator * interface to the code that allow control of the robot. */ public class OI extends Procedure { - private JoystickReader joystick0; - private JoystickReader joystick1; - private JoystickReader joystick2; + // input devices + private final JoystickReader leftJoystick; + private final JoystickReader gamepad; + + // OIFragments (driver, boxop, etc) + private final DriverOI driverOI; public OI() { loggerCategory = Category.OPERATOR_INTERFACE; - joystick0 = RobotProvider.instance.getJoystick(0); - joystick1 = RobotProvider.instance.getJoystick(1); - joystick2 = RobotProvider.instance.getJoystick(2); + leftJoystick = RobotProvider.instance.getJoystick(0); + gamepad = RobotProvider.instance.getJoystick(1); + driverOI = new DriverOI(leftJoystick); } public void run(final Context context) { @@ -30,8 +32,8 @@ public void run(final Context context) { context.waitFor(() -> RobotProvider.instance.hasNewDriverStationData()); RobotProvider.instance.refreshDriverStationData(); - // Add driver controls here - make sure to take/release ownership - // of mechanisms when appropriate. + // call each of the OI fragment's runOI methods. + driverOI.runOI(context); } } } diff --git a/src/main/java/com/team766/robot/reva/DebugOI.java b/src/main/java/com/team766/robot/reva/DebugOI.java index 0c8896a02..c461972d9 100644 --- a/src/main/java/com/team766/robot/reva/DebugOI.java +++ b/src/main/java/com/team766/robot/reva/DebugOI.java @@ -58,8 +58,7 @@ public DebugOI( this.intake = intake; this.shooter = shooter; - controlShoulder = - new Condition(() -> macropad.getButton(InputConstants.CONTROL_SHOULDER)); + controlShoulder = new Condition(() -> macropad.getButton(InputConstants.CONTROL_SHOULDER)); controlClimber = new Condition(() -> macropad.getButton(InputConstants.CONTROL_CLIMBER)); controlShooter = new Condition(() -> macropad.getButton(InputConstants.CONTROL_SHOOTER)); intakeIn = new Condition(() -> macropad.getButton(InputConstants.INTAKE_IN)); From bd9f4b75ecf425755ef05983e77e267dfedbe863 Mon Sep 17 00:00:00 2001 From: Debajit Ghosh Date: Sun, 10 Mar 2024 09:54:51 -0700 Subject: [PATCH 04/15] move Math changes to another branch --- src/main/java/com/team766/math/Math.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/team766/math/Math.java b/src/main/java/com/team766/math/Math.java index 8a475412d..8270533d4 100644 --- a/src/main/java/com/team766/math/Math.java +++ b/src/main/java/com/team766/math/Math.java @@ -29,7 +29,6 @@ public static double normalizeAngleDegrees(double angle) { /** * Performs simple linear interpolation (as described in * https://en.wikipedia.org/wiki/Linear_interpolation) of data in an array of type T. - * NOTE: the data array must be sorted by x, from lowest to highest. * * The x values (eg measured data and target data point) should be available via a getter in T. * The y values (what this interpolates from measured data) should be available via a getter in T. @@ -39,7 +38,7 @@ public static double normalizeAngleDegrees(double angle) { * public record Data(double x, double y); * ... * Data[] data = new Data[] { new Data(0.0, 1.0), new Data(1.0, 32.0), ... }; - * double interpolatedY = Math.interpolate(data, 0.5, Data::x, Data::y); + * Math.interpolate(data, 0.5, Data::x, Data::y); * * * @param The class containing the x and y data. From 56c761879d9a0318568ec4bd30eae26f55207884 Mon Sep 17 00:00:00 2001 From: Debajit Ghosh Date: Sun, 10 Mar 2024 21:31:03 -0700 Subject: [PATCH 05/15] addressing PR comments --- .../com/team766/robot/example/DriverOI.java | 25 +++++++++++++------ .../example/constants/InputConstants.java | 11 ++++++++ 2 files changed, 28 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/team766/robot/example/constants/InputConstants.java diff --git a/src/main/java/com/team766/robot/example/DriverOI.java b/src/main/java/com/team766/robot/example/DriverOI.java index fd4468290..daa63a7cb 100644 --- a/src/main/java/com/team766/robot/example/DriverOI.java +++ b/src/main/java/com/team766/robot/example/DriverOI.java @@ -3,31 +3,40 @@ import com.team766.framework.Context; import com.team766.framework.OIFragment; import com.team766.hal.JoystickReader; +import com.team766.robot.example.constants.InputConstants; import com.team766.robot.example.procedures.*; public class DriverOI extends OIFragment { - private final JoystickReader leftJoystick; + private final JoystickReader joystick; + private double joystickX; + private double joystickY; // add mechanisms here // add any conditions (joystick inputs, etc) - Condition button0; + Condition button1; Condition moveJoystick; // add any mechanisms to the constructor arguments as well - public DriverOI(JoystickReader leftJoystick) { + public DriverOI(JoystickReader joystick) { super("DriverOI"); - this.leftJoystick = leftJoystick; + this.joystick = joystick; - button0 = new Condition(() -> leftJoystick.getButton(0)); - moveJoystick = new Condition(() -> leftJoystick.getAxis(0) > 0); + button1 = new Condition(() -> joystick.getButton(InputConstants.BUTTON_TRIGGER)); + moveJoystick = new Condition(() -> Math.abs(joystickX) > 0 || Math.abs(joystickY) > 0); + } + + @Override + protected void handlePre() { + joystickX = joystick.getAxis(InputConstants.AXIS_X); + joystickY = joystick.getAxis(InputConstants.AXIS_Y); } @Override protected void handleOI(Context context) { - if (button0.isNewlyTriggering()) { + if (button1.isNewlyTriggering()) { // handle button press - } else if (button0.isFinishedTriggering()) { + } else if (button1.isFinishedTriggering()) { // handle button release } diff --git a/src/main/java/com/team766/robot/example/constants/InputConstants.java b/src/main/java/com/team766/robot/example/constants/InputConstants.java new file mode 100644 index 000000000..d3527b8c0 --- /dev/null +++ b/src/main/java/com/team766/robot/example/constants/InputConstants.java @@ -0,0 +1,11 @@ +package com.team766.robot.example.constants; + +public class InputConstants { + // this class only contains constants - instances should never be instantiated + private InputConstants() {} + + public static final int AXIS_X = 0; + public static final int AXIS_Y = 1; + + public static final int BUTTON_TRIGGER = 1; +} From a8b0e939ce969a751f45557f9a5fa4a2691129a9 Mon Sep 17 00:00:00 2001 From: Debajit Ghosh Date: Sun, 10 Mar 2024 22:32:35 -0700 Subject: [PATCH 06/15] addressing comments --- src/main/java/com/team766/robot/example/DriverOI.java | 2 -- .../com/team766/robot/example/constants/InputConstants.java | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/com/team766/robot/example/DriverOI.java b/src/main/java/com/team766/robot/example/DriverOI.java index daa63a7cb..7bc5dfab6 100644 --- a/src/main/java/com/team766/robot/example/DriverOI.java +++ b/src/main/java/com/team766/robot/example/DriverOI.java @@ -11,8 +11,6 @@ public class DriverOI extends OIFragment { private double joystickX; private double joystickY; - // add mechanisms here - // add any conditions (joystick inputs, etc) Condition button1; Condition moveJoystick; diff --git a/src/main/java/com/team766/robot/example/constants/InputConstants.java b/src/main/java/com/team766/robot/example/constants/InputConstants.java index d3527b8c0..ae21dc791 100644 --- a/src/main/java/com/team766/robot/example/constants/InputConstants.java +++ b/src/main/java/com/team766/robot/example/constants/InputConstants.java @@ -1,7 +1,7 @@ package com.team766.robot.example.constants; public class InputConstants { - // this class only contains constants - instances should never be instantiated + // this class only contains constants - should never be instantiated private InputConstants() {} public static final int AXIS_X = 0; From a28ab668398089e451c8aa8dbffa61e2e5edcd6d Mon Sep 17 00:00:00 2001 From: Debajit Ghosh Date: Sun, 10 Mar 2024 22:33:31 -0700 Subject: [PATCH 07/15] making Condition members in example private --- src/main/java/com/team766/robot/example/DriverOI.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/team766/robot/example/DriverOI.java b/src/main/java/com/team766/robot/example/DriverOI.java index 7bc5dfab6..d67355d62 100644 --- a/src/main/java/com/team766/robot/example/DriverOI.java +++ b/src/main/java/com/team766/robot/example/DriverOI.java @@ -12,8 +12,8 @@ public class DriverOI extends OIFragment { private double joystickY; // add any conditions (joystick inputs, etc) - Condition button1; - Condition moveJoystick; + private Condition button1; + private Condition moveJoystick; // add any mechanisms to the constructor arguments as well public DriverOI(JoystickReader joystick) { From 6564a8460dfe02cf0c9967040fbbd5f6c54131e3 Mon Sep 17 00:00:00 2001 From: Debajit Ghosh Date: Mon, 11 Mar 2024 19:27:38 -0700 Subject: [PATCH 08/15] remove pre/postOI. have subclasses of OIFragment call evaluateConditions(). --- .../com/team766/framework/OIFragment.java | 29 ++++++++++--------- .../com/team766/robot/common/DriverOI.java | 2 ++ .../com/team766/robot/example/DriverOI.java | 7 ++--- .../java/com/team766/robot/reva/BoxOpOI.java | 2 ++ .../java/com/team766/robot/reva/DebugOI.java | 2 ++ 5 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/team766/framework/OIFragment.java b/src/main/java/com/team766/framework/OIFragment.java index c9f042829..1a77ead94 100644 --- a/src/main/java/com/team766/framework/OIFragment.java +++ b/src/main/java/com/team766/framework/OIFragment.java @@ -1,6 +1,7 @@ package com.team766.framework; import com.team766.logging.Category; +import com.team766.logging.Severity; import java.util.LinkedList; import java.util.List; import java.util.function.BooleanSupplier; @@ -55,6 +56,7 @@ public boolean isFinishedTriggering() { private final String name; private final List conditions = new LinkedList(); + private boolean conditionsEvaluated = false; /** * Creates a new OIFragment. @@ -73,12 +75,6 @@ private void register(Condition condition) { conditions.add(condition); } - /** - * Called at the beginning of {@link #runOI(Context)}, before evaluating any of the registered conditions - * and before calling {@link #handleOI(Context)}. Subclasses should override this if needed. - */ - protected void handlePre() {} - /** * OIFragments must override this method to implement their OI logic. Typically called via the overall * OI's loop, once per iteration through the loop. Can use any {@link Condition}s @@ -91,9 +87,15 @@ protected void handlePre() {} protected abstract void handleOI(Context context); /** - * Called after {@link #handleOI}, at the end of {@link #runOI}. Subclasses should override this if needed. + * Subclasses should call this once per call to {@link #handleOI}. Evaluates each of the + * conditions for this fragment. */ - protected void handlePost() {} + protected void evaluateConditions() { + for (Condition condition : conditions) { + condition.evaluate(); + } + conditionsEvaluated = true; + } /** * Called by a Robot's OI class, once per its loop. @@ -101,11 +103,12 @@ protected void handlePost() {} * @param context The {@link Context} running the OI. */ public final void runOI(Context context) { - handlePre(); - for (Condition condition : conditions) { - condition.evaluate(); - } + // reset for the next call + conditionsEvaluated = false; + handleOI(context); - handlePost(); + if (!conditionsEvaluated) { + log(Severity.WARNING, "Fragment did not call evaluateCondition()!"); + } } } diff --git a/src/main/java/com/team766/robot/common/DriverOI.java b/src/main/java/com/team766/robot/common/DriverOI.java index fe4540946..b71c99015 100644 --- a/src/main/java/com/team766/robot/common/DriverOI.java +++ b/src/main/java/com/team766/robot/common/DriverOI.java @@ -52,6 +52,8 @@ public void handleOI(Context context) { -createJoystickDeadzone(rightJoystick.getAxis(InputConstants.AXIS_LEFT_RIGHT)) * ControlConstants.MAX_ROTATIONAL_VELOCITY; // For steer + evaluateConditions(); + if (leftJoystick.getButtonPressed(InputConstants.BUTTON_RESET_GYRO)) { drive.resetGyro(); } diff --git a/src/main/java/com/team766/robot/example/DriverOI.java b/src/main/java/com/team766/robot/example/DriverOI.java index d67355d62..50cf4973a 100644 --- a/src/main/java/com/team766/robot/example/DriverOI.java +++ b/src/main/java/com/team766/robot/example/DriverOI.java @@ -25,13 +25,12 @@ public DriverOI(JoystickReader joystick) { } @Override - protected void handlePre() { + protected void handleOI(Context context) { joystickX = joystick.getAxis(InputConstants.AXIS_X); joystickY = joystick.getAxis(InputConstants.AXIS_Y); - } - @Override - protected void handleOI(Context context) { + evaluateConditions(); + if (button1.isNewlyTriggering()) { // handle button press } else if (button1.isFinishedTriggering()) { diff --git a/src/main/java/com/team766/robot/reva/BoxOpOI.java b/src/main/java/com/team766/robot/reva/BoxOpOI.java index 56517d60d..3a347192b 100644 --- a/src/main/java/com/team766/robot/reva/BoxOpOI.java +++ b/src/main/java/com/team766/robot/reva/BoxOpOI.java @@ -43,6 +43,8 @@ public BoxOpOI( @Override protected void handleOI(Context context) { + evaluateConditions(); + // shoulder positions if (gamepad.getButtonPressed(InputConstants.XBOX_A)) { context.takeOwnership(shoulder); diff --git a/src/main/java/com/team766/robot/reva/DebugOI.java b/src/main/java/com/team766/robot/reva/DebugOI.java index c461972d9..4f577ef14 100644 --- a/src/main/java/com/team766/robot/reva/DebugOI.java +++ b/src/main/java/com/team766/robot/reva/DebugOI.java @@ -67,6 +67,8 @@ public DebugOI( @Override protected void handleOI(Context context) { + evaluateConditions(); + // fine-grained control of the shoulder // used for testing and tuning // press down the shoulder control button and nudge the angle up and down From e38c8fe7a45568e8322a5fbf7d3748685457a34c Mon Sep 17 00:00:00 2001 From: Debajit Ghosh Date: Mon, 11 Mar 2024 19:38:26 -0700 Subject: [PATCH 09/15] throw exception when evaluateConditions() called zero or more than one time. rename runOI() to run(). --- src/main/java/com/team766/framework/OIFragment.java | 10 ++++++++-- src/main/java/com/team766/robot/example/OI.java | 2 +- src/main/java/com/team766/robot/reva/OI.java | 6 +++--- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/team766/framework/OIFragment.java b/src/main/java/com/team766/framework/OIFragment.java index 1a77ead94..06920159a 100644 --- a/src/main/java/com/team766/framework/OIFragment.java +++ b/src/main/java/com/team766/framework/OIFragment.java @@ -1,6 +1,7 @@ package com.team766.framework; import com.team766.logging.Category; +import com.team766.logging.LoggerExceptionUtils; import com.team766.logging.Severity; import java.util.LinkedList; import java.util.List; @@ -11,7 +12,7 @@ * {@link #handleOI} method. * * The overall OI for a robot will contain a set of fragments, typically one per set of controls (eg, driver, boxop, debug), - * and it will call {@link #runOI(Context)} once per its own loop. During each call to {@link #runOI}, the fragment + * and it will call {@link #run(Context)} once per its own loop. During each call to {@link #runOI}, the fragment * will evaluate any {@link Condition}s that were created for this fragment. This simplifies OI logic that checks if a * specific condition is currently triggering (eg pressing or holding down a joystick button) or if a condition that had been triggering * in a previous iteration of the OI loop is no longer triggering in this iteration. @@ -91,6 +92,10 @@ private void register(Condition condition) { * conditions for this fragment. */ protected void evaluateConditions() { + if (conditionsEvaluated) { + log(Severity.WARNING, "evaluateConditions() called multiple times in this loop!"); + throw new IllegalStateException("evaluateConditions() called multiple times in this loop!"); + } for (Condition condition : conditions) { condition.evaluate(); } @@ -102,13 +107,14 @@ protected void evaluateConditions() { * Calls {@link #handlePre()}, evaluates all conditions once per call, and calls {@link #handlePost()}. * @param context The {@link Context} running the OI. */ - public final void runOI(Context context) { + public final void run(Context context) { // reset for the next call conditionsEvaluated = false; handleOI(context); if (!conditionsEvaluated) { log(Severity.WARNING, "Fragment did not call evaluateCondition()!"); + throw new IllegalStateException("Fragment did not call evaluateCondition!"); } } } diff --git a/src/main/java/com/team766/robot/example/OI.java b/src/main/java/com/team766/robot/example/OI.java index ca16c6f25..97c0fd364 100644 --- a/src/main/java/com/team766/robot/example/OI.java +++ b/src/main/java/com/team766/robot/example/OI.java @@ -33,7 +33,7 @@ public void run(final Context context) { RobotProvider.instance.refreshDriverStationData(); // call each of the OI fragment's runOI methods. - driverOI.runOI(context); + driverOI.run(context); } } } diff --git a/src/main/java/com/team766/robot/reva/OI.java b/src/main/java/com/team766/robot/reva/OI.java index e2e1d9e38..137c50bee 100644 --- a/src/main/java/com/team766/robot/reva/OI.java +++ b/src/main/java/com/team766/robot/reva/OI.java @@ -48,11 +48,11 @@ public void run(Context context) { // of mechanisms when appropriate. // Driver OI: take input from left, right joysticks. control drive. - driverOI.runOI(context); + driverOI.run(context); // Debug OI: allow for finer-grain testing of each mechanism. - debugOI.runOI(context); + debugOI.run(context); - boxOpOI.runOI(context); + boxOpOI.run(context); } } } From 6baa171ebb4b185780ef74bf7af2b162b14ba1be Mon Sep 17 00:00:00 2001 From: Debajit Ghosh Date: Mon, 11 Mar 2024 19:38:52 -0700 Subject: [PATCH 10/15] linting --- src/main/java/com/team766/framework/OIFragment.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/team766/framework/OIFragment.java b/src/main/java/com/team766/framework/OIFragment.java index 06920159a..bddaa3c99 100644 --- a/src/main/java/com/team766/framework/OIFragment.java +++ b/src/main/java/com/team766/framework/OIFragment.java @@ -1,7 +1,6 @@ package com.team766.framework; import com.team766.logging.Category; -import com.team766.logging.LoggerExceptionUtils; import com.team766.logging.Severity; import java.util.LinkedList; import java.util.List; @@ -94,7 +93,8 @@ private void register(Condition condition) { protected void evaluateConditions() { if (conditionsEvaluated) { log(Severity.WARNING, "evaluateConditions() called multiple times in this loop!"); - throw new IllegalStateException("evaluateConditions() called multiple times in this loop!"); + throw new IllegalStateException( + "evaluateConditions() called multiple times in this loop!"); } for (Condition condition : conditions) { condition.evaluate(); From a4c904bfc26a32357b5d4a9cea85311e55e7530e Mon Sep 17 00:00:00 2001 From: Debajit Ghosh Date: Tue, 12 Mar 2024 08:24:18 -0700 Subject: [PATCH 11/15] only complain if conditions warrant it --- src/main/java/com/team766/framework/OIFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/team766/framework/OIFragment.java b/src/main/java/com/team766/framework/OIFragment.java index bddaa3c99..4899c22d6 100644 --- a/src/main/java/com/team766/framework/OIFragment.java +++ b/src/main/java/com/team766/framework/OIFragment.java @@ -112,7 +112,7 @@ public final void run(Context context) { conditionsEvaluated = false; handleOI(context); - if (!conditionsEvaluated) { + if (conditions.size() > 0 && !conditionsEvaluated) { log(Severity.WARNING, "Fragment did not call evaluateCondition()!"); throw new IllegalStateException("Fragment did not call evaluateCondition!"); } From 1bb3c546620f9c9765543c85fb9f6e7ab906c34f Mon Sep 17 00:00:00 2001 From: Debajit Ghosh Date: Fri, 15 Mar 2024 00:21:14 -0700 Subject: [PATCH 12/15] Merge branch 'main' of https://github.com/Team766/2024 into oi-conditions-renaming From ea53d0f433c372207fc0181a90ebd5e4222dc460 Mon Sep 17 00:00:00 2001 From: Debajit Ghosh Date: Fri, 15 Mar 2024 00:27:19 -0700 Subject: [PATCH 13/15] updating javadoc --- src/main/java/com/team766/framework/OIFragment.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/team766/framework/OIFragment.java b/src/main/java/com/team766/framework/OIFragment.java index de7b7cebe..2419194fe 100644 --- a/src/main/java/com/team766/framework/OIFragment.java +++ b/src/main/java/com/team766/framework/OIFragment.java @@ -88,6 +88,9 @@ private void register(Condition condition) { * they have set up to simplify checking if the {@link Condition} is {@link Condition#isTriggering()}, * or, if it had been triggering in a previous iteration of the loop, if it is now * {@link Condition#isFinishedTriggering()}. + * + * When implementing handleOI, you must call {@link #evaluateConditions()} in order to use any + * Conditions; omitting this call will result in calls to {@link #run} throwing an IllegalStateException. * * @param context The {@link Context} running the OI. */ @@ -111,7 +114,6 @@ protected void evaluateConditions() { /** * Called by a Robot's OI class, once per its loop. - * Calls {@link #handlePre()}, evaluates all conditions once per call, and calls {@link #handlePost()}. * @param context The {@link Context} running the OI. */ public final void run(Context context) { From 9f3b6bf6203f1df2e9220343771ee19b0c248757 Mon Sep 17 00:00:00 2001 From: Debajit Ghosh Date: Fri, 15 Mar 2024 00:28:43 -0700 Subject: [PATCH 14/15] setting the logger category in the new ctor --- src/main/java/com/team766/framework/OIFragment.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/team766/framework/OIFragment.java b/src/main/java/com/team766/framework/OIFragment.java index 2419194fe..85861fffa 100644 --- a/src/main/java/com/team766/framework/OIFragment.java +++ b/src/main/java/com/team766/framework/OIFragment.java @@ -71,6 +71,7 @@ public OIFragment(String name) { * Creates a new OIFragment, using the name of the sub-class. */ public OIFragment() { + loggerCategory = Category.OPERATOR_INTERFACE; this.name = this.getClass().getSimpleName(); } From c7a7e2a59fd6291dcd1f742e6de00277553ef778 Mon Sep 17 00:00:00 2001 From: Debajit Ghosh Date: Fri, 15 Mar 2024 00:32:49 -0700 Subject: [PATCH 15/15] linting --- src/main/java/com/team766/framework/OIFragment.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/team766/framework/OIFragment.java b/src/main/java/com/team766/framework/OIFragment.java index 85861fffa..d5c61bdf8 100644 --- a/src/main/java/com/team766/framework/OIFragment.java +++ b/src/main/java/com/team766/framework/OIFragment.java @@ -89,8 +89,8 @@ private void register(Condition condition) { * they have set up to simplify checking if the {@link Condition} is {@link Condition#isTriggering()}, * or, if it had been triggering in a previous iteration of the loop, if it is now * {@link Condition#isFinishedTriggering()}. - * - * When implementing handleOI, you must call {@link #evaluateConditions()} in order to use any + * + * When implementing handleOI, you must call {@link #evaluateConditions()} in order to use any * Conditions; omitting this call will result in calls to {@link #run} throwing an IllegalStateException. * * @param context The {@link Context} running the OI.