Skip to content

Commit

Permalink
Initial commit w/ partial done controls
Browse files Browse the repository at this point in the history
  • Loading branch information
NatalieEMann committed Feb 2, 2025
1 parent a900ed2 commit 0cb15b2
Show file tree
Hide file tree
Showing 7 changed files with 659 additions and 5 deletions.
74 changes: 74 additions & 0 deletions src/main/java/frc/robot/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,78 @@ public static final class DriveConstants {
}
}

public static final class ElevatorConstants {

public static final double kFF = 0.00008040000102482736; // Feedforward Constant
public static final int kElevatorMotorPort = 45;
public static final boolean kInvert = false;
public static final int kSmartCurrentLimit = 60;
public static final int kSecondaryCurrentLimit = 70;
public static final double kMinOutput = -1;
public static final double kMaxOutput = 1;
public static final double kP = 5;
public static final double kI = 100000;
public static final double kD = 0;
public static final double kTolerance = 1;
public static final int kMaxExtension = 250;
public static final int kLevelOneHeight = 0; /* same as level 2 */
public static final int kLevelTwoHeight = 0;
public static final double kLevelThreeHeight = 70 / 2.54;
public static final int kLevelFourHeight = 0;
public static final int kCoralStationHeight = 0;
}

public static final class ClimberConstants {
public static final int kClimberMotorPort = -1; // TODO: Add actual motor ID
public static final double kSpeed = 0.5;
}

public static final class AlgaeConstants {

// FLYWHEEL IS 550
// OTHER IS NORMAL NEO

public static final int kFlywheelMotorPort = 90;
public static final int kGrabberAnglePort = 3;
public static final boolean kFlywheelInvert = false;
public static final boolean kGrabberAngleInvert = false;

public static final int kSmartCurrentLimit = 50;
public static final int kPeakCurrentDurationMillis = 100;

public static final int k550SmartCurrentLimit = 15;

// public static final double kMaxOutput = .1;
// public static final double kMinOutput = -.1;

public static final double kCurrentToStop = 20;
public static final double kTimeOverCurrentToStop = .01;

public static final double kP = 0.5;
public static final double kI = 0.0;
public static final double kD = 0;
}

public static final class CheeseStickConstants {
public static final int kServoPort = 45;
public static final int kMaxRotation = 270;
}

public static final class WristConstants {
// CAN IDs
public static final int kWristMotorPort = 1; /* 60 */
public static final int kSmartCurrentLimit = 20;
public static final int kSecondaryCurrentLimit = 20;

// Make sure these are tuned (can do with SysId)
public static final double kP = 0.09;
public static final double kI = 0.0;
public static final double kD = 0;
public static final double kS = 0;
public static final double kV = 0.11;
public static final double kA = 0.009;

public static final double kTolerance = 0;
}

}
66 changes: 61 additions & 5 deletions src/main/java/frc/robot/Robot.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@

package frc.robot;

import static frc.robot.Constants.AlgaeConstants.*;
import static frc.robot.Constants.ClimberConstants.*;
import static frc.robot.Constants.ControllerConstants.*;
import static frc.robot.Constants.ElevatorConstants.*;
import static frc.robot.Constants.WristConstants.*;

import java.util.Map;

import org.littletonrobotics.urcl.URCL;
Expand All @@ -15,23 +21,39 @@
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.CommandScheduler;
import edu.wpi.first.wpilibj2.command.button.CommandPS4Controller;
import frc.robot.Constants.ControllerConstants;
import edu.wpi.first.wpilibj2.command.button.CommandPS5Controller;
import frc.robot.subsystems.AlgaeGrabberSubsystem;
import frc.robot.subsystems.AlgaeGrabberSubsystem.grabberState;
import frc.robot.subsystems.CheeseStickSubsystem;
import frc.robot.subsystems.ClimberSubsystem;
import frc.robot.subsystems.DriveSubsystem;
import frc.robot.subsystems.ElevatorSubsystem;
import frc.robot.subsystems.WristSubsystem;

