From f1c80233f0bd58c679f48203d9c6f299e139264a Mon Sep 17 00:00:00 2001 From: Ray Healy Date: Tue, 10 Feb 2026 17:06:11 -0500 Subject: [PATCH] src/robolib/trajectory/ballistics: Basic impl of calculator base class - BallisticCalculator.java: The base class for calculating solutions - BCResult.java: Holds computed solution and related values - BCEvalParams.java: Stores and computes values used in candidate evaluation - BallisticConstraint.java: evaluate() takes BCEvalParams --- .../ballistics/calculators/BCResult.java | 27 ++++ .../calculators/BallisticCalculator.java | 78 ++++++++++++ .../ballistics/constraints/BCEvalParams.java | 115 ++++++++++++++++++ .../constraints/BallisticConstraint.java | 12 +- 4 files changed, 226 insertions(+), 6 deletions(-) create mode 100644 lib/src/main/java/org/fairportrobotics/frc/robolib/trajectory/ballistics/calculators/BCResult.java create mode 100644 lib/src/main/java/org/fairportrobotics/frc/robolib/trajectory/ballistics/calculators/BallisticCalculator.java create mode 100644 lib/src/main/java/org/fairportrobotics/frc/robolib/trajectory/ballistics/constraints/BCEvalParams.java diff --git a/lib/src/main/java/org/fairportrobotics/frc/robolib/trajectory/ballistics/calculators/BCResult.java b/lib/src/main/java/org/fairportrobotics/frc/robolib/trajectory/ballistics/calculators/BCResult.java new file mode 100644 index 0000000..bbe047c --- /dev/null +++ b/lib/src/main/java/org/fairportrobotics/frc/robolib/trajectory/ballistics/calculators/BCResult.java @@ -0,0 +1,27 @@ +package org.fairportrobotics.frc.robolib.trajectory.ballistics.calculators; + +import org.fairportrobotics.frc.robolib.trajectory.Velocity3d; + +public class BCResult

