Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions src/main/java/frc/robot/subsystems/kicker/KickerIO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.

package frc.robot.subsystems.kicker;

import org.littletonrobotics.junction.AutoLog;

/** Add your docs here. */
public interface KickerIO {
@AutoLog
public class KickerIOInputs {

// Motor values
public double velocityRPM;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

rotations per second is more consistent with ctre units

public double currentDrawAmps;
public double temperatureCelsius;
public double motorOutputVolts;
public double positionRotations;
}

public abstract void setPosition(double degrees);

public abstract void reset(double degrees);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

both these methods could use a Rotation2d


public abstract KickerIOInputsAutoLogged updateInputs();
}
46 changes: 46 additions & 0 deletions src/main/java/frc/robot/subsystems/kicker/KickerIOReal.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package frc.robot.subsystems.kicker;

import com.ctre.phoenix6.StatusSignal;
import com.ctre.phoenix6.configs.TalonFXConfiguration;
import com.ctre.phoenix6.controls.PositionVoltage;
import com.ctre.phoenix6.hardware.TalonFX;

import edu.wpi.first.math.util.Units;
import frc.robot.Constants;

public class KickerIOReal {

private TalonFX kickerMotor = new TalonFX(Constants.KICKER_MOTOR_ID);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

instead of using a constants class put this in a constant in this file or the subsystem file (i prefer this file because the motor id is a detail specific to the real hardware, but keeping it all in the subystem file could be more organized). the reason to go with this instead of a dedicated constants class is to keep values closer to the subsystem they pertain to

private PositionVoltage motorRequest = new PositionVoltage(Constants.KICKER_MOTOR_ID);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

the value for the constructor here is the initial position to go to, which should be 0.


private StatusSignal<Double> supplyVoltageSignal = kickerMotor.getDutyCycle();

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

you can get motor voltage with kickerMotor.getMotorVoltage()

private StatusSignal<Double> position = kickerMotor.getRotorPosition();
private StatusSignal<Double> velocity = kickerMotor.getRotorVelocity();
private StatusSignal<Double> currentDraw = kickerMotor.getStatorCurrent();

public KickerIOReal (){
TalonFXConfiguration kickerConfig = new TalonFXConfiguration();
kickerConfig.Slot0.kP = 1;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

set PIDs to 0 if you havent tuned them yet.

kickerConfig.Slot0.kD = 0.01;
kickerConfig.Slot0.kI = 0;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

make sure to apply the config to the motor, and configure the gear ratio (125/1) using config.Feedback.SensorToMechanismRatio

}

public void setPosition(double degrees) {
kickerMotor.setControl(motorRequest.withPosition(Units.degreesToRotations(degrees)*Constants.KICKER_GEAR_RATIO));

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

by configuring the gear ratio in the config you dont have to use it here. also move the gear ratio constant to KickerSubsystem

}

public void reset(double degrees){
kickerMotor.setPosition((Units.degreesToRotations(degrees))*Constants.KICKER_GEAR_RATIO);
}

public KickerIOInputsAutoLogged updateInputs() {
KickerIOInputsAutoLogged current = new KickerIOInputsAutoLogged();

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

name here could be confused with motor current


current.currentDrawAmps = currentDraw.refresh().getValue();

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

i dont believe you have to call refresh here but i could be wrong

current.positionRotations = position.refresh().getValue() / Constants.KICKER_GEAR_RATIO;
current.velocityRPM = velocity.refresh().getValue() / Constants.KICKER_GEAR_RATIO;
current.motorOutputVolts = 12 * supplyVoltageSignal.getValue();

return(current);
}
}
43 changes: 43 additions & 0 deletions src/main/java/frc/robot/subsystems/kicker/KickerSubsystem.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package frc.robot.subsystems.kicker;


import org.littletonrobotics.junction.Logger;

import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
import edu.wpi.first.wpilibj2.command.InstantCommand;
import edu.wpi.first.wpilibj2.command.RunCommand;
import edu.wpi.first.wpilibj2.command.SubsystemBase;