public class Robot extends TimedRobot {
private Command m_autonomousCommand;
private final AlgaeGrabberSubsystem m_algaeGrabberSubsystem = new AlgaeGrabberSubsystem();
private final CheeseStickSubsystem m_cheeseStickSubsystem = new CheeseStickSubsystem();
private final ClimberSubsystem m_climberSubsystem = new ClimberSubsystem();
private final DriveSubsystem m_driveSubsystem = new DriveSubsystem();
private final CommandPS4Controller m_driverController = new CommandPS4Controller(
ControllerConstants.kDriverControllerPort);
private final ElevatorSubsystem m_elevatorSubsystem = new ElevatorSubsystem();
private final WristSubsystem m_WristSubsystem = new WristSubsystem();
private final CommandPS5Controller m_driverController = new CommandPS5Controller(kDriverControllerPort); // Changed
// to
// PS5
private final CommandPS5Controller m_operatorController = new CommandPS5Controller(kOperatorControllerPort);
private final PowerDistribution m_pdh = new PowerDistribution();

public Robot() {
SmartDashboard.putData(m_pdh);
SmartDashboard.putData(CommandScheduler.getInstance());
DataLogManager.start();
DataLogManager.logNetworkTables(true);
URCL.start(Map.of(11, "FR Turn", 21, "BR Turn", 31, "BL Turn", 41, "FL Turn"));
URCL.start(
Map.of(
11, "FR Turn", 21, "BR Turn", 31, "BL Turn", 41, "FL Turn", kElevatorMotorPort, "Elevator",
kClimberMotorPort, "Climber Motor", kWristMotorPort, "Wrist Motor", kFlywheelMotorPort,
"Algae Motor"));
DriverStation.startDataLog(DataLogManager.getLog());
bindDriveControls();
}
Expand All @@ -43,6 +65,40 @@ public void bindDriveControls() {
() -> -m_driverController.getLeftX(),
() -> m_driverController.getL2Axis() - m_driverController.getR2Axis(),
m_driverController.getHID()::getSquareButton));
// TODO: Add in joystick rotation
}

public void bindElevatorControls() {
m_operatorController.circle().onTrue(m_elevatorSubsystem.setPositionLevelFourCommand());
m_operatorController.triangle().onTrue(m_elevatorSubsystem.setPositionLevelThreeCommand());
m_operatorController.square().onTrue(m_elevatorSubsystem.setPositionLevelTwoCommand());
m_operatorController.cross().onTrue(m_elevatorSubsystem.setPositionLevelOneCommand());
m_operatorController.povLeft().onTrue(m_elevatorSubsystem.setPositionCoralStationCommand());
// TODO: Add manual movement
}

public void bindAlgaeControls() {
m_operatorController.R1().onTrue(
m_algaeGrabberSubsystem.deployGrabberCommand(grabberState.DOWN)
.andThen(m_algaeGrabberSubsystem.runFlywheelCommand())); // TODO: Come up after?
m_operatorController.L1().onTrue(
m_algaeGrabberSubsystem.runFlywheelReverseCommand()
.until(m_algaeGrabberSubsystem::checkCurrentOnFlywheel)
.andThen(m_algaeGrabberSubsystem.stopFlywheelCommand()));
}

public void bindWristControls() {
// TODO: Manual movement
}

public void bindCheeseStickControls() {
m_operatorController.R2().whileFalse(m_cheeseStickSubsystem.rotateCommand(0.0));
m_operatorController.R2().whileTrue(m_cheeseStickSubsystem.rotateCommand(0.0));
}

public void bindClimberControls() {
m_operatorController.L2().whileTrue(m_climberSubsystem.moveForward())
.onFalse(m_climberSubsystem.moveBackward());
}

@Override
Expand Down
150 changes: 150 additions & 0 deletions src/main/java/frc/robot/subsystems/AlgaeGrabberSubsystem.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
// 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;

import com.revrobotics.spark.SparkBase.ControlType;
import com.revrobotics.spark.SparkBase.PersistMode;
import com.revrobotics.spark.SparkBase.ResetMode;
import com.revrobotics.spark.SparkClosedLoopController;
import com.revrobotics.spark.SparkLowLevel.MotorType;
import com.revrobotics.spark.SparkMax;
import com.revrobotics.spark.config.ClosedLoopConfig.FeedbackSensor;
import com.revrobotics.spark.config.SparkBaseConfig.IdleMode;
import com.revrobotics.spark.config.SparkMaxConfig;

import edu.wpi.first.math.filter.Debouncer;
import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.SubsystemBase;
import frc.robot.Constants.AlgaeConstants;

