generated from Programming-TRIGON/RobotTemplate
-
Notifications
You must be signed in to change notification settings - Fork 0
Subsystem Wrapper #54
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
Strflightmight09
wants to merge
50
commits into
main
Choose a base branch
from
subsystem-wrapper
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
Changes from 36 commits
Commits
Show all changes
50 commits
Select commit
Hold shift + click to select a range
2b55554
Only "works" for talonfx but I need to commit to test
Strflightmight09 3b0f64d
Better prob
Strflightmight09 0393268
Oops
Strflightmight09 b99cc94
Trying smth
Strflightmight09 c4c8b1a
Oops
Strflightmight09 e8db114
Testing
Strflightmight09 e0b76dd
Remove testing (that part works)
Strflightmight09 ef1488b
More testing
Strflightmight09 75c3b8b
Omg I'm so stupid
Strflightmight09 49a3515
nvm
Strflightmight09 88e48ef
Wrong, but not _the_ problem
Strflightmight09 b416895
Test
Strflightmight09 4cf4d18
I should prob do this
Strflightmight09 c43315a
SImplify
Strflightmight09 68ecc92
_
Strflightmight09 a80bf39
Oops
Strflightmight09 efaf9fc
Better logging
Strflightmight09 a40296f
Fix
Strflightmight09 723cd44
Fix
Strflightmight09 948089f
Added arm even tho it doesn't work
Strflightmight09 395f300
Merge branch 'main' into subsystem-wrapper
Strflightmight09 e71735a
@ShmayaR - Have fun :)
Strflightmight09 0d053c8
fixed up the simpleMotorSubsystem (still missing simulation)
ShmayaR 612c1a7
added logging stuff
ShmayaR 17c777e
added option for setting target state with velocity
ShmayaR 9be9ce1
@noamgreen12 CODEEEEEEEEEEEEEEEEEEEE
Strflightmight09 b9f1289
Added visualization offset @noamgreen12...
Strflightmight09 2340eac
Update SimpleMotorSubsystem.java
ShmayaR 853e295
angular velocity gets logged instead of linear and set target velocit…
ShmayaR fd7a890
updated target state first
ShmayaR b933b18
set mechanism to update based on control mode
ShmayaR 41fb35b
Update SimpleMotorSubsystem.java
ShmayaR 1eab762
added position (in degrees) to the update log
ShmayaR a4f05cc
update name
ShmayaR 8977f6d
put position on top
ShmayaR 630e5b4
updated at target state to work with voltage control mode
ShmayaR 91a72ee
added tolerances to at target state function
ShmayaR abc0f01
contol mode is now set when subsystem is created
ShmayaR 62c0da4
Update SimpleMotorSubsystem.java
ShmayaR 0316909
removed voltage tolerance and put things that belong in the config in…
ShmayaR c23b57d
at target state no longer checks the voltage but just if it has one
ShmayaR f03aecc
update name
ShmayaR c767967
Update SimpleMotorSubsystem.java
ShmayaR aef47a2
blahdwewed
ShmayaR 49c96d7
fixed if statemennt
ShmayaR f420000
removed new line
ShmayaR 081cabd
added java docs to flywheel
ShmayaR 395e402
added docs for the rest of the configs
ShmayaR 1e2ae32
changed interface to only have 1 thing difh
ShmayaR 8b89049
added java docs for the interfaces
ShmayaR 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
28 changes: 28 additions & 0 deletions
28
src/main/java/org/trigon/hardware/subsystems/arm/ArmConfiguration.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,28 @@ | ||||||
| package org.trigon.hardware.subsystems.arm; | ||||||
|
|
||||||
| import edu.wpi.first.math.geometry.Rotation2d; | ||||||
| import edu.wpi.first.math.system.plant.DCMotor; | ||||||
| import edu.wpi.first.wpilibj.util.Color; | ||||||
|
|
||||||
| public class ArmConfiguration { | ||||||
| public String name = ""; | ||||||
| public double | ||||||
| lengthMeters = 1, | ||||||
| maximumVelocity = 1, | ||||||
| maximumAcceleration = 1, | ||||||
| maximumJerk = 1, | ||||||
| sysIDRampRate = 1, | ||||||
| sysIDStepVoltage = 1, | ||||||
| gearRatio = 1, | ||||||
| massKilograms = 1, | ||||||
| visualizationOffset = 1; | ||||||
| public Rotation2d | ||||||
| maximumAngle = Rotation2d.kZero, | ||||||
| minimumAngle = Rotation2d.kZero, | ||||||
| angleTolerance = Rotation2d.kZero; | ||||||
| public boolean | ||||||
| focEnabled = true, | ||||||
| shouldSimulateGravity = true; | ||||||
| public Color mechanismColor = Color.kBlue; | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Rn it sounds like the physical colour of the mechanism |
||||||
| public DCMotor gearbox = DCMotor.getKrakenX60Foc(1); | ||||||
| } | ||||||
160 changes: 160 additions & 0 deletions
160
src/main/java/org/trigon/hardware/subsystems/arm/ArmSubsystem.java
Strflightmight09 marked this conversation as resolved.
Show resolved
Hide resolved
|
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,160 @@ | ||
| package org.trigon.hardware.subsystems.arm; | ||
|
|
||
| import com.ctre.phoenix6.controls.ControlRequest; | ||
| import com.ctre.phoenix6.controls.DynamicMotionMagicVoltage; | ||
| import com.ctre.phoenix6.controls.VoltageOut; | ||
| import edu.wpi.first.math.geometry.*; | ||
| import edu.wpi.first.units.Units; | ||
| import edu.wpi.first.wpilibj.sysid.SysIdRoutineLog; | ||
| import edu.wpi.first.wpilibj2.command.sysid.SysIdRoutine; | ||
| import org.littletonrobotics.junction.Logger; | ||
| import org.trigon.hardware.RobotHardwareStats; | ||
| import org.trigon.hardware.phoenix6.talonfx.TalonFXMotor; | ||
| import org.trigon.hardware.phoenix6.talonfx.TalonFXSignal; | ||
| import org.trigon.hardware.simulation.SingleJointedArmSimulation; | ||
| import org.trigon.utilities.mechanisms.SingleJointedArmMechanism2d; | ||
|
|
||
| public class ArmSubsystem { | ||
| private final TalonFXMotor motor; | ||
| private final Pose3d originPoint; | ||
| private final String name; | ||
| private final double | ||
| maximumVelocity, | ||
| maximumAcceleration, | ||
| maximumJerk, | ||
| visualizationOffsetFromGravityOffset; | ||
| private final Rotation2d angleTolerance; | ||
| private final VoltageOut voltageRequest; | ||
| private final DynamicMotionMagicVoltage positionRequest; | ||
| private final SingleJointedArmMechanism2d mechanism; | ||
| private final SysIdRoutine.Config sysIDConfig; | ||
| private ArmState targetState; | ||
|
|
||
| public ArmSubsystem(TalonFXMotor motor, ArmConfiguration config, Pose3d originPoint) { | ||
| this.motor = motor; | ||
| this.originPoint = originPoint; | ||
|
|
||
| name = config.name; | ||
| maximumVelocity = config.maximumVelocity; | ||
| maximumAcceleration = config.maximumAcceleration; | ||
| maximumJerk = config.maximumJerk; | ||
| angleTolerance = config.angleTolerance; | ||
| visualizationOffsetFromGravityOffset = config.visualizationOffset; | ||
| mechanism = new SingleJointedArmMechanism2d(name + "Mechanism", config.lengthMeters, config.mechanismColor); | ||
| voltageRequest = new VoltageOut(0).withEnableFOC(config.focEnabled); | ||
| positionRequest = new DynamicMotionMagicVoltage(0, maximumVelocity, maximumAcceleration, maximumJerk).withEnableFOC(config.focEnabled); | ||
| sysIDConfig = new SysIdRoutine.Config( | ||
| Units.Volts.of(config.sysIDRampRate).per(Units.Seconds), | ||
| Units.Volts.of(config.sysIDStepVoltage), | ||
| Units.Second.of(1000) | ||
| ); | ||
| motor.setPhysicsSimulation( | ||
| new SingleJointedArmSimulation( | ||
| config.gearbox, | ||
| config.gearRatio, | ||
| config.massKilograms, | ||
| config.lengthMeters, | ||
| config.minimumAngle, | ||
| config.maximumAngle, | ||
| config.shouldSimulateGravity | ||
| )); | ||
| } | ||
|
|
||
| public String getName() { | ||
| return name; | ||
| } | ||
|
|
||
| public SysIdRoutine.Config getSysIdConfig() { | ||
| return sysIDConfig; | ||
| } | ||
|
|
||
| public void setBrake(boolean brake) { | ||
| motor.setBrake(brake); | ||
| } | ||
|
|
||
| public void stop() { | ||
| motor.stopMotor(); | ||
| } | ||
|
|
||
| public void updateLog(SysIdRoutineLog log) { | ||
| log.motor(name) | ||
| .angularPosition(Units.Rotations.of(motor.getSignal(TalonFXSignal.POSITION))) | ||
| .angularVelocity(Units.RotationsPerSecond.of(motor.getSignal(TalonFXSignal.VELOCITY))) | ||
| .voltage(Units.Volts.of(motor.getSignal(TalonFXSignal.MOTOR_VOLTAGE))); | ||
| } | ||
|
|
||
| public void updateMechanism() { | ||
| logComponentPose(); | ||
|
|
||
| mechanism.update( | ||
| getAngle(), | ||
| Rotation2d.fromRotations(motor.getSignal(TalonFXSignal.CLOSED_LOOP_REFERENCE) + (RobotHardwareStats.isSimulation() ? 0 : visualizationOffsetFromGravityOffset)) | ||
| ); | ||
| } | ||
|
|
||
| public void updatePeriodically() { | ||
| motor.update(); | ||
| Logger.recordOutput(name + "/CurrentAngle", getAngle()); | ||
| } | ||
|
|
||
| public void sysIDDrive(double targetVoltage) { | ||
| motor.setControl(voltageRequest.withOutput(targetVoltage)); | ||
| } | ||
|
|
||
| public boolean atState(ArmState targetState) { | ||
| return this.targetState == targetState && atTargetState(); | ||
| } | ||
|
|
||
| public boolean atTargetState() { | ||
| if (targetState == null) | ||
| return false; | ||
| final double currentToTargetStateDifferenceDegrees = Math.abs(targetState.getTargetAngle().minus(getAngle()).getDegrees()); | ||
| return currentToTargetStateDifferenceDegrees < angleTolerance.getDegrees(); | ||
| } | ||
|
|
||
| public Rotation2d getAngle() { | ||
| return Rotation2d.fromRotations(motor.getSignal(TalonFXSignal.POSITION) + (RobotHardwareStats.isSimulation() ? 0 : visualizationOffsetFromGravityOffset)); | ||
| } | ||
|
|
||
| public void setTargetState(ArmState targetState) { | ||
| this.targetState = targetState; | ||
| setTargetState(targetState.getTargetAngle(), targetState.getSpeedScalar()); | ||
| } | ||
|
|
||
| public void setTargetState(Rotation2d targetAngle, double speedScalar) { | ||
| scalePositionRequestSpeed(speedScalar); | ||
| setTargetAngle(targetAngle); | ||
| } | ||
|
|
||
| public void setControl(ControlRequest request) { | ||
| motor.setControl(request); | ||
| } | ||
|
|
||
| private void scalePositionRequestSpeed(double speedScalar) { | ||
| positionRequest.Velocity = maximumVelocity * speedScalar; | ||
| positionRequest.Acceleration = maximumAcceleration * speedScalar; | ||
| positionRequest.Jerk = maximumJerk * speedScalar; | ||
| } | ||
|
|
||
| private void setTargetAngle(Rotation2d targetAngle) { | ||
| setControl(positionRequest.withPosition(targetAngle.getRotations() - (RobotHardwareStats.isSimulation() ? 0 : visualizationOffsetFromGravityOffset))); | ||
| } | ||
|
|
||
| private void logComponentPose() { | ||
| Logger.recordOutput("Poses/Components/" + name + "Pose", calculateComponentPose()); | ||
| } | ||
|
|
||
| private Pose3d calculateComponentPose() { | ||
| final Transform3d armTransform = new Transform3d( | ||
| new Translation3d(), | ||
| new Rotation3d(0, getAngle().getRadians(), 0) | ||
| ); | ||
| return originPoint.transformBy(armTransform); | ||
| } | ||
|
|
||
| public interface ArmState { | ||
| Rotation2d getTargetAngle(); | ||
|
|
||
| double getSpeedScalar(); | ||
| } | ||
| } |
25 changes: 25 additions & 0 deletions
25
src/main/java/org/trigon/hardware/subsystems/elevator/ElevatorConfiguration.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,25 @@ | ||
| package org.trigon.hardware.subsystems.elevator; | ||
|
|
||
| import edu.wpi.first.math.system.plant.DCMotor; | ||
| import edu.wpi.first.wpilibj.util.Color; | ||
|
|
||
| public class ElevatorConfiguration { | ||
| public String name = ""; | ||
| public double | ||
| positionToleranceMeters = 1, | ||
| drumRadiusMeters = 1, | ||
| minimumHeight = 1, | ||
| maximumHeight = 1, | ||
| maximumVelocity = 1, | ||
| maximumAcceleration = 1, | ||
Strflightmight09 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| maximumJerk = 1, | ||
| sysIDRampRate = 1, | ||
| sysIDStepVoltage = 1, | ||
| gearRatio = 1, | ||
| massKilograms = 1; | ||
| public boolean | ||
| focEnabled = true, | ||
| shouldSimulateGravity = true; | ||
| public Color mechanismColor = Color.kBlue; | ||
| public DCMotor gearbox = DCMotor.getKrakenX60Foc(1); | ||
| } | ||
176 changes: 176 additions & 0 deletions
176
src/main/java/org/trigon/hardware/subsystems/elevator/ElevatorSubsystem.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,176 @@ | ||
| package org.trigon.hardware.subsystems.elevator; | ||
|
|
||
| import com.ctre.phoenix6.controls.ControlRequest; | ||
| import com.ctre.phoenix6.controls.DynamicMotionMagicVoltage; | ||
| import com.ctre.phoenix6.controls.VoltageOut; | ||
| import edu.wpi.first.math.geometry.Pose3d; | ||
| import edu.wpi.first.math.geometry.Rotation3d; | ||
| import edu.wpi.first.math.geometry.Transform3d; | ||
| import edu.wpi.first.math.geometry.Translation3d; | ||
| import edu.wpi.first.units.Units; | ||
| import edu.wpi.first.wpilibj.sysid.SysIdRoutineLog; | ||
| import edu.wpi.first.wpilibj2.command.sysid.SysIdRoutine; | ||
| import org.littletonrobotics.junction.Logger; | ||
| import org.trigon.hardware.phoenix6.talonfx.TalonFXMotor; | ||
| import org.trigon.hardware.phoenix6.talonfx.TalonFXSignal; | ||
| import org.trigon.hardware.simulation.ElevatorSimulation; | ||
| import org.trigon.utilities.Conversions; | ||
| import org.trigon.utilities.mechanisms.ElevatorMechanism2d; | ||
|
|
||
| public class ElevatorSubsystem { | ||
Strflightmight09 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| private final TalonFXMotor motor; | ||
| private final Pose3d[] stagesOriginPoints; | ||
| private final String name; | ||
| private final double | ||
| positionToleranceMeters, | ||
| drumRadiusMeters, | ||
| maximumVelocity, | ||
| maximumAcceleration, | ||
| maximumJerk; | ||
| private final VoltageOut voltageRequest; | ||
| private final DynamicMotionMagicVoltage positionRequest; | ||
| private final ElevatorMechanism2d mechanism; | ||
| private final SysIdRoutine.Config sysIDConfig; | ||
| private ElevatorState targetState; | ||
|
|
||
| public ElevatorSubsystem(TalonFXMotor motor, ElevatorConfiguration config, Pose3d... stagesOriginPoints) { | ||
| this.motor = motor; | ||
| this.stagesOriginPoints = stagesOriginPoints; | ||
|
|
||
| name = config.name; | ||
| positionToleranceMeters = config.positionToleranceMeters; | ||
| drumRadiusMeters = config.drumRadiusMeters; | ||
| maximumVelocity = config.maximumVelocity; | ||
| maximumAcceleration = config.maximumAcceleration; | ||
| maximumJerk = config.maximumJerk; | ||
| mechanism = new ElevatorMechanism2d(name + "Mechanism", config.maximumHeight, config.minimumHeight, config.mechanismColor); | ||
| voltageRequest = new VoltageOut(0).withEnableFOC(config.focEnabled); | ||
| positionRequest = new DynamicMotionMagicVoltage(0, maximumVelocity, maximumAcceleration, maximumJerk).withEnableFOC(config.focEnabled); | ||
| sysIDConfig = new SysIdRoutine.Config( | ||
| Units.Volts.of(config.sysIDRampRate).per(Units.Seconds), | ||
| Units.Volts.of(config.sysIDStepVoltage), | ||
| Units.Second.of(1000) | ||
| ); | ||
| motor.setPhysicsSimulation( | ||
| new ElevatorSimulation( | ||
| config.gearbox, | ||
| config.gearRatio, | ||
| config.massKilograms, | ||
| config.drumRadiusMeters, | ||
| config.minimumHeight, | ||
| config.maximumHeight, | ||
| config.shouldSimulateGravity | ||
| )); | ||
| } | ||
|
|
||
| public String getName() { | ||
| return name; | ||
| } | ||
|
|
||
| public SysIdRoutine.Config getSysIdConfig() { | ||
| return sysIDConfig; | ||
| } | ||
|
|
||
| public void setBrake(boolean brake) { | ||
| motor.setBrake(brake); | ||
| } | ||
|
|
||
| public void stop() { | ||
| motor.stopMotor(); | ||
| } | ||
|
|
||
| public void updateLog(SysIdRoutineLog log) { | ||
| log.motor(name) | ||
| .linearPosition(Units.Meters.of(getPositionRotations())) | ||
| .linearVelocity(Units.MetersPerSecond.of(motor.getSignal(TalonFXSignal.VELOCITY))) | ||
| .voltage(Units.Volts.of(motor.getSignal(TalonFXSignal.MOTOR_VOLTAGE))); | ||
| } | ||
|
|
||
| public void updateMechanism() { | ||
| logComponentPoses(); | ||
|
|
||
| mechanism.update( | ||
| getPositionRotations(), | ||
| motor.getSignal(TalonFXSignal.CLOSED_LOOP_REFERENCE) | ||
| ); | ||
| } | ||
|
|
||
| public void updatePeriodically() { | ||
| motor.update(); | ||
| Logger.recordOutput(name + "/CurrentPositionMeters", getPositionMeters()); | ||
| } | ||
|
|
||
| public void sysIDDrive(double targetVoltage) { | ||
| motor.setControl(voltageRequest.withOutput(targetVoltage)); | ||
| } | ||
|
|
||
| public boolean atState(ElevatorState targetState) { | ||
| return this.targetState == targetState && atTargetState(); | ||
| } | ||
|
|
||
| public boolean atTargetState() { | ||
| if (targetState == null) | ||
| return false; | ||
| final double currentToTargetStateDifference = Math.abs(targetState.getTargetPositionMeters() - getPositionMeters()); | ||
| return currentToTargetStateDifference < positionToleranceMeters; | ||
| } | ||
|
|
||
| public double getPositionRotations() { | ||
| return motor.getSignal(TalonFXSignal.POSITION); | ||
| } | ||
|
|
||
| public double getPositionMeters() { | ||
| return rotationsToMeters(getPositionRotations()); | ||
| } | ||
|
|
||
| public void setTargetState(ElevatorState targetState) { | ||
| this.targetState = targetState; | ||
| setTargetState(targetState.getTargetPositionMeters(), targetState.getSpeedScalar()); | ||
| } | ||
|
|
||
| public void setTargetState(double targetPositionMeters, double speedScalar) { | ||
| scalePositionRequestSpeed(speedScalar); | ||
| setTargetPositionRotations(metersToRotations(targetPositionMeters)); | ||
| } | ||
|
|
||
| public void setControl(ControlRequest request) { | ||
| motor.setControl(request); | ||
| } | ||
|
|
||
| private void scalePositionRequestSpeed(double speedScalar) { | ||
| positionRequest.Velocity = maximumVelocity * speedScalar; | ||
| positionRequest.Acceleration = maximumAcceleration * speedScalar; | ||
| positionRequest.Jerk = maximumJerk * speedScalar; | ||
| } | ||
|
|
||
| private void setTargetPositionRotations(double targetPositionRotations) { | ||
| setControl(positionRequest.withPosition(targetPositionRotations)); | ||
| } | ||
|
|
||
| private void logComponentPoses() { | ||
| for (int i = 0; i < stagesOriginPoints.length; i++) | ||
| Logger.recordOutput("Poses/Components/" + name + "Pose" + i, calculateComponentPose(i)); | ||
| } | ||
|
|
||
| private Pose3d calculateComponentPose(int targetStage) { | ||
| final Transform3d elevatorTransform = new Transform3d( | ||
| new Translation3d(0, 0, getPositionMeters() / (targetStage + 1)), | ||
| new Rotation3d() | ||
| ); | ||
| return stagesOriginPoints[targetStage].transformBy(elevatorTransform); | ||
| } | ||
|
|
||
| private double rotationsToMeters(double positionRotations) { | ||
| return Conversions.rotationsToDistance(positionRotations, drumRadiusMeters * 2); | ||
| } | ||
|
|
||
| private double metersToRotations(double positionMeters) { | ||
| return Conversions.distanceToRotations(positionMeters, drumRadiusMeters * 2); | ||
| } | ||
|
|
||
| public interface ElevatorState { | ||
ShmayaR marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| double getTargetPositionMeters(); | ||
|
|
||
| double getSpeedScalar(); | ||
| } | ||
| } | ||
Oops, something went wrong.
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.