Skip to content

Commit

Permalink
feat: elevator subsystem (#21)
Browse files Browse the repository at this point in the history
* added elevator lead and follow ports in constants

* wrote elevator, elevatorio, and elevatoriotalonfx! yay!

* feat: delete config loop

* wrote elevator, elevatorio, and elevatoriotalonfx! yay!

* Test commit from nmp

* Test commit from nmp

* started to add code for homing

* added code for homing and current limits

* added amber's config values

* made requested edits:

* added .withEnableFOC(true).withOverrideBrakeDurNeutral(true) to motion magic stuff

* removed smart dashboard references

* deleted pid values being set to 0 because they default to 0

* cleanup code

---------

Co-authored-by: dlpond917 <[email protected]>
Co-authored-by: amb2127 <[email protected]>
  • Loading branch information
3 people authored Jan 26, 2024
1 parent 984097e commit e11c2d7
Show file tree
Hide file tree
Showing 5 changed files with 224 additions and 2 deletions.
29 changes: 27 additions & 2 deletions src/main/java/frc/robot/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ public final class Constants {
100000000 : // 100 MB
1000000000; // 1 GB
public static final int DEFAULT_PERIODS_PER_LOG = 0;
public static final double ELEVATOR_INCHES_PER_ROTATION = 0.25*22*12/60; //12:60 gears attached to 22 tooth sprocket on #25 chain with 0.25 inch pitch
public static final double ELEVATOR_LOWER_LIMIT_INCHES = 0;
public static final double ELEVATOR_UPPER_LIMIT_INCHES = 12;
public static final double NOMINAL_DT = 0.02;
public static final double ELEVATOR_HOME_VOLTAGE = -1.5;
public static final double ELEVATOR_STALLING_CURRENT = 35;
public static final double MIN_ELEVATOR_HOME_TIME = 0.2;

public enum KinematicLimits {
/**
Expand Down Expand Up @@ -58,9 +65,27 @@ public static class Ports {
public static final int WRIST_MOTOR = 1;
public static final int WRIST_ENCODER = 2;

}

public static final int ELEVATOR_LEAD = 31;
public static final int ELEVATOR_FOLLOW = 32;

}
//TODO: figure out actual values for below
public enum ElevatorPosition {
BOTTOM("bottom", 0),
STOW("stow", 1),
INTAKE("intake", 2),
SPEAKER("speaker", 3),
AMP("amp", 4),
TRAP("trap", 5),
TOP("top", 6);

public final String positionName;
public final double positionLocationInches;
ElevatorPosition(String positionName, double positionLocationInches) {
this.positionName = positionName;
this.positionLocationInches = positionLocationInches;
}
}

public static final double SWERVE_DRIVE_P = 100;
public static final double SWERVE_DRIVE_D = 0.05;
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/frc/robot/Robot.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
import frc.subsystem.wrist.Wrist;
import frc.subsystem.wrist.WristIO;
import frc.subsystem.wrist.WristIOTalonFX;
import frc.subsystem.elevator.Elevator;
import frc.subsystem.elevator.ElevatorIO;
import frc.subsystem.elevator.ElevatorIOTalonFX;
import frc.utility.Controller;
import frc.utility.Controller.XboxButtons;
import frc.utility.ControllerDriveInputs;
Expand Down Expand Up @@ -50,6 +53,7 @@ public class Robot extends LoggedRobot {

static Drive drive;
static Wrist wrist;
static Elevator elevator;

/**
* This function is run when the robot is first started up and should be used
Expand Down Expand Up @@ -122,6 +126,7 @@ public void robotInit() {

drive = new Drive(new ModuleIOTalonFX(0), new ModuleIOTalonFX(1), new ModuleIOTalonFX(2), new ModuleIOTalonFX(3), new GyroIOPigeon2());
wrist = new Wrist(new WristIOTalonFX());
elevator = new Elevator(new ElevatorIOTalonFX());
} else {
setUseTiming(false); // Run as fast as possible
if(Objects.equals(VIRTUAL_MODE, "REPLAY")) {
Expand All @@ -134,6 +139,7 @@ public void robotInit() {

drive = new Drive(new ModuleIO() {}, new ModuleIO() {}, new ModuleIO() {}, new ModuleIO() {}, new GyroIO() {});
wrist = new Wrist(new WristIO() {});
elevator = new Elevator(new ElevatorIO() {});
}
// Initialize auto chooser
chooser.addDefaultOption("Default Auto", defaultAuto);
Expand All @@ -146,6 +152,7 @@ public void robotInit() {
Logger.start();
drive.start();
wrist.start();
elevator.start();
}

/** This function is called periodically during all modes. */
Expand Down
56 changes: 56 additions & 0 deletions src/main/java/frc/subsystem/elevator/Elevator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package frc.subsystem.elevator;

import edu.wpi.first.wpilibj.DriverStation;
import static frc.robot.Constants.*;
import frc.subsystem.AbstractSubsystem;
import org.littletonrobotics.junction.Logger;


public class Elevator extends AbstractSubsystem {
final ElevatorIO elevatorIO;
private final ElevatorInputsAutoLogged elevatorInputs = new ElevatorInputsAutoLogged();

private boolean homing = false;
private double homeTime = 0;
public Elevator(ElevatorIO elevatorIO){
super();
this.elevatorIO = elevatorIO;
}

public void setPosition(ElevatorPosition position) {
this.setPosition(position.positionLocationInches / ELEVATOR_INCHES_PER_ROTATION);
}

public void setPosition(double positionInRotations) {
double positionInInches = positionInRotations * ELEVATOR_INCHES_PER_ROTATION;
if (positionInInches < ELEVATOR_LOWER_LIMIT_INCHES) {
positionInInches = ELEVATOR_LOWER_LIMIT_INCHES;
} else if (positionInInches > ELEVATOR_UPPER_LIMIT_INCHES) {
positionInInches = ELEVATOR_UPPER_LIMIT_INCHES;
}
positionInRotations = positionInInches / ELEVATOR_INCHES_PER_ROTATION;
elevatorIO.setPosition(positionInRotations);
}

public void update() {
elevatorIO.updateInputs(elevatorInputs);

if (homing) {
if (DriverStation.isEnabled()) {
homeTime -= NOMINAL_DT;
elevatorIO.setElevatorVoltage(ELEVATOR_HOME_VOLTAGE);
double avgMotorVoltage = (elevatorInputs.leadMotorVoltage + elevatorInputs.followMotorVoltage) / 2.0;
if (homeTime <= 0 && avgMotorVoltage > ELEVATOR_STALLING_CURRENT) {
homing = false;
elevatorIO.setEncoderToZero();
}
Logger.getInstance().recordOutput("Elevator/Home time", homeTime);
}
}
}

public void home() {
homeTime = MIN_ELEVATOR_HOME_TIME;
homing = true;
}
}
27 changes: 27 additions & 0 deletions src/main/java/frc/subsystem/elevator/ElevatorIO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package frc.subsystem.elevator;

import org.littletonrobotics.junction.AutoLog;

public interface ElevatorIO {
@AutoLog
class ElevatorInputs {
public double leadMotorPosition;
public double leadMotorVelocity;
public double leadMotorVoltage;
public double leadMotorAmps;
public double leadMotorTemp;

public double followMotorPosition;
public double followMotorVelocity;
public double followMotorVoltage;
public double followMotorAmps;
public double followMotorTemp;
}

default void updateInputs(ElevatorInputs inputs) {}

default void setPosition(double targetPositionInRotations){}

default void setEncoderToZero() {}
default void setElevatorVoltage(double voltage) {}
}
107 changes: 107 additions & 0 deletions src/main/java/frc/subsystem/elevator/ElevatorIOTalonFX.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package frc.subsystem.elevator;

import com.ctre.phoenix6.BaseStatusSignal;
import com.ctre.phoenix6.StatusSignal;
import com.ctre.phoenix6.configs.*;
import com.ctre.phoenix6.controls.Follower;
import com.ctre.phoenix6.controls.MotionMagicVoltage;
import com.ctre.phoenix6.controls.VoltageOut;
import com.ctre.phoenix6.hardware.TalonFX;
import com.ctre.phoenix6.signals.GravityTypeValue;
import frc.robot.Constants;

import static frc.robot.Constants.ELEVATOR_STALLING_CURRENT;

public class ElevatorIOTalonFX implements ElevatorIO {
private final StatusSignal<Double> leadMotorPosition;
private final StatusSignal<Double> leadMotorVelocity;
private final StatusSignal<Double> leadMotorVoltage;
private final StatusSignal<Double> leadMotorAmps;
private final StatusSignal<Double> leadMotorTemp;
private final StatusSignal<Double> followMotorPosition;
private final StatusSignal<Double> followMotorVelocity;
private final StatusSignal<Double> followMotorVoltage;
private final StatusSignal<Double> followMotorAmps;
private final StatusSignal<Double> followMotorTemp;

private final TalonFX leadMotor;
private final TalonFX followMotor;

public ElevatorIOTalonFX() {
leadMotor = new TalonFX(Constants.Ports.ELEVATOR_LEAD);
followMotor = new TalonFX(Constants.Ports.ELEVATOR_FOLLOW);
withVoltage = new VoltageOut(0);

leadMotorPosition = leadMotor.getPosition();
leadMotorVelocity = leadMotor.getVelocity();
leadMotorVoltage = leadMotor.getMotorVoltage();
leadMotorAmps = leadMotor.getSupplyCurrent();
leadMotorTemp = leadMotor.getDeviceTemp();

followMotorPosition = followMotor.getPosition();
followMotorVelocity = followMotor.getVelocity();
followMotorVoltage = followMotor.getMotorVoltage();
followMotorAmps = followMotor.getSupplyCurrent();
followMotorTemp = followMotor.getDeviceTemp();

BaseStatusSignal.setUpdateFrequencyForAll(50, leadMotorPosition, leadMotorVelocity, leadMotorVoltage, leadMotorAmps, leadMotorTemp, followMotorPosition, followMotorVelocity, followMotorVoltage, followMotorAmps, followMotorTemp);

leadMotor.optimizeBusUtilization();
followMotor.optimizeBusUtilization();

TalonFXConfiguration motorConfig = new TalonFXConfiguration();
MotionMagicConfigs motionMagic = motorConfig.MotionMagic;

motionMagic.MotionMagicCruiseVelocity = 20; // rotations per second at cruise
motionMagic.MotionMagicAcceleration = 40; // time to reach max vel
motionMagic.MotionMagicJerk = 200; // time to reach max accel

Slot0Configs slot0 = motorConfig.Slot0;
slot0.kP = 1;
slot0.GravityType = GravityTypeValue.Elevator_Static;

FeedbackConfigs fdb = motorConfig.Feedback;
fdb.SensorToMechanismRatio = Constants.ELEVATOR_INCHES_PER_ROTATION;

motorConfig = motorConfig.withCurrentLimits(new CurrentLimitsConfigs()
.withSupplyCurrentLimit(ELEVATOR_STALLING_CURRENT)
.withSupplyCurrentLimitEnable(true)
.withStatorCurrentLimitEnable(false));

leadMotor.getConfigurator().apply(motorConfig);
followMotor.getConfigurator().apply(motorConfig);

followMotor.setControl(new Follower(leadMotor.getDeviceID(), false));
}
private final MotionMagicVoltage motionMagicRequest = new MotionMagicVoltage().withEnableFOC(true).withOverrideBrakeDurNeutral(true);
public void setPosition(double targetPositionInRotations) {
leadMotor.setControl(motionMagicRequest.withPosition(targetPositionInRotations));
}

public void updateInputs(ElevatorInputs inputs) {
BaseStatusSignal.refreshAll(leadMotorPosition, leadMotorVelocity, leadMotorVoltage, leadMotorAmps, leadMotorTemp, followMotorPosition, followMotorVoltage, followMotorAmps, followMotorTemp);

inputs.leadMotorPosition = leadMotorPosition.getValue() * Constants.ELEVATOR_INCHES_PER_ROTATION;
inputs.leadMotorVelocity = leadMotorVelocity.getValue();
inputs.leadMotorVoltage = leadMotorVoltage.getValue();
inputs.leadMotorAmps = leadMotorAmps.getValue();
inputs.leadMotorTemp = leadMotorTemp.getValue();

inputs.followMotorPosition = followMotorPosition.getValue() * Constants.ELEVATOR_INCHES_PER_ROTATION;
inputs.followMotorVelocity = followMotorVelocity.getValue();
inputs.followMotorVoltage = followMotorVoltage.getValue();
inputs.followMotorAmps = followMotorAmps.getValue();
inputs.followMotorTemp = followMotorTemp.getValue();
}

public void setEncoderToZero() {
leadMotor.setPosition(0);
//elevatorFollower.getEncoder().setPosition(position);
}

private final VoltageOut withVoltage = new VoltageOut().withEnableFOC(true).withOverrideBrakeDurNeutral(true);

public void setElevatorVoltage(double voltage) {
leadMotor.setControl(withVoltage.withOutput(voltage));
}
}

0 comments on commit e11c2d7

Please sign in to comment.