Apply shooter tuner changes stash

Show selected path
This commit is contained in:
nathanrsxtn
2022-04-08 11:35:19 -06:00
parent 0812135d6a
commit a07bbfbbae
6 changed files with 120 additions and 48 deletions
@@ -169,6 +169,7 @@ public class PathRecorder extends CommandBase {
if (pathName != null) {
LOGGER.log(Level.WARNING, "Loading path {0}.", pathName);
loadedPathTrajectory = PathPlanner.loadPath(PATH_EXTENSION_REMOVER.apply(pathName), SwerveDriveConstants.PATH_MAX_VELOCITY, SwerveDriveConstants.PATH_MAX_ACCELERATION);
m_swerveDrive.m_field.getObject("traj").setTrajectory(loadedPathTrajectory);
LOGGER.info("Done loading.");
} else {
LOGGER.severe("No path to load.");
@@ -21,6 +21,7 @@ import edu.wpi.first.wpilibj.shuffleboard.BuiltInLayouts;
import edu.wpi.first.wpilibj.shuffleboard.Shuffleboard;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
import edu.wpi.first.wpilibj2.command.CommandBase;
import edu.wpi.first.wpilibj2.command.InstantCommand;
import frc4388.robot.subsystems.BoomBoom;
import frc4388.robot.subsystems.BoomBoom.ShooterTableEntry;
import frc4388.utility.shuffleboard.SendableTable;
@@ -41,7 +42,7 @@ public class ShooterTuner extends CommandBase {
m_shotEditor = new ShotEditor();
m_shotCsvAppender = new CSVAppender();
tableOverrideEntry = new ShooterTableEntry();
m_tableEditor = new SendableTable(() -> m_boomBoom.m_shooterTable);
m_tableEditor = new SendableTable(m_boomBoom::getShooterTable, m_boomBoom::setShooterTable);
setName("Shooter Data Mode");
}
@@ -54,12 +55,18 @@ public class ShooterTuner extends CommandBase {
manual.add("Manual Data Appender", m_shotCsvAppender);
var csv = tab.getLayout("Shooter Table", BuiltInLayouts.kList).withPosition(2, 0).withSize(7, 5);
csv.add("Shooter Table", m_tableEditor);
csv.add("Shooter Tuner State", this);
csv.add("Save to CSV File", new InstantCommand(m_boomBoom::saveShooterTable) {
@Override
public boolean runsWhenDisabled() {
return true;
}
});
csv.add("Shooter Tuner State (Disable to Reload)", this);
}
tableOverrideEntry.distance = 0.0;
tableOverrideEntry.hoodExt = 0.0;
tableOverrideEntry.drumVelocity = 0.0;
m_boomBoom.m_shooterTable = new ShooterTableEntry[] { tableOverrideEntry };
m_boomBoom.setShooterTable(new ShooterTableEntry[] { tableOverrideEntry });
Shuffleboard.selectTab("Shooter Tuner");
SmartDashboard.putData("Shooter Table", m_tableEditor);
}
@@ -72,7 +79,7 @@ public class ShooterTuner extends CommandBase {
public void end(boolean interrupted) {
m_boomBoom.loadShooterTable();
LOGGER.info(Errors.log().wrapWithDefault(() -> Files.readString(PATH), "Failed to read CSV"));
ShuffleboardHelper.purgeShuffleboardTab("Shooter Tuner");
// ShuffleboardHelper.purgeShuffleboardTab("Shooter Tuner");
}
@Override
public final boolean isFinished() {
@@ -6,6 +6,8 @@ package frc4388.robot.subsystems;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Map;
@@ -20,6 +22,7 @@ import java.util.stream.IntStream;
import com.ctre.phoenix.motorcontrol.TalonFXControlMode;
import com.ctre.phoenix.motorcontrol.can.WPI_TalonFX;
import com.diffplug.common.base.Errors;
import com.diffplug.common.base.StringPrinter;
import edu.wpi.first.util.sendable.Sendable;
import edu.wpi.first.wpilibj.Filesystem;
@@ -55,7 +58,14 @@ public class BoomBoom extends SubsystemBase {
public Double distance, hoodExt, drumVelocity;
}
public ShooterTableEntry[] m_shooterTable;
private ShooterTableEntry[] m_shooterTable;
public ShooterTableEntry[] getShooterTable() {
return m_shooterTable;
}
public void setShooterTable(ShooterTableEntry[] shooterTable) {
m_shooterTable = shooterTable;
}
/** Creates a new BoomBoom, which has a drum shooter and angle adjuster. */
public BoomBoom(WPI_TalonFX shooterFalconLeft, WPI_TalonFX shooterFalconRight) {
@@ -140,30 +150,31 @@ public class BoomBoom extends SubsystemBase {
// m_shooterFalconLeft.set(m_controller.calculate(m_shooterFalconLeft.get(), targetVel));
}
// This is a helper class that allows us to read a CSV file into a Java array.
private CSV<ShooterTableEntry> m_csv = new CSV<>(ShooterTableEntry::new) {
// This is a regular expression that removes all parentheses from the header of the CSV file.
private final Pattern parentheses = Pattern.compile("\\([^\\)]*+\\)");
/**
* Removes the parentheses from the CSV header
*
* @param header The header to be sanitized.
* @return The headerSanitizer method is overriding the headerSanitizer method in the parent class.
* The parentheses.matcher(header) is matching the header with the parentheses regular
* expression. The replaceAll method is replacing all of the parentheses with an empty
* string. The super.headerSanitizer(parentheses.matcher(header).replaceAll("")) is calling
* the parent sanitizer.
*/
@Override
protected String headerSanitizer(String header) {
return super.headerSanitizer(parentheses.matcher(header).replaceAll(""));
}
};
public void loadShooterTable() {
try {
// This is a helper class that allows us to read a CSV file into a Java array.
CSV<ShooterTableEntry> csv = new CSV<>(ShooterTableEntry::new) {
// This is a regular expression that removes all parentheses from the header of the CSV file.
private final Pattern parentheses = Pattern.compile("\\([^\\)]*+\\)");
/**
* Removes the parentheses from the CSV header
*
* @param header The header to be sanitized.
* @return The headerSanitizer method is overriding the headerSanitizer method in the parent class.
* The parentheses.matcher(header) is matching the header with the parentheses regular
* expression. The replaceAll method is replacing all of the parentheses with an empty
* string. The super.headerSanitizer(parentheses.matcher(header).replaceAll("")) is calling
* the parent sanitizer.
*/
@Override
protected String headerSanitizer(String header) {
return super.headerSanitizer(parentheses.matcher(header).replaceAll(""));
}
};
// This is reading the CSV file into a Java array.
m_shooterTable = Arrays.stream(csv.read(new File(Filesystem.getDeployDirectory(), "ShooterData.csv").toPath())).sorted(Comparator.comparingDouble(e -> e.distance)).toArray(ShooterTableEntry[]::new);
m_shooterTable = Arrays.stream(m_csv.read(new File(Filesystem.getDeployDirectory(), "ShooterData.csv").toPath())).sorted(Comparator.comparingDouble(e -> e.distance)).toArray(ShooterTableEntry[]::new);
} catch (IOException exception) {
ShooterTableEntry dummyEntry = new ShooterTableEntry();
dummyEntry.distance = 0.0;
@@ -174,6 +185,14 @@ public class BoomBoom extends SubsystemBase {
}
}
public void saveShooterTable() {
StringPrinter sp = new StringPrinter(Errors.log().wrap(s -> {
Files.writeString(new File(Filesystem.getDeployDirectory(), "ShooterData.csv").toPath(), s);
System.err.println(s);
}));
Errors.log().run(() -> m_csv.write(sp.toWriter(), "Distance (in) ,Hood Ext. (u) ,Drum Velocity (u/ds)", m_shooterTable, true));
}
public void updateOffset(double change) {
pidOffset = pidOffset + change;
}
@@ -54,7 +54,7 @@ public class SwerveDrive extends SubsystemBase {
public Rotation2d rotTarget = new Rotation2d();
private ChassisSpeeds chassisSpeeds = new ChassisSpeeds();
private final Field2d m_field = new Field2d();
public final Field2d m_field = new Field2d();
public SwerveDrive(SwerveModule leftFront, SwerveModule leftBack, SwerveModule rightFront, SwerveModule rightBack,
WPI_Pigeon2 gyro) {