Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
e1c32d1
Add 3d turret implementation
therekrab Jan 30, 2026
dcb1812
I think the system works for pitch-constrained SOTM?
therekrab Jan 31, 2026
3e12672
Maybe works, but for real?
therekrab Feb 3, 2026
f8c7a98
Merge branch 'main' into turret3d
therekrab Feb 3, 2026
8d187bb
Add some more fixes, implement constraints everywhere.
therekrab Feb 5, 2026
025d802
Enable feeding
therekrab Feb 7, 2026
e0e8d22
Merge branch 'shooter' into turret3d
therekrab Feb 8, 2026
0d9a590
Oops I almost broke logging
therekrab Feb 8, 2026
25d1955
Add turret testing
therekrab Feb 8, 2026
c89a586
Forward changes from the shooter branch to turret3d
therekrab Feb 9, 2026
9b99b93
Add more loggig for turret & shooter status
therekrab Feb 9, 2026
9201315
Math.clamp() wasn't added until java >17
therekrab Feb 11, 2026
870f194
Add turret angle snapping
therekrab Feb 12, 2026
262068d
Add initial support for non-linear velocity parameters for speed control
therekrab Feb 12, 2026
c9d0057
ToF recursion works now?
therekrab Feb 12, 2026
9ec5c67
Make fixes
therekrab Feb 12, 2026
cccd05a
Un-disable drag for simulation
therekrab Feb 12, 2026
7cbae20
Fix bug
therekrab Feb 12, 2026
cfe69db
Make some changes that don't really do anything
therekrab Feb 13, 2026
4dc3cab
Remove withSpeedControl() method
therekrab Feb 13, 2026
9d0e84a
lazy load aim params
therekrab Feb 13, 2026
25bf9c0
Add aim prediction to make sotm faster
therekrab Feb 14, 2026
1861283
Improve
therekrab Feb 14, 2026
c60f779
Merge with main
therekrab Feb 14, 2026
5b6d82f
Merge branch 'main' into turret3d
therekrab Feb 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion CompBot/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ configurations {
// Defining my dependencies. In this case, WPILib (+ friends), and vendor libraries.
// Also defines JUnit 5.
dependencies {
implementation 'org.apache.commons:commons-math3:3.6.1'
annotationProcessor wpi.java.deps.wpilibAnnotations()
implementation wpi.java.deps.wpilib()
implementation wpi.java.vendor.java()
Expand Down
22 changes: 21 additions & 1 deletion CompBot/src/main/java/frc/robot/Constants.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,36 @@
package frc.robot;

import static edu.wpi.first.units.Units.Inches;
import static edu.wpi.first.units.Units.Meters;
import edu.wpi.first.math.geometry.Pose3d;
import edu.wpi.first.math.geometry.Rotation2d;
import edu.wpi.first.math.geometry.Rotation3d;
import edu.wpi.first.units.measure.Distance;
import frc.robot.aiming.AimConstraints;
import frc.robot.aiming.AimStrategy;
import frc.robot.aiming.PhysicsAim;

public class Constants {
// Checked the FIRST Game Manual and fixed the field dimensions.
public static class FieldConstants {
/** The longer side, corresponds to X values */
public static final Distance kFieldLength = Meters.of(16.541);
/** The shorter side, corresponds to Y values */
public static final Distance kFieldWidth = Meters.of(8.069);

/** The length of the alliance zone, corresponds to X axis */
public static final Distance kAllianceZoneLength = Inches.of(182.11);

public static final Pose3d kBlueHub = new Pose3d(4.632516, 4.011139, 1.83, Rotation3d.kZero);
public static final Pose3d kFeedTarget = new Pose3d(4.5, 2, 1.0, Rotation3d.kZero);
}

public static class AimConstants {
public static final AimStrategy kAim = new PhysicsAim(
new AimConstraints(
Rotation2d.fromDegrees(49.5), // Min pitch
Rotation2d.fromDegrees(72.0), // Max pitch
18), // Max output (speed)
2,
10);
}
}
2 changes: 1 addition & 1 deletion CompBot/src/main/java/frc/robot/Robot.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ public Robot() {
public void robotPeriodic() {
FieldManager.getInstance().clearFuel();

robotContainer.superstructure.periodic();
StatusSignalUtil.refreshAll();
CommandScheduler.getInstance().run();
robotContainer.superstructure.periodic();

FieldManager.getInstance().drawFuel();

Expand Down
20 changes: 20 additions & 0 deletions CompBot/src/main/java/frc/robot/aiming/AimConstraints.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package frc.robot.aiming;

import edu.wpi.first.math.geometry.Rotation2d;

/**
* A class representing the physical constraints of the shooter.
*/
public record AimConstraints(
Rotation2d minShooterAngle,
Rotation2d maxShooterAngle,
double maxOutput) {

/** Returns whether the given aim parameters satisfy this constraint */
public boolean check(AimParams params) {
boolean outputOk = params.output <= maxOutput();
boolean pitchOk = (params.pitch.getRadians() >= minShooterAngle.getRadians())
&& (params.pitch.getRadians() <= maxShooterAngle.getRadians());
return outputOk && pitchOk;
}
}
3 changes: 1 addition & 2 deletions CompBot/src/main/java/frc/robot/aiming/AimMeasurement.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@

import edu.wpi.first.math.geometry.Rotation2d;
import edu.wpi.first.units.measure.Distance;
import edu.wpi.first.units.measure.LinearVelocity;
import edu.wpi.first.units.measure.Time;

public record AimMeasurement(
Distance distance,
Rotation2d pitch,
LinearVelocity velocity,
double shooterControl,
Time time) {
}
64 changes: 48 additions & 16 deletions CompBot/src/main/java/frc/robot/aiming/AimParams.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
package frc.robot.aiming;

import static edu.wpi.first.units.Units.Degrees;
import static edu.wpi.first.units.Units.MetersPerSecond;
import edu.wpi.first.math.geometry.Rotation2d;
import edu.wpi.first.units.measure.LinearVelocity;

import frc.robot.util.OnboardLogger;

/**
* The parameters of a shooter at a particlar moment in time. This is the type that is returned when
* a shot is generated, meaning that this is what is applied to each subystem.
*/
public class AimParams {
/** The status of the parameters object. */
public AimStatus status = AimStatus.Unchecked;
/** The manner of speed control the paramters requires */
public SpeedControl control = SpeedControl.ProjectileVelocity;
/** the launch angle of the fuel out of the robot. */
public Rotation2d pitch = Rotation2d.kZero;
/**
Expand All @@ -20,23 +19,56 @@ public class AimParams {
* shooter.
*/
public Rotation2d yaw = Rotation2d.kZero;
/** the velocity that the fuel should be ejected out at, relative to the robot. */
public LinearVelocity velocity = MetersPerSecond.zero();
/**
* the output that the fuel should be ejected out at. If control is ProjectileVelocity, then this
* is m/s relative to the robot.
*/
public double output = 0.0;
/** the tolerated error in the shot's pitch */
public Rotation2d deltaPitch = Rotation2d.fromDegrees(4);
/** the tolerated error in the shot's yaw */
public Rotation2d deltaYaw = Rotation2d.fromDegrees(2);
/** the tolerated error in the shot's velocity */
public LinearVelocity deltaVelocity = MetersPerSecond.of(0.35);
public double deltaOutput = 0.35;

public AimParams() {}

public AimParams(AimStatus status) {
this.status = status;
}

private OnboardLogger ologger = new OnboardLogger("AimParams");
public enum AimStatus {
/** The program has not yet evaluated the valididty of this parameters object */
Unchecked,
/** Not a possible shot, do not try to attempt. Values are invalid. */
Impossible,
/** A shot that is calculated to go in */
Possible;

public boolean isOk() {
return this == Possible;
}
}

public static AimParams impossible() {
return new AimParams(AimStatus.Impossible);
}

/** Returns whether the aim parameters calculated are feasible */
public boolean isOk() {
return status.isOk();
}

public AimParams() {
ologger.registerMeasurement("Pitch", () -> pitch.getMeasure(), Degrees);
ologger.registerMeasurement("Yaw", () -> yaw.getMeasure(), Degrees);
ologger.registerMeasurement("Velocity", () -> velocity, MetersPerSecond);
ologger.registerMeasurement("Error/Pitch", () -> deltaPitch.getMeasure(), Degrees);
ologger.registerMeasurement("Error/Yaw", () -> deltaYaw.getMeasure(), Degrees);
ologger.registerMeasurement("Error/Velocity", () -> deltaVelocity, MetersPerSecond);
public enum SpeedControl {
/**
* The velocity parameter of the {@link AimParams} is the projectile's desired velocity, in
* meters per second.
*/
ProjectileVelocity,
/**
* The velocity parameter of the {@link AimParams} is the shooter's control input, in its
* appropriate units.
*/
MechanismControl;
}
}
11 changes: 4 additions & 7 deletions CompBot/src/main/java/frc/robot/aiming/AimStrategy.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
package frc.robot.aiming;

import frc.robot.superstructure.StateManager;
import edu.wpi.first.math.geometry.Pose3d;
import edu.wpi.first.math.geometry.Translation2d;

/**
* An interface representing a method of aim-calculation; i.e. calculating what shot parameters are
* necessary for a given robot configuration
*/
public abstract class AimStrategy {
public AimParams params = new AimParams();

public interface AimStrategy {
/**
* Updates the AimParams with the new calculated shot based on the robot's state
*
* @param state The {@link frc.robot.superstructure.Superstructure}'s state.
*/
public abstract AimParams update(StateManager state);
public AimParams update(Pose3d target, Pose3d shooter, Translation2d velocity);
}
38 changes: 0 additions & 38 deletions CompBot/src/main/java/frc/robot/aiming/ExperimentalAim.java

This file was deleted.

38 changes: 0 additions & 38 deletions CompBot/src/main/java/frc/robot/aiming/InterpolationAim.java

This file was deleted.

Loading