Giter Site home page Giter Site logo

frc2024's Introduction

Team 3952's Robot Code for the 2024 "Crescendo" Season.

Vision code is located separately.

frc2024's People

Contributors

ebay-kid avatar siiverfish avatar stanleymw avatar itsavs avatar foxinabox384 avatar

Stargazers

 avatar  avatar

Watchers

Yavor Kolev avatar

frc2024's Issues

Tune Intake Pivot

Note: make sure the limit switches + absolute encoder are mounted + plugged in properly before beginning.

These values may change after mech re-manufactures the robot with metal, but the values should be reasonably close on the PID loop that only a slight re-tune is necessary. (The conversion factor should be fine, though the absolute encoder may need to be re-zeroed). Also make sure they fix their crappy wire job

TODO:

  • MAKE SURE WIRES ARENT IN THE WAY BECAUSE SNIPPED WIRES BAD
  • Tune conversion factor on relative encoders
  • Tune conversion factor, zero point on absolute encoders (the conversion factor should be 1:1 because it's on the shaft itself)
  • Tune the PID to go to angle setpoints (position)

Shooter subsystem

Info:

  • Two main motors in a top-down configuration, one following the other. For consistency, make the top motor the "follower" and the bottom motor the "leader"
  • One motor that pivots the shooter
  • One motor for the flap on the shooter
  • Assume 2 limit switches - one for pivot, one for flap

Basic requirements:

  • Setting speed on all motors (note: for the two main shooter motors, only one method is needed - this method should only set the speed on the motor designated as the "leader")
  • Getters for the positions of the pivot and shooter motors
  • Methods to set, and reset, positions of the pivot and shooter motors
  • Getters for the velocity of both (i.e. 2 methods) shooter motors
  • Getter for each limit switch's value
  • Make class variables to store the PIDController on the integrated motor controller (cansparkmax) so we can control all motors (for the two main motors, only control the "leader" motor). Please default the PID values to all 0, we can tune later
  • Setters for the PIDController references on all controllers. For the pivot and flap, these should take in degrees. The one for the main motors can just take in an RPM

Migrate to a new controller

Resolves an issue with our previous flight joysticks where attempting to go to a non-multiple-of-90 degree angle would cause it to first report a 90deg angle before jumping to the correct angle (and causing really bad stutters).

Stutter checks (and PID stability tests) should still be run with the new controller (going one direction to a different one quickly/reversing direction quickly, etc)

Intake Subsystem

2 Motors (on CANSparkMax), one should be inverted from the other.
Motors should follow each other
Trigger power when button is pressed (button # TBD)

New controller configuration system

This year's code changes including moving away from using raw button numbers on the controllers, and towards polling the buttons at meaningful positions on the controller (ex. bumper, trigger, ABXY buttons).

We want to avoid using the old system of checking which button numbers correspond to which physical button presses by abstracting this away into AbstractController and its subclasses.

Here is an example of some methods in AbstractController:

/**
* On the right hand side on controllers, there's four buttons arranged in a diamond shape. Due to what I can only assume to be a stylistic decision, the PS5 controller decided to not go with X/Y/A/B, hence the interesting name choice.
* @return A bindable {@link Trigger} for the button at the top of the diamond on the right side of the controller.
*/
public abstract Trigger upperButton();
/**
* On the right hand side on controllers, there's four buttons arranged in a diamond shape. Due to what I can only assume to be a stylistic decision, the PS5 controller decided to not go with X/Y/A/B, hence the interesting name choice.
* @return A bindable {@link Trigger} for the button on the left of the diamond on the right side of the controller.
*/
public abstract Trigger leftButton();
/**
* On the right hand side on controllers, there's four buttons arranged in a diamond shape. Due to what I can only assume to be a stylistic decision, the PS5 controller decided to not go with X/Y/A/B, hence the interesting name choice.
* @return A bindable {@link Trigger} for the button on the right of the diamond on the right side of the controller.
*/
public abstract Trigger rightButton();
/**
* On the right hand side on controllers, there's four buttons arranged in a diamond shape. Due to what I can only assume to be a stylistic decision, the PS5 controller decided to not go with X/Y/A/B, hence the interesting name choice.
* @return A bindable {@link Trigger} for the button at the bottom of the diamond on the right side of the controller.
*/
public abstract Trigger lowerButton();
/**
* Get the POV value.
* @return The POV value. -1 if not pressed, else 0 for up and increasing clockwise.
* @see GenericHID#getPOV()
*/
public abstract int getPOV();
/**
* While holding the controller, the buttons on the far side of the controller. Gets the far button on the left side that is higher up. (bumper?)
* @return The upper button on the far side on the left.
*/
public abstract Trigger leftShoulderButton();
/**
* While holding the controller, the buttons on the far side of the controller. Gets the far button on the right side that is higher up. (bumper?)
* @return The upper button on the far side on the right.
*/
public abstract Trigger rightShoulderButton();
/**
* While holding the controller, the buttons on the far side of the controller. Gets the far button on the left side that is lower.
* @return The upper button on the far side on the left.
*/
public abstract Trigger leftShoulderTrigger();
/**
* While holding the controller, the buttons on the far side of the controller. Gets the far button on the right side that is lower.
* @return The upper button on the far side on the right.
*/
public abstract Trigger rightShoulderTrigger();

However, we still want to have a centralized configuration file/class that can be easily located and accessed.

An example of this year's current setup is shown below:

public void execute() {
if(joystick.rightButton().getAsBoolean()) {
this.intake.setIntakeSpeed(0.6, 0.4);
} else if(joystick.lowerButton().getAsBoolean()) {
this.intake.setIntakeSpeed(-0.2, -0.2);
} else {
this.intake.setIntakeSpeed(0, 0);
}
if(joystick.leftShoulderButton().getAsBoolean()) {
this.intake.pivotToAngle(0);
} else if(joystick.leftShoulderTrigger().getAsBoolean()) {
this.intake.pivotToAngle(-90);
}

Note how no constants or numbers are used - only direct calls to wrapped controller methods provided by AbstractController. While the use of these methods is preferred, the hard-coded buttons are not as they should be easier to locate around the codebase rather than locked in different files.

An example of the technique from previous years is shown below: (note the use of constants from the Constants.ControllerConstants class - these values are raw integers corresponding to raw button indices)
https://github.com/FRCteam3952/FRC2023/blob/73fec8fbcf24258c696e7088896c4645cfcf98d5/src/main/java/frc/robot/commands/clawcommands/ClawOpenandCloseCommand.java#L21-L33

// Github decided not to embed the above link, so here's what that code looks like:
public void execute() {
    // System.out.println("CLAW TOGGLE: " + toggle);
    if (this.joystick.getRawButtonWrapper(ControllerConstants.CLAW_GRIP_OR_RELEASE_BUTTON_NUMBER) && toggle) {
        System.out.println("BUTTON PRESSED");
        // this.claw.setClawOpened(!this.claw.getClawClosed());
        if(this.claw.getClawClosed()) {
            this.claw.setClawOpened(false);
        } else {
            this.claw.setClawOpened(true);
        }
        toggle = false;
    }
    if (this.joystick.getRawButtonReleasedWrapper(ControllerConstants.CLAW_GRIP_OR_RELEASE_BUTTON_NUMBER)) {
        // ... method continues

We also would like to maintain a way to accomplish code similar to the following, but using the new controller code:
https://github.com/FRCteam3952/FRC2023/blob/73fec8fbcf24258c696e7088896c4645cfcf98d5/src/main/java/frc/robot/RobotContainer.java#L169-L172

nintendoProController.controller.button(ControllerConstants.CALIBRATE_ARM_BUTTON_NUMBER).onTrue(new CalibrateArmPivotsCommand(arm, nintendoProController));
driverController.joystick.button(ControllerConstants.BALANCE_CHARGE_STATION_BUTTON_NUMBER).whileTrue(new BalanceChargeStationCommand(driveTrain));
nintendoProController.controller.button(ControllerConstants.FLIP_TURRET_BUTTON_NUMBER).onTrue(Commands.runOnce(() -> { // ... code continues

Again note the use of the constants, but also note that we are directly accessing the controller our class is specifically being used to wrap around - we want to avoid that and instead use the AbstractController methods.

The main goal of this issue is to:

  • Maintain the new system found in AbstractController, with methods to abstract away determining which button is actually being checked/pressed. New methods may be added if necessary, but this should be unlikely.
  • Implement a new system for configuring user input (i.e. which button presses correspond to which response from the robot)
  • This system should have an easy process to determine which controller method should be called for a specific action.
  • This system should have an easy process to modify which controller button corresponds to which action.
  • This system should not rely on having a physical controller to figure out which button is which (i.e. the names of the methods in AbstractController should correspond to how the system handles buttons - AbstractController#leftShoulderButton() should correspond to a LEFT_SHOULDER_BUTTON or similar).

Ideally, using this system would look something like the following (adapting our current setup):

if(ControlHandler.get(this.joystick, ControllerConstants.RUN_INTAKE_BUTTON)) { // code continues

However, the file names and syntax shown here don't need to be copied - you can go in a different path if you see fit.

Side note: the methods in AbstractController and the final code example return Triggers, which are a part of the WPILIB library's controller support. Look into their documentation on this if necessary.

Tune Shooter RPM PID

Tune the shooter RPM PID (velocity). No need for a conversion factor, the raw RPM units is fine.

  • Tune the shooter PID. It should be able to achieve values at 3000RPM (just in case).
  • Make sure it doesn't oscillate

ClimberCommand

Will require the following subsystems: Climber, Shooter, Intake
Will use the RobotGyro

goal:

  1. move both climber hooks all the way up, then start moving both down until one hits an amperage spike.
  2. stop moving the one that hit an amperage spike, continue moving the other until it also hits an amperage spike
  3. move both up while balancing the robot using the hooks
  4. while moving up, make sure that we're not tilting forwards/backwards by adjusting the intake and climber angles to compensate for wobble
  5. use robot gyro to tell if we're not flat

final goal: climbed onto chain with our robot floor parallel to the ground.

Climber Subsystem

Two motors, separately controlled (add port constants to Constants.java)
Need a PID on position for each motor (pls default initialize to all 0s)
Get amperage of each motor
Getter/Setter of positions
Set the speed (as in, [-1, 1] speed) directly for each motor individually

If possible, please also add the necessary flags to Flags.java to toggle functionality (see other Flags inner classes for a reference point)

Define and set up an indexing process

  • The process should combine the intake, conveyor, and shooter
  • When shooting, we need to make sure that it's not contacting the shooter wheels
  • You may need to check for an amperage spike to know the note's been intake'd (or tell mech to add a sensor)
  • This one may take more time to code

Retune PIDs

Current issues:

Stuttering back and forth while on ground and slowing to speed 0

Turning PID currently slow and does not seem to be completely reaching target value (off by ~0.05rad, or ~3deg).

Driving PID does not reach target speed (off by >10% even when on blocks)

Requirements:

No stuttering when on blocks or on the ground

Turning PID reaches target value with high accuracy (less than 0.05 rad consistently at high + low change amounts)

Drive PID reaches close to target speed (within 10% hopefully)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.