Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 5 additions & 5 deletions src/main/java/frc/robot/RobotContainer.java
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ public void putShuffleboardCommands() {
}
if (Constants.RAMP_DEBUG) {
SmartShuffleboard.put("Ramp", "myTargetPos", 0);
SmartShuffleboard.putCommand("Ramp", "SetRamp", CommandUtil.logged(new RampMove(ramp, () -> SmartShuffleboard.getDouble("Ramp", "myTargetPos", 0))));
SmartShuffleboard.putCommand("Ramp", "SetRamp", CommandUtil.logged(new RampMove(ramp, lightStrip, () -> SmartShuffleboard.getDouble("Ramp", "myTargetPos", 0))));
// SmartShuffleboard.putCommand("Ramp", "SetArmPID400", CommandUtil.logged(new RampMove(ramp, 15 )));
// SmartShuffleboard.putCommand("Ramp", "SetArmPID500", CommandUtil.logged(new RampMove(ramp, 500)));
SmartShuffleboard.putCommand("Ramp", "ResetRamp", CommandUtil.logged(new ResetRamp(ramp, lightStrip)));
Expand Down Expand Up @@ -236,12 +236,12 @@ private void configureBindings() {

// Set up to shoot Speaker CLOSE - Y
controller.y().onTrue(CommandUtil.parallel("Setup Speaker Shot (CLOSE)",
new RampMove(ramp, () -> GameConstants.RAMP_POS_SHOOT_SPEAKER_CLOSE),
new RampMove(ramp, lightStrip ,() -> GameConstants.RAMP_POS_SHOOT_SPEAKER_CLOSE),
new ShootSpeaker(shooter, drivetrain, lightStrip)));

// Set up to shoot Speaker AWAY - X
controller.x().onTrue(CommandUtil.parallel("Setup Speaker Shot (AWAY)",
new RampMove(ramp, () -> GameConstants.RAMP_POS_SHOOT_SPEAKER_AWAY),
new RampMove(ramp, lightStrip ,() -> GameConstants.RAMP_POS_SHOOT_SPEAKER_AWAY),
new ShootSpeaker(shooter, drivetrain, lightStrip)));

// Cancell all - B
Expand All @@ -252,14 +252,14 @@ private void configureBindings() {
new TimedFeeder(feeder, lightStrip, Constants.TIMED_FEEDER_EXIT),
new WaitCommand(GameConstants.SHOOTER_TIME_BEFORE_STOPPING),
new StopShooter(shooter),
new RampMove(ramp, () -> GameConstants.RAMP_POS_STOW)));
new RampMove(ramp, lightStrip ,() -> GameConstants.RAMP_POS_STOW)));

//Driver Shoot
joyRightButton2.onTrue(CommandUtil.sequence("Driver Shoot",
new TimedFeeder(feeder,lightStrip, Constants.TIMED_FEEDER_EXIT),
new WaitCommand(GameConstants.SHOOTER_TIME_BEFORE_STOPPING),
new StopShooter(shooter),
new RampMove(ramp, () -> GameConstants.RAMP_POS_STOW))
new RampMove(ramp, lightStrip, () -> GameConstants.RAMP_POS_STOW))
);

// start intaking a note
Expand Down
24 changes: 21 additions & 3 deletions src/main/java/frc/robot/commands/ramp/RampMove.java
Original file line number Diff line number Diff line change
@@ -1,33 +1,51 @@
package frc.robot.commands.ramp;

import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj2.command.Command;
import frc.robot.constants.Constants;
import frc.robot.subsystems.LightStrip;
import frc.robot.subsystems.Ramp;
import frc.robot.utils.TimeoutCounter;

import java.util.function.DoubleSupplier;

