Skip to content
2 changes: 1 addition & 1 deletion src/main/deploy/pathplanner/navgrid.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/main/deploy/pathplanner/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"robotMOI": 5.018,
"robotTrackwidth": 0.546,
"driveWheelRadius": 0.049,
"driveGearing": 6.12,
"driveGearing": 7.03,
"maxDriveSpeed": 4.4,
"driveMotorType": "krakenX60FOC",
"driveCurrentLimit": 100.0,
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/frc/trigon/lib
15 changes: 4 additions & 11 deletions src/main/java/frc/trigon/robot/RobotContainer.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@

package frc.trigon.robot;

import com.pathplanner.lib.auto.AutoBuilder;
import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.Commands;
import edu.wpi.first.wpilibj2.command.sysid.SysIdRoutine;
import frc.trigon.lib.utilities.flippable.Flippable;
import frc.trigon.robot.commands.CommandConstants;
import frc.trigon.robot.commands.commandfactories.autonomous.GeneralAutonomousCommands;
import frc.trigon.robot.commands.commandfactories.FuelIntakeCommands;
import frc.trigon.robot.commands.commandfactories.GeneralCommands;
import frc.trigon.robot.commands.commandfactories.ShootingCommands;
Expand Down Expand Up @@ -38,7 +38,6 @@
import frc.trigon.robot.subsystems.swerve.Swerve;
import frc.trigon.robot.subsystems.turret.Turret;
import frc.trigon.robot.subsystems.turret.TurretCommands;
import org.littletonrobotics.junction.networktables.LoggedDashboardChooser;