public class KickerSubsystem extends SubsystemBase {
KickerIO io;
KickerIOInputsAutoLogged inputs;


public KickerSubsystem(KickerIO io) {
this.io = io;
inputs = new KickerIOInputsAutoLogged();

SmartDashboard.putData("reset Kicker value", new InstantCommand(
()->{io.reset(0);}
));
}

public InstantCommand reset (){
return new InstantCommand(

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

can use this.runOnce(() -> //code) instead of new InstantCommand, which is slightly cleaner (this is me being pedantic, also i only learned about it after i taught yall how to do it this way so oops)

()->{io.reset(0);}
);
}

public RunCommand run(double degrees) {
return new RunCommand(() -> {
io.setPosition(degrees);
}, this);
}

@Override
public void periodic() {
inputs = io.updateInputs();
Logger.processInputs("Kicker", inputs);
}
}
27 changes: 27 additions & 0 deletions src/main/java/frc/robot/subsystems/pivot/PivotIO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.

package frc.robot.subsystems.pivot;

import org.littletonrobotics.junction.AutoLog;

/** Add your docs here. */
public interface PivotIO {
@AutoLog
public class PivotIOInputs {

// Motor values
public double velocityRPM;
public double currentDrawAmps;
public double temperatureCelsius;
public double motorOutputVolts;
public double positionRotations;
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

same feedback as with kicker (its basically the same mech in software, just with more weight)


public abstract void setPosition(double degrees);

public abstract void reset(double degrees);

public abstract PivotIOInputsAutoLogged updateInputs();
}
57 changes: 57 additions & 0 deletions src/main/java/frc/robot/subsystems/pivot/PivotIOReal.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package frc.robot.subsystems.pivot;
import com.ctre.phoenix6.StatusSignal;

// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.



import com.ctre.phoenix6.configs.TalonFXConfiguration;
import com.ctre.phoenix6.controls.PositionVoltage;
import com.ctre.phoenix6.hardware.TalonFX;

import edu.wpi.first.math.util.Units;
import frc.robot.Constants;

public class PivotIOReal implements PivotIO{

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

same feedback as with kicker


private TalonFX pivotMotor = new TalonFX(Constants.PIVOT_MOTOR_ID);
private PositionVoltage motorRequest = new PositionVoltage(Constants.PIVOT_MOTOR_ID);

private StatusSignal<Double> supplyVoltageSignal = pivotMotor.getDutyCycle();
private StatusSignal<Double> position = pivotMotor.getRotorPosition();
private StatusSignal<Double> velocity = pivotMotor.getRotorVelocity();
private StatusSignal<Double> currentDraw = pivotMotor.getStatorCurrent();


public PivotIOReal (){
TalonFXConfiguration pivotConfig = new TalonFXConfiguration();
pivotConfig.Slot0.kP = 1;
pivotConfig.Slot0.kD = 0.01;
pivotConfig.Slot0.kI = 0;
}

@Override
public void setPosition(double degrees) {
pivotMotor.setControl(motorRequest.withPosition(Units.degreesToRotations(degrees)*Constants.PIVOT_GEAR_RATIO));
}

@Override
public void reset(double degrees){
pivotMotor.setPosition((Units.degreesToRotations(degrees))*Constants.PIVOT_GEAR_RATIO);
}


@Override
public PivotIOInputsAutoLogged updateInputs() {
PivotIOInputsAutoLogged current = new PivotIOInputsAutoLogged();

current.currentDrawAmps = currentDraw.refresh().getValue();
current.positionRotations = position.refresh().getValue() / Constants.PIVOT_GEAR_RATIO;
current.velocityRPM = velocity.refresh().getValue() / Constants.PIVOT_GEAR_RATIO;
current.motorOutputVolts = 12 * supplyVoltageSignal.getValue();

return(current);
}
}
55 changes: 55 additions & 0 deletions src/main/java/frc/robot/subsystems/pivot/PivotIOSim.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.

package frc.robot.subsystems.pivot;

import edu.wpi.first.math.controller.PIDController;
import edu.wpi.first.math.system.plant.DCMotor;
import edu.wpi.first.math.util.Units;
import edu.wpi.first.wpilibj.simulation.SingleJointedArmSim;

/** Add your docs here. */
public class PivotIOSim implements PivotIO {

SingleJointedArmSim arm =
new SingleJointedArmSim(
DCMotor.getFalcon500(1),
27 * (24 / 18),
SingleJointedArmSim.estimateMOI(Units.inchesToMeters(30), 3),

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

this probably needs to be updated, ill get back to you with numbers

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

tbh only do this once you have other stuff and have time to sim

Units.inchesToMeters(30),
0,
3.5,
true,
0);
PIDController pid = new PIDController(1, 0, 0);

public PivotIOInputsAutoLogged updateInputs() {

PivotIOInputsAutoLogged input = new PivotIOInputsAutoLogged();

// var motorSimState = motor.getSimState();

input.velocityRPM = arm.getVelocityRadPerSec() * 60;
input.currentDrawAmps = arm.getCurrentDrawAmps();
input.temperatureCelsius = 0;
input.motorOutputVolts = arm.getOutput(0);
input.positionRotations = Units.radiansToDegrees(arm.getAngleRads());

arm.update(0.020);

return input;
}

@Override
public void setPosition(double degrees) {
double outputVolts = pid.calculate(Units.radiansToDegrees(arm.getAngleRads()), degrees);
arm.setInput(outputVolts);
}

@Override
public void reset(double degrees) {
// TODO Auto-generated method stub

}
}
45 changes: 45 additions & 0 deletions src/main/java/frc/robot/subsystems/pivot/PivotSubsystem.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.

package frc.robot.subsystems.pivot;

import org.littletonrobotics.junction.Logger;

import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
import edu.wpi.first.wpilibj2.command.InstantCommand;
import edu.wpi.first.wpilibj2.command.RunCommand;
import edu.wpi.first.wpilibj2.command.SubsystemBase;

/** Add your docs here. */
public class PivotSubsystem extends SubsystemBase {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

same feedback as with kicker

PivotIO io;
PivotIOInputsAutoLogged inputs;

public PivotSubsystem(PivotIO io) {
this.io = io;
inputs = new PivotIOInputsAutoLogged();

SmartDashboard.putData("reset Pivot value", new InstantCommand(
()->{io.reset(0);}
));
}

public InstantCommand reset (){
return new InstantCommand(
()->{io.reset(0);}
);
}

public RunCommand run(double degrees) {
return new RunCommand(() -> {
io.setPosition(degrees);
}, this);
}

@Override
public void periodic() {
inputs = io.updateInputs();
Logger.processInputs("Pivot", inputs);
}
}
25 changes: 25 additions & 0 deletions src/main/java/frc/robot/subsystems/shooter/ShooterIO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.

package frc.robot.subsystems.shooter;

import org.littletonrobotics.junction.AutoLog;

/** Add your docs here. */
public interface ShooterIO {
@AutoLog
public class ShooterIOInputs {

// Motor values
public double velocityRPM;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

could be in rotations per second

public double currentDrawAmps;
public double temperatureCelsius;
public double motorOutputVolts; }

public abstract void setVelocity(double velocity);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

name the parameter with units, like rotationsPerSecond instead of velocity


public abstract void reset(double velocity);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

not needed for this mechanism since we dont care about position


public abstract ShooterIOInputsAutoLogged updateInputs();
}
41 changes: 41 additions & 0 deletions src/main/java/frc/robot/subsystems/shooter/ShooterIOReal.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package frc.robot.subsystems.shooter;

import com.ctre.phoenix6.StatusSignal;
import com.ctre.phoenix6.configs.TalonFXConfiguration;
import com.ctre.phoenix6.controls.VelocityVoltage;
import com.ctre.phoenix6.hardware.TalonFX;

import frc.robot.Constants;

public class ShooterIOReal {

private TalonFX bottomShooterMotor = new TalonFX(Constants.BOTTOM_SHOOTER_MOTOR_ID);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

rename to be more concise (can use f2 in vscode to rename all instances of this.)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

also same feedback about constants

private VelocityVoltage bottomShooterMotorVelocity = new VelocityVoltage(0);


private StatusSignal<Double> supplyVoltageSignal = bottomShooterMotor.getDutyCycle();

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

can use voltage instead of duty cycle

private StatusSignal<Double> velocity = bottomShooterMotor.getRotorVelocity();
private StatusSignal<Double> currentDraw = bottomShooterMotor.getStatorCurrent();

public ShooterIOReal(){
TalonFXConfiguration pivotConfig = new TalonFXConfiguration();

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

holdover name?

pivotConfig.Slot0.kP = 1;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

should also configure kV, and set all these to 0 by default

pivotConfig.Slot0.kD = 0.01;
pivotConfig.Slot0.kI = 0;
}

public void setVelocity(double velocity) {
bottomShooterMotor.setControl(bottomShooterMotorVelocity.withVelocity(velocity));
}


public ShooterIOInputsAutoLogged updateInputs() {
ShooterIOInputsAutoLogged current = new ShooterIOInputsAutoLogged();

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

name is somewhat confusing


current.currentDrawAmps = currentDraw.refresh().getValue();
current.velocityRPM = velocity.refresh().getValue() / Constants.BOTTOM_SHOOTER_GEAR_RATIO;
current.motorOutputVolts = 12 * supplyVoltageSignal.getValue();

return(current);
}
}
Loading