public class RampMove extends Command{
public class RampMove extends Command {

private final Ramp ramp;
private final DoubleSupplier encoderValue;
private final TimeoutCounter timeoutCounter;
private final Timer timer = new Timer();

public RampMove(Ramp ramp, DoubleSupplier encoderValue) {
public RampMove(Ramp ramp, LightStrip lightStrip, DoubleSupplier encoderValue) {
this.ramp = ramp;
this.encoderValue = encoderValue;
this.timeoutCounter = new TimeoutCounter("RampMove", lightStrip);
addRequirements(this.ramp);
}

@Override
public void initialize() {
timer.restart();
ramp.setRampPos(encoderValue.getAsDouble());
}


@Override
public void execute() {
ramp.updateFF();
}

@Override
public void end(boolean interrupted) {
timer.stop();
}

@Override
public boolean isFinished() {
if (timer.hasElapsed(Constants.RAMP_MOVE_TIMEOUT)){
timeoutCounter.increaseTimeoutCount();
return true;
}
return Math.abs(ramp.getRampPos() - ramp.getDesiredPosition()) < Constants.RAMP_MOVE_THRESHOLD;
}
}
1 change: 1 addition & 0 deletions src/main/java/frc/robot/commands/ramp/RampMoveAndWait.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public void initialize() {

@Override
public void execute() {
ramp.updateFF();
}

@Override
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/frc/robot/constants/GameConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ public class GameConstants {
public static final boolean ENABLE_VISION = true;
public static final boolean LED_DEBUG = false;
public static final boolean RELY_COLOR_SENSOR = false;
public static final boolean LOG_LIMIT_SWITCHES = true;
public static final boolean DRIVE_CURRENT_DEBUG = false;


//AMP
public static final double SHOOT_AMP_MOTOR_SPEED = 0.2;//0.2
Expand Down Expand Up @@ -154,5 +157,7 @@ public class GameConstants {
public static final double RAMP_ELIM_FF_THRESHOLD = 0.075;
public static final int LIGHTSTRIP_PORT = 7;
public static final long GYRO_THREAD_RATE_MS = 10;
public static final double RAMP_MOVE_THRESHOLD = 0.001;
public static final double RAMP_MOVE_TIMEOUT = 5;

}
6 changes: 5 additions & 1 deletion src/main/java/frc/robot/subsystems/Climber.java
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,11 @@ public void periodic() {

SmartShuffleboard.put("Climber", "Left Encoder", climberLeft.getEncoder().getPosition());
SmartShuffleboard.put("Climber", "Right Encoder", climberRight.getEncoder().getPosition());
Logger.logBoolean(baseLogName + "climber/engaged",ratchetEngaged, Constants.ENABLE_LOGGING);
}
if (Constants.LOG_LIMIT_SWITCHES){
Logger.logBoolean(baseLogName + "climber/isRevLeftLmt",isLeftReverseLimitSwitchPressed(), Constants.ENABLE_LOGGING);
Logger.logBoolean(baseLogName + "climber/isRevRightLmt",isRightReverseLimitSwitchPressed(), Constants.ENABLE_LOGGING);
}
Logger.logBoolean(baseLogName + "climber/engaged",ratchetEngaged, Constants.ENABLE_LOGGING);
}
}
16 changes: 8 additions & 8 deletions src/main/java/frc/robot/subsystems/Deployer.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,15 @@ public void periodic() {
SmartShuffleboard.put("Deployer", "encoder", getEncoder());
SmartShuffleboard.put("Deployer", "Fwd Limt", isDeployerForwardLimitSwitchClosed());
SmartShuffleboard.put("Deployer", "Rev Limit", isDeployerReverseLimitSwitchClosed());
SmartShuffleboard.put("Driver", "Is Intake Deployer Raised?", isDeployerForwardLimitSwitchClosed())
.withPosition(0, 2)
.withSize(2, 2);
}

/*
SmartShuffleboard.put("Driver", "Is Intake Deployer Raised?", isDeployerForwardLimitSwitchClosed())
.withPosition(0, 2)
.withSize(2, 2);
*/
Logger.logBoolean(baseLogName + "FWD LMT", isDeployerForwardLimitSwitchClosed(), Constants.ENABLE_LOGGING);
Logger.logBoolean(baseLogName + "REV LMT", isDeployerForwardLimitSwitchClosed(), Constants.ENABLE_LOGGING);
if (Constants.LOG_LIMIT_SWITCHES) {
Logger.logBoolean(baseLogName + "FWD LMT", isDeployerForwardLimitSwitchClosed(), Constants.ENABLE_LOGGING);
Logger.logBoolean(baseLogName + "REV LMT", isDeployerForwardLimitSwitchClosed(), Constants.ENABLE_LOGGING);
}

}

//Spin deployer motor
Expand Down
10 changes: 4 additions & 6 deletions src/main/java/frc/robot/subsystems/Feeder.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,12 @@ public void periodic() {
SmartShuffleboard.put("Feeder", "Color Sensor", "Certainty", matchedColor.confidence);
SmartShuffleboard.put("Feeder", "Piece Seen Incoming", pieceSeen(true));
SmartShuffleboard.put("Feeder", "Piece Seen Reverse", pieceSeen(false));
SmartShuffleboard.put("Driver", "Has Game Piece?", pieceSeen(false))
.withPosition(0, 0)
.withSize(2, 2);
Logger.logDouble(baseLogName + "FeederMotorSpeed",getFeederMotorSpeed(),Constants.ENABLE_LOGGING);
}

/*
SmartShuffleboard.put("Driver", "Has Game Piece?", pieceSeen(false))
.withPosition(0, 0)
.withSize(2, 2);
*/
Logger.logDouble(baseLogName + "FeederMotorSpeed",getFeederMotorSpeed(),Constants.ENABLE_LOGGING);
}