public class AlgaeGrabberSubsystem extends SubsystemBase {
private final SparkMax m_flywheel;
private final SparkMax m_grabberAngleMotor = new SparkMax(AlgaeConstants.kGrabberAnglePort,
MotorType.kBrushless);
private final SparkClosedLoopController m_grabberClosedLoopController = m_grabberAngleMotor
.getClosedLoopController();

Debouncer m_debouncerCurrentLimitStop;

private double m_setVelocity;

public enum grabberState {
UP,
DOWN
}

public AlgaeGrabberSubsystem() {
SparkMaxConfig config;
m_debouncerCurrentLimitStop = new Debouncer(AlgaeConstants.kTimeOverCurrentToStop);
m_flywheel = new SparkMax(AlgaeConstants.kFlywheelMotorPort, MotorType.kBrushless);

// Initialize Motors
// applies the inverts and coast mode to the flywheel motors. if you want to
// make a motor spin the other way change it in the AlgaeConstants.k____Invert
// variable
// also applies voltage and current stuff to the motors

config = new SparkMaxConfig();
config.inverted(AlgaeConstants.kFlywheelInvert).idleMode(IdleMode.kBrake);
config.voltageCompensation(12).smartCurrentLimit(AlgaeConstants.k550SmartCurrentLimit);
m_flywheel.configure(config, ResetMode.kResetSafeParameters, PersistMode.kPersistParameters);

config = new SparkMaxConfig();
config.inverted(AlgaeConstants.kGrabberAngleInvert).idleMode(IdleMode.kBrake);
config.voltageCompensation(12).smartCurrentLimit(AlgaeConstants.kSmartCurrentLimit);
config.closedLoop
.feedbackSensor(FeedbackSensor.kPrimaryEncoder)
.pid(AlgaeConstants.kP, AlgaeConstants.kI, AlgaeConstants.kD);
m_grabberAngleMotor.configure(config, ResetMode.kResetSafeParameters, PersistMode.kPersistParameters);
}

@Override
public void periodic() {
// use this to check what the kCurrentToStop should be
// System.out.println(m_flywheel.getOutputCurrent());
}

public double getVelocity() {
return m_flywheel.getAbsoluteEncoder().getVelocity();
}

/**
* sets the speed for the wheels to grab the Algae balls
*
* @param velocity (double) (-1 to 1) sets m_setVelocity and changes the wheel
* to go that speed using .set from {@link SparkMax}
* @return (void) motor will spin velocity
*/
public void setVelocity(double velocity) {
m_setVelocity = velocity;
m_flywheel.set(m_setVelocity);
}

/**
* checks the current draw on the flywheel motor and will check if it's lower or
* higher than AlgaeConstants.kCurrentToStop using a debouncer
*
* @return (boolean) true -> if the current draw is higher or equal than
* kCurrentToStop
* <p>
* (boolean) false -> otherwise
*/
public boolean checkCurrentOnFlywheel() {
return m_debouncerCurrentLimitStop
.calculate(m_flywheel.getOutputCurrent() >= AlgaeConstants.kCurrentToStop);
}

/**
* command to stop the algae flywheel using the setVelocity method
*
* @return (setVelocity(0)) sets the flywheel velocity to 0
*/
public Command stopFlywheelCommand() {
return runOnce(() -> {
setVelocity(0);
});
}

/**
* command to start the algae flywheel using the setVelocity method
*
* @return (setVelocity(.75)) sets the flywheel velocity to 75%
*/
public Command runFlywheelCommand() {
return runOnce(() -> {
setVelocity(.75);
});
}

/**
* command to reverse the algae flywheel using the setVelocity method
*
* @return (setVelocity(-.75)) sets the flywheel velocity to -75%
*/
public Command runFlywheelReverseCommand() {
return runOnce(() -> {
setVelocity(-.75);
});
}

/**
* deploys the grabber for algae
*
* @param state (enum grabberState) can be UP or DOWN, UP will bring the grabber
* up, DOWN will bring it down
*
* @return moves the whole grabber setup using a PID based on the grabberState
* enum given
*/
public Command deployGrabberCommand(grabberState state) {
return runOnce(() -> {
if (grabberState.DOWN == state) {
m_grabberClosedLoopController.setReference(2, ControlType.kPosition);
} else if (grabberState.UP == state) {
m_grabberClosedLoopController.setReference(0, ControlType.kPosition);
}
});
}
}
42 changes: 42 additions & 0 deletions src/main/java/frc/robot/subsystems/CheeseStickSubsystem.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package frc.robot.subsystems;

import static frc.robot.Constants.CheeseStickConstants.*;

import edu.wpi.first.wpilibj.Servo;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.SubsystemBase;

public class CheeseStickSubsystem extends SubsystemBase {
private Servo m_motor;
public Timer time;

public CheeseStickSubsystem() {
m_motor = new Servo(kServoPort);
time = new Timer();
m_motor.setBoundsMicroseconds(2500, 0, 1500, 0, 500);
}

public void init() {
m_motor.setZeroLatch();
}

@Override
public void periodic() {
SmartDashboard.putNumber("Time", time.get());
SmartDashboard.putNumber("Position", m_motor.getPosition());
}

/**
* Rotates the servo. Does not wait for it to finish.
*
* @param angle The angle from 0 in the left to 270 in the right.
* @return The command.
*/
public Command rotateCommand(Double angle) {
if (angle == null)
return runOnce(() -> m_motor.set(.5));
return runOnce(() -> m_motor.set(angle / kMaxRotation)).withName("Rotate Servo");
}
}
Loading

0 comments on commit 0cb15b2

Please sign in to comment.