public class RobotContainer {
public static final RobotPoseEstimator ROBOT_POSE_ESTIMATOR = new RobotPoseEstimator();
Expand All @@ -54,25 +53,23 @@ public class RobotContainer {
public static final Shooter SHOOTER = new Shooter();
public static final Spindexer SPINDEXER = new Spindexer();
public static final Turret TURRET = new Turret();
private LoggedDashboardChooser<Command> autoChooser;

public RobotContainer() {
initializeGeneralSystems();
buildAutoChooser();
configureBindings();
}

/**
* @return the command to run in autonomous mode
*/
public Command getAutonomousCommand() {
return autoChooser.get();
return GeneralAutonomousCommands.getAutonomousCommand();
}

private void configureBindings() {
bindDefaultCommands();
bindControllerCommands();
// configureSysIDBindings(TURRET);
// configureSysIDBindings(SWERVE);
}

private void bindDefaultCommands() {
Expand Down Expand Up @@ -103,7 +100,7 @@ private void bindControllerCommands() {
OperatorConstants.SET_FIXED_SHOOTING_POSITION_LEFT_CORNER_TRIGGER.onTrue(ShootingCommands.getChangeFixedShootingPositionCommand(ShootingCommands.FixedShootingPosition.LEFT_CORNER));
OperatorConstants.SET_FIXED_SHOOTING_POSITION_CLOSE_TO_TOWER_TRIGGER.onTrue(ShootingCommands.getChangeFixedShootingPositionCommand(ShootingCommands.FixedShootingPosition.CLOSE_TO_TOWER));
OperatorConstants.SET_FIXED_SHOOTING_POSITION_CLOSE_TO_OUTPOST_TRIGGER.onTrue(ShootingCommands.getChangeFixedShootingPositionCommand(ShootingCommands.FixedShootingPosition.CLOSE_TO_OUTPOST));
OperatorConstants.SHORT_EJECTION_TRIGGER.whileTrue(ShootingCommands.getShortEjectFuelCommand());
OperatorConstants.SHORT_EJECTION_TRIGGER.whileTrue(TurretCommands.getDebuggingCommand());
}

private void configureSysIDBindings(MotorSubsystem subsystem) {
Expand All @@ -125,8 +122,4 @@ private void initializeGeneralSystems() {
AutonomousConstants.init();
ShootingLookupTable3D.init();
}

private void buildAutoChooser() {
autoChooser = new LoggedDashboardChooser<>("AutoChooser", AutoBuilder.buildAutoChooser());
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
package frc.trigon.robot.commands.commandclasses;

import edu.wpi.first.math.MathUtil;
import edu.wpi.first.math.controller.ProfiledPIDController;
import edu.wpi.first.math.controller.PIDController;
import edu.wpi.first.math.geometry.Pose2d;
import edu.wpi.first.math.geometry.Rotation2d;
import edu.wpi.first.math.geometry.Translation2d;
import edu.wpi.first.math.trajectory.TrapezoidProfile;
import edu.wpi.first.wpilibj2.command.*;
import frc.trigon.lib.hardware.RobotHardwareStats;
import frc.trigon.lib.utilities.flippable.Flippable;
import frc.trigon.robot.RobotContainer;
import frc.trigon.robot.commands.CommandConstants;
import frc.trigon.robot.constants.OperatorConstants;
import frc.trigon.robot.misc.shootingphysics.ShootingCalculations;
import frc.trigon.robot.subsystems.swerve.SwerveCommands;
import frc.trigon.robot.subsystems.swerve.SwerveConstants;
import org.littletonrobotics.junction.Logger;
Expand All @@ -21,26 +22,26 @@
* A command class to assist in the intaking of a game piece.
*/
public class IntakeAssistCommand extends ParallelCommandGroup {
private final ProfiledPIDController
private final PIDController
xPIDController = RobotHardwareStats.isSimulation() ?
new ProfiledPIDController(5, 0, 0, new TrapezoidProfile.Constraints(5, 15)) :
new ProfiledPIDController(2.4, 0, 0, new TrapezoidProfile.Constraints(2.65, 5.5)),
new PIDController(5, 0, 0) :
new PIDController(2.4, 0, 0),
yPIDController = RobotHardwareStats.isSimulation() ?
new ProfiledPIDController(3, 0, 0.01, new TrapezoidProfile.Constraints(5, 15)) :
new ProfiledPIDController(0.3, 0, 0.03, new TrapezoidProfile.Constraints(2.65, 5.5)),
new PIDController(0.3, 0, 0) :
new PIDController(0.26, 0, 0),
thetaPIDController = RobotHardwareStats.isSimulation() ?
new ProfiledPIDController(0.1, 0, 0, new TrapezoidProfile.Constraints(2.8, 5)) :
new ProfiledPIDController(2.4, 0, 0, new TrapezoidProfile.Constraints(2.65, 5.5));
new PIDController(0.1, 0, 0) :
new PIDController(2.4, 0, 0);
private Translation2d distanceFromTrackedGamePiece;

/**
* Creates a new intake assist command that assists the driver with intaking a game piece based on the powers.
* Creates a new intake assist command that assists the driver with intaking a game piece.
*
* @param xAssistPower the amount of assist to apply to the X-axis (Forward and backwards)
* @param yAssistPower the amount of assist to apply to the Y-axis (Sideways)
* @param thetaAssistPower the amount of assist to apply to the rotation
* @param shouldAssistX should apply to the X-axis (Forward and backwards)
* @param shouldAssistY should apply to the Y-axis (Sideways)
* @param shouldAssistTheta should apply to the rotation
*/
public IntakeAssistCommand(double xAssistPower, double yAssistPower, double thetaAssistPower) {
public IntakeAssistCommand(boolean shouldAssistX, boolean shouldAssistY, boolean shouldAssistTheta) {
addCommands(
new RunCommand(this::trackGamePiece),
new SequentialCommandGroup(
Expand All @@ -49,56 +50,54 @@ public IntakeAssistCommand(double xAssistPower, double yAssistPower, double thet
new WaitUntilCommand(this::hasNoTrackedGamePiece)
).repeatedly(),
SwerveCommands.getClosedLoopSelfRelativeDriveCommand(
() -> calculateTranslationPower(true, xAssistPower),
() -> calculateTranslationPower(false, yAssistPower),
() -> calculateThetaPower(thetaAssistPower)
() -> calculateTranslationPower(true, shouldAssistX),
() -> calculateTranslationPower(false, shouldAssistY),
() -> calculateThetaPower(shouldAssistTheta)
)
);
}

private void resetPIDControllers() {
xPIDController.reset(distanceFromTrackedGamePiece.getX(), RobotContainer.SWERVE.getSelfRelativeVelocity().getX());
yPIDController.reset(distanceFromTrackedGamePiece.getY(), RobotContainer.SWERVE.getSelfRelativeVelocity().getY());
thetaPIDController.reset(distanceFromTrackedGamePiece.getAngle().getRadians(), RobotContainer.SWERVE.getRotationalVelocityRadiansPerSecond());
xPIDController.reset();
yPIDController.reset();
thetaPIDController.reset();

xPIDController.setGoal(0);
yPIDController.setGoal(0);
thetaPIDController.setGoal(0);
xPIDController.setSetpoint(0);
yPIDController.setSetpoint(0);
thetaPIDController.setSetpoint(0);
}

private double calculateTranslationPower(boolean isXAxis, double assistScalar) {
private double calculateTranslationPower(boolean isXAxis, boolean shouldAssist) {
final Translation2d selfRelativeJoystickValue = getSelfRelativeJoystickPosition();
final double joystickValue = isXAxis ? selfRelativeJoystickValue.getX() : selfRelativeJoystickValue.getY();
final double joystickValue = CommandConstants.calculateDriveStickAxisValue(isXAxis ? selfRelativeJoystickValue.getX() : selfRelativeJoystickValue.getY());

if (hasNoTrackedGamePiece())
if (!shouldAssist || hasNoTrackedGamePiece())
return joystickValue;

final double
pidOutput = clampToSwerveOutputRange(isXAxis ?
xPIDController.calculate(distanceFromTrackedGamePiece.getX()) :
yPIDController.calculate(distanceFromTrackedGamePiece.getY()));

return calculateAssistPower(assistScalar, pidOutput, joystickValue);
return calculateAssistPower(pidOutput, joystickValue);
}

private double calculateThetaPower(double assistScalar) {
final double joystickValue = OperatorConstants.DRIVER_CONTROLLER.getRightX();
private double calculateThetaPower(boolean shouldAssist) {
final double joystickValue = CommandConstants.calculateDriveStickAxisValue(OperatorConstants.DRIVER_CONTROLLER.getRightX());

if (hasNoTrackedGamePiece())
if (!shouldAssist || hasNoTrackedGamePiece())
return joystickValue;

return calculateThetaAssistPower(assistScalar, joystickValue, distanceFromTrackedGamePiece.getAngle().unaryMinus());
return calculateThetaAssistPower(joystickValue, distanceFromTrackedGamePiece.getAngle().unaryMinus());
}
Comment on lines +85 to 92
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Wrong axis scaling method for rotation.

Line 86 uses calculateDriveStickAxisValue for the rotation stick (getRightX), but this method is intended for translation axes. Based on the CommandConstants documentation, this should use calculateRotationStickAxisValue which applies the correct rotation-specific divider and shift power.

- final double joystickValue = CommandConstants.calculateDriveStickAxisValue(OperatorConstants.DRIVER_CONTROLLER.getRightX());
+ final double joystickValue = CommandConstants.calculateRotationStickAxisValue(OperatorConstants.DRIVER_CONTROLLER.getRightX());


private double calculateThetaAssistPower(double assistScalar, double joystickValue, Rotation2d thetaOffset) {
private double calculateThetaAssistPower(double joystickValue, Rotation2d thetaOffset) {
final double pidOutput = clampToSwerveOutputRange(thetaPIDController.calculate(thetaOffset.getRadians()));
return calculateAssistPower(assistScalar, pidOutput, joystickValue);
return calculateAssistPower(pidOutput, joystickValue);
}

private double calculateAssistPower(double assistScalar, double pidOutput, double joystickValue) {
if (assistScalar == 0)
return joystickValue;
return (joystickValue * (1 - assistScalar)) + (pidOutput * assistScalar);
private double calculateAssistPower(double pidOutput, double joystickValue) {
return joystickValue + pidOutput;
}
Comment on lines +99 to 101
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Result may exceed valid output range.

Adding joystickValue (up to ±1) to pidOutput (clamped to ±1) can produce values outside [-1, 1]. If the downstream drive command doesn't handle this, you may get unexpected saturation behavior.

Consider clamping the final result:

return MathUtil.clamp(joystickValue + pidOutput, -1, 1);


private boolean hasNoTrackedGamePiece() {
Expand Down Expand Up @@ -165,28 +164,17 @@ private boolean isGamePieceWithinAssistFOV(Translation2d gamePiecePosition, Pose
}

private boolean isDrivingTowardsGamePiece(Translation2d gamePieceFieldRelativePosition, Pose2d robotPose) {
final Translation2d fieldRelativeDistanceFromGamePiece = gamePieceFieldRelativePosition.minus(robotPose.getTranslation());

final double velocityTowardsGamePiece = calculateVelocityTowardsGamePiece(fieldRelativeDistanceFromGamePiece);
final Translation2d velocityRelativeToGamePiece = ShootingCalculations.calculateVelocityRelativeToPoint(gamePieceFieldRelativePosition, robotPose.getTranslation(), getFieldRelativeJoystickPosition());
if (velocityRelativeToGamePiece.getX() < Math.abs(velocityRelativeToGamePiece.getY()))
return false;
final double velocityTowardsGamePiece = velocityRelativeToGamePiece.getX() * SwerveConstants.MAXIMUM_SPEED_METERS_PER_SECOND;
return velocityTowardsGamePiece > OperatorConstants.MINIMUM_VELOCITY_TOWARDS_GAME_PIECE_FOR_INTAKE_ASSIST_METERS_PER_SECOND;
}

private double calculateMaximumAssistAngleDegrees(double gamePieceDistance) {
return OperatorConstants.INTAKE_ASSIST_MAXIMUM_ASSISTABLE_ANGLE_FORMULA.applyAsDouble(gamePieceDistance);
}

private double calculateVelocityTowardsGamePiece(Translation2d fieldRelativeDistanceFromGamePiece) {
final Translation2d fieldRelativeJoystickPosition = getFieldRelativeJoystickPosition();

final Rotation2d joystickAngle = fieldRelativeJoystickPosition.getAngle();
final Rotation2d fieldRelativeGamePieceAngleFromRobot = fieldRelativeDistanceFromGamePiece.getAngle();
final Rotation2d angularOffset = joystickAngle.minus(fieldRelativeGamePieceAngleFromRobot);

final double desiredRobotVelocity = fieldRelativeJoystickPosition.getNorm() * SwerveConstants.MAXIMUM_SPEED_METERS_PER_SECOND;

return angularOffset.getCos() * desiredRobotVelocity;
}

private double clampToSwerveOutputRange(double value) {
return MathUtil.clamp(value, -1, 1);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import edu.wpi.first.wpilibj2.command.InstantCommand;
import edu.wpi.first.wpilibj2.command.SequentialCommandGroup;
import frc.trigon.robot.RobotContainer;
import frc.trigon.robot.commands.commandfactories.AutonomousCommands;
import frc.trigon.robot.commands.commandfactories.autonomous.GeneralAutonomousCommands;
import org.littletonrobotics.junction.Logger;

import java.util.function.Supplier;
Expand Down Expand Up @@ -44,7 +44,7 @@ public boolean runsWhenDisabled() {

private Command getUpdateAutoStartPoseCommand() {
return new InstantCommand(() -> {
this.autoStartPose = AutonomousCommands.getAutoStartPose(autoName.get());
this.autoStartPose = GeneralAutonomousCommands.getAutoStartPose(autoName.get());
Logger.recordOutput("PathPlanner/AutoStartPose", autoStartPose);
});
}
Expand Down
Loading
Loading