-
Notifications
You must be signed in to change notification settings - Fork 9
Gains tuning utility class #217
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
base: main
Are you sure you want to change the base?
Changes from 5 commits
e81a82a
bbca421
d4094ab
cdc5d0b
be1cd96
3d34a60
887710a
208b36e
2719a3c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,7 @@ | |
| import static edu.wpi.first.units.Units.Seconds; | ||
| import static edu.wpi.first.units.Units.Volts; | ||
|
|
||
| import com.ctre.phoenix6.configs.Slot0Configs; | ||
| import com.ctre.phoenix6.configs.TalonFXConfiguration; | ||
| import com.ctre.phoenix6.configs.TalonFXConfigurator; | ||
| import com.ctre.phoenix6.controls.MotionMagicVoltage; | ||
|
|
@@ -28,6 +29,7 @@ | |
| import edu.wpi.first.wpilibj2.command.sysid.SysIdRoutine; | ||
| import edu.wpi.first.wpilibj2.command.sysid.SysIdRoutine.Direction; | ||
| import frc.robot.Hardware; | ||
| import frc.robot.util.GainsTuningEntry; | ||
| import java.util.function.Supplier; | ||
|
|
||
| public class ArmPivot extends SubsystemBase { | ||
|
|
@@ -75,6 +77,19 @@ public class ArmPivot extends SubsystemBase { | |
| // TalonFX | ||
| private final TalonFX motor; | ||
|
|
||
| // Testing tuning entry :P | ||
| private final boolean TUNING_ENABLED = false; | ||
| private final GainsTuningEntry PIDtuner = | ||
| new GainsTuningEntry( | ||
| "ArmPivot", | ||
| ARMPIVOT_KP, | ||
| ARMPIVOT_KI, | ||
| ARMPIVOT_KD, | ||
| ARMPIVOT_KA, | ||
| ARMPIVOT_KV, | ||
| ARMPIVOT_KS, | ||
| ARMPIVOT_KG); | ||
|
|
||
| // alerts if motor is not connected. | ||
| private final Alert NotConnectedError = | ||
| new Alert("ArmPivot", "Motor not connected", AlertType.kError); | ||
|
|
@@ -227,6 +242,17 @@ public void factoryDefaults() { | |
| public void periodic() { | ||
| // Error that ensures the motor is connected | ||
| NotConnectedError.set(notConnectedDebouncer.calculate(!motor.getMotorVoltage().hasUpdated())); | ||
| if (TUNING_ENABLED) { | ||
| Slot0Configs pidTunerConfigs = new Slot0Configs(); | ||
| pidTunerConfigs.kP = PIDtuner.getP(); | ||
| pidTunerConfigs.kI = PIDtuner.getI(); | ||
| pidTunerConfigs.kD = PIDtuner.getD(); | ||
| pidTunerConfigs.kS = PIDtuner.getS(); | ||
| pidTunerConfigs.kV = PIDtuner.getV(); | ||
| pidTunerConfigs.kA = PIDtuner.getA(); | ||
| pidTunerConfigs.kG = PIDtuner.getG(); | ||
| motor.getConfigurator().apply(pidTunerConfigs); | ||
|
iamawesomecat marked this conversation as resolved.
Contributor
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. It might be better to just store the configurator object locally, so that you don't have to retrieve it every time through this loop. Because this loop is periodic, it can happen often, so you want to optimize for fast run-time. |
||
| } | ||
| } | ||
| } | ||
| // -Samuel "Big North" Mallick | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,122 @@ | ||
| package frc.robot.util; | ||
|
|
||
| import edu.wpi.first.networktables.NetworkTable; | ||
| import edu.wpi.first.networktables.NetworkTableEntry; | ||
| import edu.wpi.first.networktables.NetworkTableInstance; | ||
|
|
||
| public class GainsTuningEntry { | ||
|
|
||
| private final NetworkTable table; | ||
| private String kSubsystemName; | ||
| private NetworkTableEntry kPEntry; | ||
| private NetworkTableEntry kIEntry; | ||
| private NetworkTableEntry kDEntry; | ||
| private NetworkTableEntry kAEntry; | ||
| private NetworkTableEntry kVEntry; | ||
| private NetworkTableEntry kSEntry; | ||
| private NetworkTableEntry kGEntry; | ||
|
iamawesomecat marked this conversation as resolved.
iamawesomecat marked this conversation as resolved.
|
||
| public boolean updated = true; | ||
|
|
||
| /* Base PID Feedback entires. Excludes kA, kV, kS, and kG | ||
| * | ||
| */ | ||
|
iamawesomecat marked this conversation as resolved.
Outdated
|
||
| public GainsTuningEntry(String subsystemName, double kp, double ki, double kd) { | ||
| table = NetworkTableInstance.getDefault().getTable("Gains/" + subsystemName); | ||
| this.kSubsystemName = subsystemName; | ||
|
Contributor
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. Is there any validation you need to do on any of these parameters? e.g. null or empty subsystemName, negative or null values? What assumptions are you making about the data that need to be confirmed? |
||
| kPEntry = table.getEntry("kP"); | ||
| kIEntry = table.getEntry("kI"); | ||
| kDEntry = table.getEntry("kD"); | ||
| kAEntry = null; | ||
| kVEntry = null; | ||
| kSEntry = null; | ||
| kGEntry = null; | ||
| kPEntry.setDouble(kp); | ||
| kIEntry.setDouble(ki); | ||
| kDEntry.setDouble(kd); | ||
| } | ||
|
|
||
| /* With ALL Feedback + Feedforward entries, INCLUDING kA | ||
| * | ||
| */ | ||
| public GainsTuningEntry( | ||
| String subsystemName, | ||
| double kp, | ||
| double ki, | ||
| double kd, | ||
| double ka, | ||
| double kv, | ||
| double ks, | ||
| double kg) { | ||
| this(subsystemName, kp, ki, kd); | ||
| kAEntry = table.getEntry("kA"); | ||
| kVEntry = table.getEntry("kV"); | ||
| kSEntry = table.getEntry("kS"); | ||
| kGEntry = table.getEntry("kG"); | ||
| kAEntry.setDouble(ka); | ||
| kVEntry.setDouble(kv); | ||
| kSEntry.setDouble(ks); | ||
| kGEntry.setDouble(kg); | ||
| } | ||
|
|
||
| /* With Feedback + Feedforward entries, except kA | ||
| * | ||
| */ | ||
| public GainsTuningEntry( | ||
| String subsystemName, double kp, double ki, double kd, double kv, double ks, double kg) { | ||
| this(subsystemName, kp, ki, kd); | ||
| kVEntry = table.getEntry("kV"); | ||
| kSEntry = table.getEntry("kS"); | ||
| kGEntry = table.getEntry("kG"); | ||
| kVEntry.setDouble(kv); | ||
| kSEntry.setDouble(ks); | ||
| kGEntry.setDouble(kg); | ||
| } | ||
|
|
||
| public String getSubsystem() { | ||
| return kSubsystemName; | ||
| } | ||
|
|
||
| public double getP() { | ||
| return kPEntry.getDouble(0); | ||
| } | ||
|
|
||
| public double getI() { | ||
| return kIEntry.getDouble(0); | ||
| } | ||
|
|
||
| public double getD() { | ||
| return kDEntry.getDouble(0); | ||
| } | ||
|
|
||
| public double getA() { | ||
| if (kAEntry == null) { | ||
| return 0; | ||
| } else { | ||
| return kAEntry.getDouble(0); | ||
| } | ||
|
iamawesomecat marked this conversation as resolved.
Outdated
|
||
| } | ||
|
iamawesomecat marked this conversation as resolved.
|
||
|
|
||
| public double getV() { | ||
| if (kVEntry == null) { | ||
| return 0; | ||
| } else { | ||
| return kVEntry.getDouble(0); | ||
| } | ||
| } | ||
|
|
||
| public double getS() { | ||
| if (kSEntry == null) { | ||
| return 0; | ||
| } else { | ||
| return kSEntry.getDouble(0); | ||
| } | ||
| } | ||
|
|
||
| public double getG() { | ||
| if (kGEntry == null) { | ||
| return 0; | ||
| } else { | ||
| return kGEntry.getDouble(0); | ||
| } | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.