Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rename OICondition inner class to Condition. update example OI to use OIFragment and Conditions. #77

Open
wants to merge 17 commits into
base: main
Choose a base branch
from

Conversation

dejabot
Copy link
Contributor

@dejabot dejabot commented Mar 10, 2024

Description

  • simple renaming of OICondition to Condition, since it's within OIFragment.
  • set the loggerCategory for OIFragment
  • add usage of OIFragment and Condition to example OI.

How Has This Been Tested?

renaming, loggerCategory, and examples only.

@dejabot dejabot requested a review from rcahoon March 10, 2024 16:59
joystick0 = RobotProvider.instance.getJoystick(0);
joystick1 = RobotProvider.instance.getJoystick(1);
joystick2 = RobotProvider.instance.getJoystick(2);
leftJoystick = RobotProvider.instance.getJoystick(0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should there not be a rightJoystick?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for these examples (most frequently used with BurroBots - a competition bot would typically use Swerve drive with the com.team766.robot.common.DriverOI), I was thinking arcade drive. but the example sets the wrong expectation with leftJoystick - renamed to joystick.

I can also include leftJoystick and rightJoystick or joystick and gamepad if you think that's better.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

joystick SGTM

src/main/java/com/team766/robot/example/DriverOI.java Outdated Show resolved Hide resolved
@dejabot
Copy link
Contributor Author

dejabot commented Mar 11, 2024

Thx! PTAL?

src/main/java/com/team766/robot/example/DriverOI.java Outdated Show resolved Hide resolved
@Override
protected void handlePre() {
joystickX = joystick.getAxis(InputConstants.AXIS_X);
joystickY = joystick.getAxis(InputConstants.AXIS_Y);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

non-blocking, because i'm not sure if i have a better way to do this, but

it seems like the code around conditions is getting pretty spread out, which hurts readability. it requires code in the constructor, in handlePre, and in handleOI

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, let's discuss.

this is less about code for conditions and more about code used in the OI that's also used in conditions.
problem to solve - allow for some code to run before conditions are evaluated (since we moved that to an explicit step run by something like the OIFragment). we could simplify by having everything in handleOI, at the cost of "missing a frame".

I understand the concern - open to a different approach that allows code to run before the evaluation step.

wdyt?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thinking about alternatives - one could be to make this part of the Conditions - tho I don't think that would be more readable.

eg, that woud make updating variables a side effect.. and given that lambdas are supposed to be short, devs might end up moving some of the logic into helper methods called via method references.

Copy link
Member

@rcahoon rcahoon Mar 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of ideas. I'm not sure any of them is the best, though I like (2) because it doesn't require class member variables.

  1. Condition has an invalidate() method that OIFragment calls before handleOI. Then conditions are lazily evaluated on the first call to e.g. isTriggering
  2. Instead of passing the lambda to the constructor, Condition has an evaluate method that the user is required to call during handleOI.
public class DriverOI extends OIFragment {
    private final JoystickReader joystick;

    private Condition moveJoystick = new Condition();

    public DriverOI(JoystickReader joystick) {
        super("DriverOI");
        this.joystick = joystick;
    }

    protected void handleOI(Context context) {
        final double joystickX = joystick.getAxis(InputConstants.AXIS_X);
        final double joystickY = joystick.getAxis(InputConstants.AXIS_Y);
        moveJoystick.evaluate(Math.abs(joystickX) > 0 || Math.abs(joystickY) > 0);

        if (moveJoystick.isTriggering()) {
            // handle joystick movement
        }
    }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, I'd be a bit uncomfortable with 2 since that feels a bit error-prone, eg if devs miss calling that, they'll wonder why their conditions aren't triggering as expected.

if we wanted to avoid having a preHandle, we could recommend conditions be more self-contained vs depend on these intermediate member variables that store their own state. (nothing would prevent someone from doing that eg in a helper method the developer set up and called from their conditions but those calls would be more obviously visible).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i thought about requesting that conditions be more self-contained, but then I thought about what if the condition is based off of some complex code, for example processing vision output or something. I guess in that case, probably that complex processing should be moved into a Mechanism or ProcedureWithValue or something. but it still seems like something that someone might want to do, even if it was just temporary.

what if we combined (1) and (2)? the OIFragment invalidates the Condition prior to calling handleOI, and if you try to query the Condition before evaluating it, it raises an exception. we could also raise an exception if someone tries to evaluate a condition multiple times in a single frame (i.e. evaluate is called when the Condition is not invalidated)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks! riffing off of this, I'm trying something simple that allows a fragment sublass to evaluate all of the conditions and checks that that call was made, throwing an exception if not.

wdyt?

src/main/java/com/team766/robot/example/DriverOI.java Outdated Show resolved Hide resolved
@dejabot
Copy link
Contributor Author

dejabot commented Mar 11, 2024

thx, PTAL?

@dejabot
Copy link
Contributor Author

dejabot commented Mar 15, 2024

removed pre and post methods. make users evaluate conditions (OIFragment will throw an IllegalStateException if this is omitted).

PTAL? thank you!

@rcahoon
Copy link
Member

rcahoon commented Mar 15, 2024

getting rid of pre and post methods is a nice improvement. i'm still kinda hung up on the need to use class member variables, which don't make data dependencies between variables/conditions obvious (e.g. the user could call evaluateConditions() before all variables have been updated), so I made this branch for comparison https://github.com/Team766/2024/compare/rcahoon/oi-conditions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants