Skip to content

Commit

Permalink
load on select
Browse files Browse the repository at this point in the history
Signed-off-by: Jade Turner <spacey-sooty@proton.me>
  • Loading branch information
spacey-sooty committed Dec 4, 2024
1 parent c02cec6 commit 781fa0b
Show file tree
Hide file tree
Showing 6 changed files with 352 additions and 39 deletions.
166 changes: 166 additions & 0 deletions src/main/deploy/choreo/TestPath.traj

Large diffs are not rendered by default.

49 changes: 20 additions & 29 deletions src/main/java/frc/robot/Robot.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import edu.wpi.first.networktables.NetworkTableInstance;
import edu.wpi.first.wpilibj.DriverStation;
import edu.wpi.first.wpilibj.DriverStation.Alliance;
import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.CommandScheduler;
import edu.wpi.first.wpilibj2.command.Commands;
import edu.wpi.first.wpilibj2.command.button.CommandXboxController;
Expand All @@ -33,20 +32,16 @@
import frc.robot.subsystems.drive.Drive;
import frc.robot.subsystems.drive.DriveIO;
import frc.robot.subsystems.drive.DriveIOCTRE;
import frc.robot.subsystems.shooter.Shooter;
import frc.robot.subsystems.shooter.ShooterIO;
import frc.robot.subsystems.shooter.ShooterIOSim;
import frc.robot.subsystems.vision.VisionIO;
import frc.robot.subsystems.vision.VisionIOLimelight;
import frc.robot.subsystems.vision.VisionIOSim;
import frc.robot.subsystems.vision.VisionSource;
import frc.robot.util.AutoChooser;
import java.io.File;
import java.util.Set;
import java.util.function.Supplier;
import org.littletonrobotics.junction.LogFileUtil;
import org.littletonrobotics.junction.LoggedRobot;
import org.littletonrobotics.junction.Logger;
import org.littletonrobotics.junction.networktables.LoggedDashboardChooser;
import org.littletonrobotics.junction.networktables.NT4Publisher;
import org.littletonrobotics.junction.wpilog.WPILOGReader;
import org.littletonrobotics.junction.wpilog.WPILOGWriter;
Expand All @@ -62,7 +57,6 @@ public class Robot extends LoggedRobot {
private final CommandXboxController driver = new CommandXboxController(0);

private final Drive drive;
private final Shooter shooter;
private final VisionSource limelight_back;
private final VisionSource limelight_front;

Expand All @@ -71,8 +65,7 @@ public class Robot extends LoggedRobot {
.withDriveRequestType(
DriveRequestType.Velocity); // Use closed-loop control for drive motors

private final LoggedDashboardChooser<Supplier<Command>> autoChooser =
new LoggedDashboardChooser<>("Autos");
private final AutoChooser autoChooser;
private final AutoFactory autoFactory;

public Robot() {
Expand Down Expand Up @@ -120,8 +113,6 @@ public Robot() {

limelight_back = new VisionSource(new VisionIOLimelight("limelight-back"));
limelight_front = new VisionSource(new VisionIOLimelight("limelight-front"));
shooter =
new Shooter(new ShooterIO() {}); // no op since we dont have a shooter on the real robot
break;

case SIM:
Expand All @@ -140,7 +131,6 @@ public Robot() {

limelight_back = new VisionSource(new VisionIOSim("limelight-back"));
limelight_front = new VisionSource(new VisionIOSim("limelight-front"));
shooter = new Shooter(new ShooterIOSim());
break;

// in replay
Expand All @@ -155,7 +145,6 @@ public Robot() {
drive = new Drive(new DriveIO() {});
limelight_back = new VisionSource(new VisionIO() {});
limelight_front = new VisionSource(new VisionIO() {});
shooter = new Shooter(new ShooterIO() {});
break;
}

Expand Down Expand Up @@ -206,7 +195,6 @@ public Robot() {
drive
.moveToPosition(new Pose2d(2, 5.6, new Rotation2d()))
.until(drive::isTeleopAtSetpoint));
driver.b().whileTrue(shooter.maintain(500));

// Run SysId routines when holding back/start and X/Y.
// Note that each routine should be run exactly once in a single log.
Expand All @@ -223,11 +211,13 @@ public Robot() {
() -> DriverStation.getAlliance().orElse(Alliance.Blue) == Alliance.Red,
new AutoFactory.AutoBindings());

autoChooser = new AutoChooser(autoFactory, "AutoChooser");

autoChooser.addOption(
"Simple Path",
() -> {
final AutoLoop routine = autoFactory.newLoop("simple");
final AutoTrajectory path = autoFactory.trajectory("SimplePath", routine);
(factory) -> {
final AutoLoop routine = factory.newLoop("simple");
final AutoTrajectory path = factory.trajectory("SimplePath", routine);

routine
.enabled()
Expand All @@ -244,9 +234,9 @@ public Robot() {

autoChooser.addOption(
"Bad Idea TM",
() -> {
final AutoLoop routine = autoFactory.newLoop("jadesadumbass");
final AutoTrajectory path = autoFactory.trajectory("VeryBadIdeaTm", routine);
(factory) -> {
final AutoLoop routine = factory.newLoop("jadesadumbass");
final AutoTrajectory path = factory.trajectory("VeryBadIdeaTm", routine);

routine
.enabled()
Expand All @@ -263,9 +253,9 @@ public Robot() {

autoChooser.addOption(
"Move To Side",
() -> {
final AutoLoop routine = autoFactory.newLoop("side");
final AutoTrajectory path = autoFactory.trajectory("MoveToSide", routine);
(factory) -> {
final AutoLoop routine = factory.newLoop("side");
final AutoTrajectory path = factory.trajectory("MoveToSide", routine);

routine
.enabled()
Expand All @@ -282,9 +272,9 @@ public Robot() {

autoChooser.addOption(
"Test Path",
() -> {
final AutoLoop routine = autoFactory.newLoop("test");
final AutoTrajectory path = autoFactory.trajectory("TestPath", routine);
(factory) -> {
final AutoLoop routine = factory.newLoop("test");
final AutoTrajectory path = factory.trajectory("TestPath", routine);

routine
.enabled()
Expand All @@ -299,19 +289,20 @@ public Robot() {
return routine.cmd();
});

autoChooser.addDefaultOption(
autoChooser.addOption(
"Set Pose to Vision Pose",
() -> {
(factory) -> {
return Commands.runOnce(
() -> drive.resetPose(limelight_back.getPose().toPose2d()), drive);
});

autonomous().whileTrue(Commands.defer(() -> autoChooser.get().get().asProxy(), Set.of()));
autonomous().whileTrue(Commands.defer(() -> autoChooser.getSelected().asProxy(), Set.of()));
}

@Override
public void robotPeriodic() {
CommandScheduler.getInstance().run();
autoChooser.periodic();

if (limelight_back.inField()) {
drive.addVisionMeasurement(
Expand Down
10 changes: 5 additions & 5 deletions src/main/java/frc/robot/generated/BuildConstants.java

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,22 @@ public VisionIOLimelight(String camera) {

@Override
public void updateInputs(VisionIOInputs inputs) {
inputs.camera = camera;
inputs.cameraOffset = cameraOffset;
inputs.timestamp = Util.now().in(Milliseconds);
inputs.validIds = validIds;

var pose = botpose.get();
if (pose != null && pose.length != 0) {
var rotation =
new Rotation3d(
degreesToRadians(pose[3]), degreesToRadians(pose[4]), degreesToRadians(pose[5]));
inputs.estimatedPose = new Pose3d(pose[0], pose[1], pose[2], rotation);
inputs.timestamp = Util.now().in(Milliseconds);
inputs.latency = pose[6];
inputs.tagCount = pose[7];
inputs.inField = Util.inField(inputs.estimatedPose);
inputs.camera = camera;
inputs.validIds = validIds;
inputs.averageTagDistance = pose[9];
inputs.averageTagArea = pose[10];
inputs.cameraOffset = cameraOffset;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public Matrix<N3, N1> getStdDevs() {
if (inputs.tagCount <= 0) {
return VecBuilder.fill(9999999, 9999999, 9999999);
}
return VecBuilder.fill(0.7, 0.7, 9999999);
return VecBuilder.fill(0.15, 0.15, 9999999);
}

public void setCameraOffset(Transform3d translation) {
Expand Down
155 changes: 155 additions & 0 deletions src/main/java/frc/robot/util/AutoChooser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
package frc.robot.util;

import choreo.auto.AutoFactory;
import edu.wpi.first.networktables.NetworkTable;
import edu.wpi.first.networktables.NetworkTableInstance;
import edu.wpi.first.networktables.StringArrayEntry;
import edu.wpi.first.networktables.StringEntry;
import edu.wpi.first.wpilibj.DriverStation;
import edu.wpi.first.wpilibj.IterativeRobotBase;
import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.Commands;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import org.littletonrobotics.junction.LogTable;
import org.littletonrobotics.junction.Logger;
import org.littletonrobotics.junction.inputs.LoggableInputs;
import org.littletonrobotics.junction.networktables.LoggedDashboardInput;

/**
* An auto chooser that allows for the selection of auto routines at runtime.
*
* <p>This chooser takes a lazy loading approach to auto routines, only generating the auto routine
* when it is selected. This approach has the benefit of not loading all autos on startup, but also
* not loading the auto during auto start causing a delay.
*
* <p>Once the {@link AutoChooser} is made you can add auto routines to it using the {@link
* #addAutoRoutine(String, AutoRoutineGenerator)} method. Unlike {@code SendableChooser} this
* chooser has to be updated every cycle by calling the {@link #update()} method in your {@link
* IterativeRobotBase#robotPeriodic()}.
*
* <p>You can retrieve the auto routine {@link Command} that is currently selected by calling the
* {@link #getSelectedAutoRoutine()} method.
*/
public class AutoChooser implements LoggedDashboardInput {
/** A function that generates an auto routine {@link Command} from an {@link AutoFactory}. */
public static interface AutoRoutineGenerator extends Function<AutoFactory, Command> {
/** A generator that returns a command that does nothing */
static final AutoRoutineGenerator NONE = factory -> Commands.none().withName("Do Nothing Auto");
}

private static final String NONE_NAME = "Nothing";
private String selectedValue;

private final HashMap<String, AutoRoutineGenerator> autoRoutines =
new HashMap<>(Map.of(NONE_NAME, AutoRoutineGenerator.NONE));

private final StringEntry selected, active;
private final StringArrayEntry options;

private final AutoFactory factory;
private final String path;

private final LoggableInputs inputs =
new LoggableInputs() {
public void toLog(LogTable table) {
table.put(path, selectedValue);
}

public void fromLog(LogTable table) {
selectedValue = table.get(path, selectedValue);
}
};

private String lastAutoRoutineName = NONE_NAME;
private Command lastAutoRoutine = AutoRoutineGenerator.NONE.apply(null);

/**
* Create a new auto chooser.
*
* @param factory The auto factory to use for auto routine generation.
* @param tableName The name of the network table to use for the chooser, passing in an empty
* string will put this chooser at the root of the network tables.
*/
public AutoChooser(AutoFactory factory, String tableName) {
this.factory = factory;

path = NetworkTable.normalizeKey(tableName, true) + "/AutoChooser";
NetworkTable table = NetworkTableInstance.getDefault().getTable(path);

selected = table.getStringTopic("selected").getEntry(NONE_NAME);
table.getStringTopic(".type").publish().set("String Chooser");
table.getStringTopic("default").publish().set(NONE_NAME);
active = table.getStringTopic("active").getEntry(NONE_NAME);
options =
table.getStringArrayTopic("options").getEntry(autoRoutines.keySet().toArray(new String[0]));
}

/**
* Update the auto chooser.
*
* <p>This method should be called every cycle in the {@link IterativeRobotBase#robotPeriodic()}.
* It will check if the selected auto routine has changed and update the active auto routine.
*/
public void update() {
if (DriverStation.isDisabled() || IterativeRobotBase.isSimulation()) {
String selectStr = selected.get();
if (selectStr.equals(lastAutoRoutineName)) return;
if (!autoRoutines.containsKey(selectStr)) {
selected.set(NONE_NAME);
selectStr = NONE_NAME;
DriverStation.reportError("Selected an auto that isn't an option", false);
}
lastAutoRoutineName = selectStr;
lastAutoRoutine = autoRoutines.get(lastAutoRoutineName).apply(this.factory);
active.set(lastAutoRoutineName);
}
}

/**
* Add an auto routine to the chooser.
*
* <p>An auto routine is a function that takes an AutoFactory and returns a Command. These
* functions can be static, a lambda or belong to a local variable.
*
* <p>A good paradigm is making an `AutoRoutines` class that has a reference to all your
* subsystems and has helper methods for auto commands inside it. Then you crate methods inside
* that class that take an `AutoFactory` and return a `Command`.
*
* @param name The name of the auto routine.
* @param generator The function that generates the auto routine.
*/
public void addOption(String name, AutoRoutineGenerator generator) {
autoRoutines.put(name, generator);
options.set(autoRoutines.keySet().toArray(new String[0]));
}

@Override
public void periodic() {
update();
if (!Logger.hasReplaySource()) {
selectedValue = selected.get();
}
Logger.processInputs(prefix + path, inputs);
}

/**
* Choose an auto routine by name.
*
* @param choice The name of the auto routine to choose.
*/
public void choose(String choice) {
selected.set(choice);
update();
}

/**
* Get the currently selected auto routine.
*
* @return The currently selected auto routine.
*/
public Command getSelected() {
return lastAutoRoutine;
}
}

0 comments on commit 781fa0b

Please sign in to comment.