{ + public final Double velPenalty; /// The penalty for the computed launcher velocity (null if invalid) + public final Velocity3d velGlobal; /// The computed launcher velocity (in the global coorinate space) + public final Velocity3d velRelative; /// The computed launcher velocity (in the robot-relative coordinate space) + public final P velParam; /// The model parameter that yielded velGlobal + + + public BCResult( + Double velPenalty, + Velocity3d velGlobal, + Velocity3d velRelative, + P velParam + ) { + this.velPenalty = velPenalty; + this.velGlobal = velGlobal; + this.velRelative = velRelative; + this.velParam = velParam; + } + + public boolean isValid() { + return this.velPenalty != null; + } +} diff --git a/lib/src/main/java/org/fairportrobotics/frc/robolib/trajectory/ballistics/calculators/BallisticCalculator.java b/lib/src/main/java/org/fairportrobotics/frc/robolib/trajectory/ballistics/calculators/BallisticCalculator.java new file mode 100644 index 0000000..62a5937 --- /dev/null +++ b/lib/src/main/java/org/fairportrobotics/frc/robolib/trajectory/ballistics/calculators/BallisticCalculator.java @@ -0,0 +1,78 @@ +package org.fairportrobotics.frc.robolib.trajectory.ballistics.calculators; + +import java.util.ArrayList; + +import org.fairportrobotics.frc.robolib.trajectory.Velocity3d; +import org.fairportrobotics.frc.robolib.trajectory.ballistics.constraints.BCEvalParams; +import org.fairportrobotics.frc.robolib.trajectory.ballistics.constraints.BallisticConstraint; +import org.fairportrobotics.frc.robolib.trajectory.ballistics.models.BallisticModel; + +import edu.wpi.first.units.measure.Angle; + +public abstract class BallisticCalculator { + private ArrayList constraints; + private double velocityDiffWeight; + + // + // Setup code + // + + public BallisticCalculator() { + constraints = new ArrayList<>(); + this.velocityDiffWeight = 1.0; + } + + public BallisticCalculator addConstraint(BallisticConstraint constraint) { + constraints.add(constraint); + return this; + } + + public BallisticCalculator setVelocityDiffWeight(double weight) { + this.velocityDiffWeight = weight; + return this; + } + + // + // Computation + // + + /** + * Public solution + * @param The type of model to compute against + * @param

The candidate parameter type of the model + * @param model The model to compute against + * @param initParam The seed parameter (to start computation) + * @param velRobot The velocity of the robot (in the model's coordinate system) + * @param velShooter The velocity currently imparted by the shooter (in the model's coordinate system) + * @param robotHeading The heading of the robot (in the model's coordinate system) + * @return The generated BCResult + */ + public abstract , P> BCResult

computeSolution( + M model, Velocity3d velRobot, Velocity3d velShooter, + Angle robotHeading, boolean quickMode + ); + + + protected , P> Double evaluateCandidate( + M model, BCEvalParams evalParams + ) { + // Get the weight component for velocity difference + Velocity3d velShooterDiff = + evalParams.getCandidateGlobalShooterVelocity() + .minus(evalParams.getCurrentGlobalShooterVelocity()); + double numerator = velShooterDiff.getSquareMagnitude() * this.velocityDiffWeight; + double denominator = this.velocityDiffWeight; + + // Evaluate against all constraints + for (BallisticConstraint constraint : this.constraints) { + Double penaltyPercent = constraint.evaluate(model, evalParams); + if(penaltyPercent == null) return null; + + numerator += penaltyPercent * constraint.getWeight(); + denominator += constraint.getWeight(); + } + + // Get the final sum + return numerator/denominator; + } +} diff --git a/lib/src/main/java/org/fairportrobotics/frc/robolib/trajectory/ballistics/constraints/BCEvalParams.java b/lib/src/main/java/org/fairportrobotics/frc/robolib/trajectory/ballistics/constraints/BCEvalParams.java new file mode 100644 index 0000000..c1e4497 --- /dev/null +++ b/lib/src/main/java/org/fairportrobotics/frc/robolib/trajectory/ballistics/constraints/BCEvalParams.java @@ -0,0 +1,115 @@ +package org.fairportrobotics.frc.robolib.trajectory.ballistics.constraints; + +import org.fairportrobotics.frc.robolib.trajectory.Velocity3d; + +import edu.wpi.first.units.measure.Angle; + +/** + * Param block for ballistic constraint and calculator evaluation + */ +public class BCEvalParams { + // + // Members + // + + // Robot motion params + private final Velocity3d currentGlobalRobotVelocity; + private final Angle currentGlobalRobotAngle; + private final Velocity3d currentGlobalShooterVelocity; + + // Candidate params + private final Velocity3d candidateGlobalTotalVelocity; + + // Composite value cache + private Velocity3d cache_candidateGlobalShooterVelocity; + private Velocity3d cache_candidateRelativeShooterVelocity; + + // + // Setup + // + + public BCEvalParams( + Velocity3d currentGlobalRobotVelocity, + Angle currentGlobalRobotAngle, + Velocity3d currentGlobalShooterVelocity, + Velocity3d candidateGlobalTotalVelocity + ) { + this.currentGlobalRobotVelocity = currentGlobalRobotVelocity; + this.currentGlobalRobotAngle = currentGlobalRobotAngle; + this.currentGlobalShooterVelocity = currentGlobalShooterVelocity; + this.candidateGlobalTotalVelocity = candidateGlobalTotalVelocity; + + this.cache_candidateGlobalShooterVelocity = null; + this.cache_candidateRelativeShooterVelocity = null; + } + + + // + // Base attribute getters + // + + /** + * @return The robot's current velocity (in field coordinates) + */ + public Velocity3d getCurrentGlobalRobotVelocity() { + return this.currentGlobalRobotVelocity; + } + + + /** + * @return The robot's current heading angle (in field coordinates) + */ + public Angle getCurrentGlobalRobotAngle() { + return this.currentGlobalRobotAngle; + } + + + /** + * @return The shooter's current launch velocity (in field coordinates) + */ + public Velocity3d getCurrentGlobalShooterVelocity() { + return this.currentGlobalShooterVelocity; + } + + /** + * @return The candidate total (robot + shooter) velocity (in field coordinates) + */ + public Velocity3d getCandidateGlobalTotalVelocity() { + return this.candidateGlobalTotalVelocity; + } + + // + // Composite value getters + // + + /** + * @return The candidate shooter velocity (in field coordinates) at current + * robot velocity + */ + public Velocity3d getCandidateGlobalShooterVelocity() { + if(this.cache_candidateGlobalShooterVelocity == null) { + this.cache_candidateGlobalShooterVelocity = + this.candidateGlobalTotalVelocity + .minus(this.currentGlobalRobotVelocity); + } + return this.cache_candidateGlobalShooterVelocity; + } + + /** + * @return The candidate shooter velocity (in robot coordinates) at current + * robot velocity and heading + */ + public Velocity3d getCandidateRelativeShooterVelocity() { + if(this.cache_candidateRelativeShooterVelocity == null) { + this.cache_candidateRelativeShooterVelocity = + new Velocity3d( + this.getCandidateGlobalShooterVelocity().getHorizontalVelocity(), + this.getCandidateGlobalShooterVelocity().getVeritcalVelocity(), + this.getCandidateGlobalShooterVelocity().getAzimuthAngle() + .minus(this.getCurrentGlobalRobotAngle()) + ); + } + return this.cache_candidateRelativeShooterVelocity; + } + +} diff --git a/lib/src/main/java/org/fairportrobotics/frc/robolib/trajectory/ballistics/constraints/BallisticConstraint.java b/lib/src/main/java/org/fairportrobotics/frc/robolib/trajectory/ballistics/constraints/BallisticConstraint.java index c473446..b53150d 100644 --- a/lib/src/main/java/org/fairportrobotics/frc/robolib/trajectory/ballistics/constraints/BallisticConstraint.java +++ b/lib/src/main/java/org/fairportrobotics/frc/robolib/trajectory/ballistics/constraints/BallisticConstraint.java @@ -1,8 +1,8 @@ package org.fairportrobotics.frc.robolib.trajectory.ballistics.constraints; -import org.fairportrobotics.frc.robolib.trajectory.Velocity3d; import org.fairportrobotics.frc.robolib.trajectory.ballistics.models.BallisticModel; + public abstract class BallisticConstraint { protected double weight; @@ -42,14 +42,14 @@ public abstract class BallisticConstraint { /** * Evaluate a given solution's fitness against this constraint * - * TODO: Expand this with additional parameters - * * @param The type of BallisticModel * @param

The parameter type of M - * @param model The model used to compute candidate - * @param candidate The candidate velocity computed by model + * @param model The model used to compute the candidate + * @param evalParams The candidate parameters used in evaluation * @return A penalty value (from 0 to 1.0) for this match (null if candidate * is invalid). Used with weight to determine candidate fitness */ - public abstract , P> Double evaluate(M model, Velocity3d candidate); + public abstract , P> Double evaluate( + M model, BCEvalParams evalParams + ); }