-
Notifications
You must be signed in to change notification settings - Fork 0
Yishay Amir #11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
yisha23
wants to merge
18
commits into
main
Choose a base branch
from
side-shooter-yishay
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Yishay Amir #11
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
d46d959
added sideShooterConstantas
yisha23 930fe12
fix according to the rewiew
yisha23 32726f0
added optimizeBusUtilization()
yisha23 c8dc826
created getSetTargetAngleCommand
yisha23 04041e5
fixed according to code rewiew
yisha23 c702353
created SideShooterCommands
yisha23 50c5418
fixed according to code rewiew
yisha23 0b793c0
finished subsystem
yisha23 0e67372
created ArmConstants
yisha23 e937844
reformat class
yisha23 6ec507a
fixed according to code review
yisha23 ab18038
fixed according to code reviwe
yisha23 c67882f
added Arm and ArmCommands
yisha23 ca4f95e
added feedforward
yisha23 847e2bf
fixed according code review
yisha23 f5dfefe
fixed according code review
yisha23 6adcef7
fixed according code review
yisha23 55212d1
fixed according code review
yisha23 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
package frc.trigon.robot.subsystems.arm; | ||
|
||
import com.ctre.phoenix.motorcontrol.can.TalonSRX; | ||
import com.revrobotics.CANSparkMax; | ||
import edu.wpi.first.math.geometry.Rotation2d; | ||
import edu.wpi.first.math.trajectory.TrapezoidProfile; | ||
import edu.wpi.first.math.util.Units; | ||
import edu.wpi.first.wpilibj.Timer; | ||
import edu.wpi.first.wpilibj2.command.SubsystemBase; | ||
import frc.trigon.robot.utilities.Conversions; | ||
|
||
public class Arm extends SubsystemBase { | ||
private final static Arm INSTANCE = new Arm(); | ||
private final CANSparkMax | ||
masterElevatorMotor = ArmConstants.MASTER_ELEVATOR_MOTOR, | ||
followerElevatorMotor = ArmConstants.FOLLOWER_ELEVATOR_MOTOR, | ||
masterAngleMotor = ArmConstants.MASTER_ELEVATOR_MOTOR, | ||
followerAngleMotor = ArmConstants.FOLLOWER_ANGLE_MOTOR; | ||
private final TalonSRX elevatorEncoder = ArmConstants.ELEVATOR_ENCODER; | ||
private TrapezoidProfile | ||
angleMotorProfile = null, | ||
elevatorMotorProfile = null; | ||
private double | ||
lastAngleMotorProfileGeneration, | ||
lastElevatorMotorProfileGeneration; | ||
|
||
public static Arm getInstance() { | ||
return INSTANCE; | ||
} | ||
|
||
private Arm() { | ||
} | ||
|
||
void generateElevatorMotorProfile(double targetPositionMeters, double speedPercentage) { | ||
elevatorMotorProfile = new TrapezoidProfile( | ||
Conversions.scaleConstraints(ArmConstants.ELEVATOR_CONSTRAINTS, speedPercentage), | ||
new TrapezoidProfile.State(targetPositionMeters, 0), | ||
new TrapezoidProfile.State(getElevatorPositionRevolutions(), getElevatorVelocityMetersPerSeconds()) | ||
); | ||
|
||
lastElevatorMotorProfileGeneration = Timer.getFPGATimestamp(); | ||
} | ||
|
||
void generateAngleMotorProfile(Rotation2d targetAngle, double speedPercentage) { | ||
angleMotorProfile = new TrapezoidProfile( | ||
Conversions.scaleConstraints(ArmConstants.ANGLE_CONSTRAINTS, speedPercentage), | ||
new TrapezoidProfile.State(targetAngle.getDegrees(), 0), | ||
new TrapezoidProfile.State(getAnglePosition().getDegrees(), getAngleVelocityDegreesPerSeconds()) | ||
); | ||
|
||
lastAngleMotorProfileGeneration = Timer.getFPGATimestamp(); | ||
} | ||
|
||
void setTargetAngleFromProfile() { | ||
if (angleMotorProfile == null) { | ||
stopAngleMotors(); | ||
return; | ||
} | ||
|
||
TrapezoidProfile.State targetState = angleMotorProfile.calculate(getAngleProfileTime()); | ||
setAngleMotorsVoltage(calculateAngleOutput(targetState)); | ||
} | ||
|
||
void setTargetElevatorPositionFromProfile() { | ||
if (angleMotorProfile == null) { | ||
stopElevatorMotors(); | ||
return; | ||
} | ||
|
||
TrapezoidProfile.State targetState = elevatorMotorProfile.calculate(getElevatorProfileTime()); | ||
setElevatorMotorsVoltage(calculateElevatorOutput(targetState)); | ||
} | ||
|
||
boolean atAngle(Rotation2d angle) { | ||
return Math.abs(angle.getDegrees() - getAnglePosition().getDegrees()) < ArmConstants.ANGLE_TOLERANCE_DEGREES; | ||
} | ||
|
||
boolean atTargetPositionElevator(double positionMeters) { | ||
return Math.abs(positionMeters - getElevatorPositionRevolutions()) < ArmConstants.ELEVATOR_TOLERANCE_METERS; | ||
} | ||
|
||
boolean isElevatorOpening(double targetMeters) { | ||
return targetMeters > getElevatorPositionRevolutions(); | ||
} | ||
|
||
private double getElevatorVelocityMetersPerSeconds() { | ||
double elevatorVelocityMagTicksPer100ms = elevatorEncoder.getSelectedSensorVelocity(); | ||
double elevatorVelocityMagTicksPerSecond = Conversions.perHundredMsToPerSecond(elevatorVelocityMagTicksPer100ms); | ||
double elevatorVelocityRevolutionPerSecond = Conversions.magTicksToRevolutions(elevatorVelocityMagTicksPerSecond); | ||
return elevatorVelocityRevolutionPerSecond / ArmConstants.ELEVATOR_METERS_PER_REVOLUTION; | ||
} | ||
|
||
private Rotation2d getAnglePosition() { | ||
double positionRevolutions = ArmConstants.ANGLE_ENCODER_POSITION_SIGNAL.refresh().getValue(); | ||
return Rotation2d.fromRotations(positionRevolutions); | ||
} | ||
|
||
private double getElevatorPositionRevolutions() { | ||
double elevatorPositionMagTicks = elevatorEncoder.getSelectedSensorPosition(); | ||
double elevatorPositionRevolution = Conversions.magTicksToRevolutions(elevatorPositionMagTicks); | ||
yisha23 marked this conversation as resolved.
Show resolved
Hide resolved
yisha23 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return elevatorPositionRevolution / ArmConstants.ELEVATOR_METERS_PER_REVOLUTION; | ||
yisha23 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
private double getAngleVelocityDegreesPerSeconds() { | ||
return Conversions.revolutionsToDegrees(ArmConstants.ANGLE_ENCODER_VELOCITY_SIGNAL.refresh().getValue()); | ||
} | ||
|
||
private double calculateElevatorOutput(TrapezoidProfile.State targetState) { | ||
double pidOutput = ArmConstants.ELEVATOR_PID_CONTROLLER.calculate( | ||
getElevatorPositionRevolutions(), | ||
targetState.position | ||
); | ||
|
||
double feedforward = ArmConstants.ELEVATOR_MOTOR_FEEDFORWARD.calculate( | ||
targetState.velocity | ||
); | ||
|
||
return pidOutput + feedforward; | ||
} | ||
|
||
private double calculateAngleOutput(TrapezoidProfile.State targetState) { | ||
double pidOutput = ArmConstants.ANGLE_PID_CONTROLLER.calculate( | ||
getAnglePosition().getDegrees(), | ||
targetState.position | ||
); | ||
|
||
double feedforward = ArmConstants.ANGLE_MOTOR_FEEDFORWARD.calculate( | ||
Units.degreesToRadians(targetState.position), | ||
Units.degreesToRadians(targetState.velocity) | ||
); | ||
|
||
return pidOutput + feedforward; | ||
} | ||
|
||
private void setAngleMotorsVoltage(double outputVoltage) { | ||
masterAngleMotor.setVoltage(outputVoltage); | ||
followerAngleMotor.setVoltage(outputVoltage); | ||
} | ||
|
||
private void setElevatorMotorsVoltage(double outputVoltage) { | ||
masterElevatorMotor.setVoltage(outputVoltage); | ||
followerElevatorMotor.setVoltage(outputVoltage); | ||
} | ||
|
||
private double getAngleProfileTime() { | ||
return Timer.getFPGATimestamp() - lastAngleMotorProfileGeneration; | ||
} | ||
|
||
private double getElevatorProfileTime() { | ||
return Timer.getFPGATimestamp() - lastElevatorMotorProfileGeneration; | ||
} | ||
|
||
private void stopElevatorMotors() { | ||
masterElevatorMotor.stopMotor(); | ||
followerElevatorMotor.stopMotor(); | ||
} | ||
|
||
private void stopAngleMotors() { | ||
masterAngleMotor.stopMotor(); | ||
followerAngleMotor.stopMotor(); | ||
} | ||
} |
81 changes: 81 additions & 0 deletions
81
src/main/java/frc/trigon/robot/subsystems/arm/ArmCommands.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package frc.trigon.robot.subsystems.arm; | ||
|
||
import edu.wpi.first.math.geometry.Rotation2d; | ||
import edu.wpi.first.wpilibj2.command.Command; | ||
import edu.wpi.first.wpilibj2.command.DeferredCommand; | ||
import edu.wpi.first.wpilibj2.command.FunctionalCommand; | ||
import edu.wpi.first.wpilibj2.command.SequentialCommandGroup; | ||
|
||
import java.util.Set; | ||
|
||
public class ArmCommands { | ||
private static final Arm ARM = Arm.getInstance(); | ||
|
||
public static Command getSetTargetStateCommand(ArmConstants.ArmState state) { | ||
return getSetTargetPositionCommand(state.angle, state.elevatorPositionMeters, 100, 100); | ||
} | ||
|
||
/** | ||
* set the arm to the wanted state | ||
* | ||
* @param state the wanted state | ||
* @param elevatorSpeedPercentage max speed of the elevator in percentages | ||
* @param angleSpeedPercentage max speed of the elevator angle in percentages | ||
* @return a command | ||
*/ | ||
public static Command getsetTargetStateCommand(ArmConstants.ArmState state, double elevatorSpeedPercentage, double angleSpeedPercentage) { | ||
return getSetTargetPositionCommand(state.angle, state.elevatorPositionMeters, elevatorSpeedPercentage, angleSpeedPercentage); | ||
} | ||
|
||
public static Command getSetTargetPositionCommand(Rotation2d targetAngle, double targetElevatorPositionMeters) { | ||
return getSetTargetPositionCommand(targetAngle, targetElevatorPositionMeters, 100, 100); | ||
} | ||
|
||
/** | ||
* set the arm to the wanted position | ||
* | ||
* @param targetAngle the target angle | ||
* @param targetElevatorPositionMeters the target of the elevator | ||
* @param elevatorSpeedPercentage max speed of the elevator in percentages | ||
* @param angleSpeedPercentage max speed of the elevator angle in percentages | ||
* @return a command | ||
*/ | ||
public static Command getSetTargetPositionCommand(Rotation2d targetAngle, double targetElevatorPositionMeters, double elevatorSpeedPercentage, double angleSpeedPercentage) { | ||
return new DeferredCommand(() -> getCurrentSetTargetPositionCommand(targetAngle, targetElevatorPositionMeters, elevatorSpeedPercentage, angleSpeedPercentage), Set.of()); | ||
} | ||
|
||
private static Command getCurrentSetTargetPositionCommand(Rotation2d targetAngle, double targetElevatorPositionMeters, double elevatorSpeedPercentage, double angleSpeedPercentage) { | ||
if (ARM.isElevatorOpening(targetElevatorPositionMeters)) { | ||
return new SequentialCommandGroup( | ||
getSetTargetAngleCommand(targetAngle, angleSpeedPercentage).until(() -> ARM.atAngle(targetAngle)), | ||
getSetTargetElevatorPositionCommand(targetElevatorPositionMeters, elevatorSpeedPercentage) | ||
); | ||
} | ||
return new SequentialCommandGroup( | ||
getSetTargetElevatorPositionCommand(targetElevatorPositionMeters, elevatorSpeedPercentage).until(() -> ARM.atTargetPositionElevator(targetElevatorPositionMeters)), | ||
getSetTargetAngleCommand(targetAngle, angleSpeedPercentage) | ||
); | ||
} | ||
|
||
private static Command getSetTargetAngleCommand(Rotation2d targetAngle, double SpeedPercentage) { | ||
return new FunctionalCommand( | ||
() -> ARM.generateAngleMotorProfile(targetAngle, SpeedPercentage), | ||
ARM::setTargetAngleFromProfile, | ||
(interrupted) -> { | ||
}, | ||
() -> false, | ||
ARM | ||
); | ||
} | ||
|
||
private static Command getSetTargetElevatorPositionCommand(double targetElevatorPositionMeters, double SpeedPercentage) { | ||
return new FunctionalCommand( | ||
() -> ARM.generateElevatorMotorProfile(targetElevatorPositionMeters, SpeedPercentage), | ||
ARM::setTargetElevatorPositionFromProfile, | ||
(interrupted) -> { | ||
}, | ||
() -> false, | ||
ARM | ||
); | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.