public boolean getForwardSwitchTripped() {
Expand Down
58 changes: 32 additions & 26 deletions src/main/java/frc/robot/subsystems/LightStrip.java
Original file line number Diff line number Diff line change
@@ -1,52 +1,58 @@
package frc.robot.subsystems;

import edu.wpi.first.wpilibj.motorcontrol.Spark;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
import edu.wpi.first.wpilibj2.command.SubsystemBase;
import frc.robot.constants.Constants;
import frc.robot.utils.BlinkinPattern;
import frc.robot.utils.logging.Logger;
import frc.robot.utils.smartshuffleboard.SmartShuffleboard;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BooleanSupplier;

public class LightStrip extends SubsystemBase {
private static final String baseLogName = "/robot/lightstrip/";
private final Spark colorSensorPort;
private BlinkinPattern pattern = BlinkinPattern.WHITE;
private final Map<BooleanSupplier, BlinkinPattern> predicateLightEvents = new HashMap<>();

private final AtomicReference<BlinkinPattern> pattern = new AtomicReference<>(BlinkinPattern.BLACK);
private final ConcurrentHashMap<BooleanSupplier, BlinkinPattern> predicateLightEvents = new ConcurrentHashMap<>();
private final AtomicBoolean running = new AtomicBoolean(true);
public LightStrip(int port) {
this.colorSensorPort = new Spark(port);
}

@Override
public void periodic() {
predicateLightEvents.keySet()
.stream()
.filter(BooleanSupplier::getAsBoolean)
.findFirst()
.ifPresent(c -> {
setPattern(predicateLightEvents.get(c));
predicateLightEvents.remove(c);
Logger.logInteger(baseLogName + "predicateSize", predicateLightEvents.size(), Constants.ENABLE_LOGGING);
new Thread(() -> {
while (running.get()){
for (BooleanSupplier supplier : predicateLightEvents.keySet()){
if (supplier.getAsBoolean()){
setPattern(predicateLightEvents.get(supplier));
predicateLightEvents.remove(supplier);
break;
}
}
);
try {
Thread.sleep(40);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}).start();
}

public void setPattern(BlinkinPattern pattern) {
this.pattern = pattern;
this.pattern.set(pattern);
Copy link
Contributor

Choose a reason for hiding this comment

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

Seems like there is no real need to protect the pattern and the running since they are primitives (boolean and a reference), though using an atomic reference here does not hurt. The one thing that does require protecting as it is modified from both threads is the map, which is currently vulnerable.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

changed to concurrent hashmap

colorSensorPort.set(pattern.getPwm());
SmartDashboard.putString("PATTERN",pattern.toString());
Logger.logDouble(baseLogName + "pwmSignal", pattern.getPwm(), Constants.ENABLE_LOGGING);
Logger.logString(baseLogName + "pwmName", pattern.toString(), Constants.ENABLE_LOGGING);
if (Constants.LED_DEBUG){
SmartShuffleboard.put("Lightstrip", "pwm", pattern.getPwm());
SmartShuffleboard.put("Lightstrip", "pattern", pattern.toString());
}
}

public BlinkinPattern getPattern() {
return pattern;
return pattern.get();
}
public void scheduleOnTrue(BooleanSupplier callable, BlinkinPattern pattern) {
predicateLightEvents.put(callable, pattern);
}

public void setRunning(boolean running) {
this.running.set(running);
}
}
67 changes: 36 additions & 31 deletions src/main/java/frc/robot/subsystems/Ramp.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ public class Ramp extends SubsystemBase {
private final NeoPidMotor neoPidMotor;
private double rampPos = Constants.RAMP_POS;
private final InterpolatingDoubleTreeMap rampAngleMap = new InterpolatingDoubleTreeMap();
private double neoModerFF = Constants.RAMP_PID_FAR_FF;

public Ramp() {
neoPidMotor = new NeoPidMotor(Constants.RAMP_ID);
configureMotor();
Expand All @@ -32,48 +34,33 @@ private void configureMotor() {
neoPidMotor.setSmartMotionAllowedClosedLoopError(Constants.RAMP_ERROR_RANGE);
neoPidMotor.setMaxAccel(Constants.RAMP_MAX_RPM_ACCELERATION);
neoPidMotor.getPidController().setP(Constants.RAMP_PID_P);
neoPidMotor.getPidController().setFF(Constants.RAMP_PID_FAR_FF);
neoPidMotor.getPidController().setFF(neoModerFF);
}

public void periodic() {
if (Math.abs(getRampPos() - getDesiredPosition()) <= Constants.RAMP_ELIM_FF_THRESHOLD){
neoPidMotor.getPidController().setFF(NeoPidMotor.DEFAULT_FF);
}else{
neoPidMotor.getPidController().setFF(Constants.RAMP_PID_FAR_FF);
}
if (Constants.RAMP_DEBUG){
SmartShuffleboard.put("Ramp", "Encoder Value", getRampPos());
SmartShuffleboard.put("Ramp", "Desired pos", rampPos);
SmartShuffleboard.put("Ramp", "Reverse Switch Tripped", getReversedSwitchState());
SmartShuffleboard.put("Ramp", "Forward Switch Tripped", getForwardSwitchState());
// double pidP = SmartShuffleboard.getDouble("Ramp", "PID P", neoPidMotor.getPidController().getP());
Copy link
Contributor

Choose a reason for hiding this comment

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

The code above (setting thePID_FF) can probably be be part of a command rather then run every time in periodic

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since the ramp is a PID and the MoveRamp command finishes instantly, what do you recommend? Reading the document it does say to use the method "Infrequently" because it takes time. I could store the last PID Value and compare against it before setting it?

Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a functional reason that the command be done immediately? I would think that it would make sense for a command to terminate once the ramp it at the position.
So you can have a sequential group of two commands: One to get the ramp "close enough" with FF and another to get the ramp closer (without the FF), and the second one to end once the ramp error is within range.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I checked and I don't think it will break anything if I make the ramp move not end immediately. I added the logic to the ramp commands

// double pidI = SmartShuffleboard.getDouble("Ramp", "PID I", neoPidMotor.getPidController().getI());
// double pidD = SmartShuffleboard.getDouble("Ramp", "PID D", neoPidMotor.getPidController().getD());
// double pidFF = SmartShuffleboard.getDouble("Ramp", "PID FF", neoPidMotor.getPidController().getFF());
// if (pidP != neoPidMotor.getPidController().getP()) neoPidMotor.getPidController().setP(pidP);
// if (pidI != neoPidMotor.getPidController().getI()) neoPidMotor.getPidController().setI(pidI);
// if (pidD != neoPidMotor.getPidController().getD()) neoPidMotor.getPidController().setD(pidD);
// if (pidFF != neoPidMotor.getPidController().getFF()) neoPidMotor.getPidController().setFF(pidFF);
SmartShuffleboard.put("Driver", "Speaker Close", isShootCloseAngle())
.withPosition(9, 0)
.withSize(1, 1);
SmartShuffleboard.put("Driver", "Speaker Away", isShootAwayAngle())
.withPosition(9, 1)
.withSize(1, 1);
SmartShuffleboard.put("Driver", "Amp", isShootAmpAngle())
.withPosition(8, 1)
.withSize(1, 1);
SmartShuffleboard.put("Ramp", "Forward Switch Tripped", getForwardSwitchState());
Copy link
Contributor

Choose a reason for hiding this comment

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

why deleting the debug shuffleboard values?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

delete selection was to big when removing pid stuff

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

SmartShuffleboard.put("Ramp", "Forward Switch Tripped", getForwardSwitchState());
Logger.logDouble(baseLogName + "EncoderValue", getRampPos(), Constants.ENABLE_LOGGING);
Logger.logDouble(baseLogName + "DesiredPos", rampPos, Constants.ENABLE_LOGGING);
}
if (Constants.LOG_LIMIT_SWITCHES){
Logger.logBoolean(baseLogName + "FWD LMT", getForwardSwitchState(), Constants.ENABLE_LOGGING);
Logger.logBoolean(baseLogName + "REV LMT", getReversedSwitchState(), Constants.ENABLE_LOGGING);
}

Logger.logDouble(baseLogName + "EncoderValue", getRampPos(), Constants.ENABLE_LOGGING);
Logger.logDouble(baseLogName + "DesiredPos", rampPos, Constants.ENABLE_LOGGING);
Logger.logBoolean(baseLogName + "FWD LMT", getForwardSwitchState(), Constants.ENABLE_LOGGING);
Logger.logBoolean(baseLogName + "REV LMT", getReversedSwitchState(), Constants.ENABLE_LOGGING);

/*
SmartShuffleboard.put("Driver", "Speaker Close", isShootCloseAngle())
.withPosition(9, 0)
.withSize(1, 1);
SmartShuffleboard.put("Driver", "Speaker Away", isShootAwayAngle())
.withPosition(9, 1)
.withSize(1, 1);
SmartShuffleboard.put("Driver", "Amp", isShootAmpAngle())
.withPosition(8, 1)
.withSize(1, 1);
*/
}

public void setRampPos(double targetPosition) {
Expand Down Expand Up @@ -150,4 +137,22 @@ public void setAngle(Rotation2d angleFromGround) {
public double calcPose(Pose2d pose2d, Alignable alignable) {
return rampAngleMap.get(pose2d.getTranslation().getDistance(new Translation2d(alignable.getX(), alignable.getY())));
}

public void setFF(double feedForward) {
neoPidMotor.getPidController().setFF(feedForward);
neoModerFF = feedForward;
}
public double getFF(){
return neoModerFF;
}

public void updateFF() {
if (Math.abs(getRampPos() - getDesiredPosition()) <= Constants.RAMP_ELIM_FF_THRESHOLD) {
if (getFF() != NeoPidMotor.DEFAULT_FF) {
setFF(NeoPidMotor.DEFAULT_FF);
}
} else if (getFF() != Constants.RAMP_PID_FAR_FF) {
setFF(Constants.RAMP_PID_FAR_FF);
}
}
}
Loading