trajectory/ballistics/constraints: Added
RobotLauncherVelBC Constrains robot-relative spherical velocity components
This commit is contained in:
parent
66150eea99
commit
e171339c5c
|
|
@ -0,0 +1,129 @@
|
||||||
|
package org.fairportrobotics.frc.robolib.trajectory.ballistics.constraints;
|
||||||
|
|
||||||
|
import org.fairportrobotics.frc.robolib.Util;
|
||||||
|
import org.fairportrobotics.frc.robolib.trajectory.ballistics.models.BallisticModel;
|
||||||
|
|
||||||
|
import edu.wpi.first.units.Units;
|
||||||
|
import edu.wpi.first.units.measure.Angle;
|
||||||
|
import edu.wpi.first.units.measure.LinearVelocity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A ballistic constraint defining the minimum and maximum values for
|
||||||
|
* robot-relative launcher velocity (in spherical coordinates)
|
||||||
|
*/
|
||||||
|
public class RobotLauncherVelBC extends BallisticConstraint {
|
||||||
|
private final Double minVelocityMPS;
|
||||||
|
private final Double maxVelocityMPS;
|
||||||
|
private final Double targetVelocityPercent;
|
||||||
|
|
||||||
|
private final Double minAzimuthDegrees;
|
||||||
|
private final Double maxAzimuthDegrees;
|
||||||
|
private final Double targetAzimuthPercent;
|
||||||
|
|
||||||
|
private final Double minElevationDegrees;
|
||||||
|
private final Double maxElevationDegrees;
|
||||||
|
private final Double targetElevationPercent;
|
||||||
|
|
||||||
|
class BoundViolated extends Exception {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Full constructor for the constraint
|
||||||
|
*
|
||||||
|
* Percent variables are a percentage (0.0-1.0) of the range between the min
|
||||||
|
* and max values for the given value where no penalty is applied. Range is
|
||||||
|
* always centered on the midpoint of the values
|
||||||
|
*
|
||||||
|
* @param minVelocity Minimum radial velocity (nullable)
|
||||||
|
* @param maxVelocity Maximum radial velocity (nullable)
|
||||||
|
* @param targetVelocityPercent Ideal percent range for radial velocity (nullable)
|
||||||
|
* @param minAzimuth Minimum azimuth angle (nullable)
|
||||||
|
* @param maxAzimuth Maximum azimuth angle (nullable)
|
||||||
|
* @param targetAzimuthPercent Ideal percent range for azimuth (nullable)
|
||||||
|
* @param minElevation Minimum elevation angle (nullable)
|
||||||
|
* @param maxElevation Maximum elevation angle (nullable)
|
||||||
|
* @param targetElevationPercent Ideal percent range for elevation (nullable)
|
||||||
|
*/
|
||||||
|
public RobotLauncherVelBC(
|
||||||
|
LinearVelocity minVelocity, LinearVelocity maxVelocity, Double targetVelocityPercent,
|
||||||
|
Angle minAzimuth, Angle maxAzimuth, Double targetAzimuthPercent,
|
||||||
|
Angle minElevation, Angle maxElevation, Double targetElevationPercent
|
||||||
|
) {
|
||||||
|
this.minVelocityMPS = minVelocity.in(Units.MetersPerSecond);
|
||||||
|
this.maxVelocityMPS = maxVelocity.in(Units.MetersPerSecond);
|
||||||
|
this.targetVelocityPercent = targetVelocityPercent;
|
||||||
|
|
||||||
|
this.minAzimuthDegrees = minAzimuth.in(Units.Degrees);
|
||||||
|
this.maxAzimuthDegrees = maxAzimuth.in(Units.Degrees);
|
||||||
|
this.targetAzimuthPercent = targetAzimuthPercent;
|
||||||
|
|
||||||
|
this.minElevationDegrees = minElevation.in(Units.Degrees);
|
||||||
|
this.maxElevationDegrees = maxElevation.in(Units.Degrees);
|
||||||
|
this.targetElevationPercent = targetElevationPercent;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Double getPartialWeight(
|
||||||
|
Double lowerBound, Double upperBound, Double idealPercentRange, double value
|
||||||
|
) throws BoundViolated {
|
||||||
|
// There is nothing to check for this bound
|
||||||
|
if(lowerBound == null && upperBound == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform bounds checking
|
||||||
|
if(
|
||||||
|
(lowerBound != null && value < lowerBound) ||
|
||||||
|
(upperBound != null && value > upperBound)
|
||||||
|
) {
|
||||||
|
throw new BoundViolated();
|
||||||
|
} else if(lowerBound == null || upperBound == null || idealPercentRange == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
double idealMin = 0.5 - idealPercentRange/2;
|
||||||
|
double idealMax = 0.5 + idealPercentRange/2;
|
||||||
|
double valuePercent = Util.rangePercent(lowerBound, upperBound, value);
|
||||||
|
|
||||||
|
if(valuePercent < idealMin) {
|
||||||
|
return Util.rangePercent(idealMin, 0.0, valuePercent);
|
||||||
|
} else if(valuePercent > idealMax) {
|
||||||
|
return Util.rangePercent(idealMax, 1.0, valuePercent);
|
||||||
|
} else {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public <M extends BallisticModel<P>, P> Double evaluate(
|
||||||
|
M model, BCEvalParams evalParams
|
||||||
|
) {
|
||||||
|
Double velocityWeight = null;
|
||||||
|
Double azimuthWeight = null;
|
||||||
|
Double elevationWeight = null;
|
||||||
|
|
||||||
|
// Compute the partial penalty for velocity
|
||||||
|
try {
|
||||||
|
velocityWeight = this.getPartialWeight(
|
||||||
|
minVelocityMPS, maxVelocityMPS, targetVelocityPercent,
|
||||||
|
evalParams.getCandidateShooterVelocityRelative().getSphericalVelocity().in(Units.MetersPerSecond)
|
||||||
|
);
|
||||||
|
azimuthWeight = this.getPartialWeight(
|
||||||
|
minAzimuthDegrees, maxAzimuthDegrees, targetAzimuthPercent,
|
||||||
|
evalParams.getCandidateShooterVelocityRelative().getAzimuthAngle().in(Units.Degrees)
|
||||||
|
);
|
||||||
|
elevationWeight = this.getPartialWeight(
|
||||||
|
minElevationDegrees, maxElevationDegrees, targetElevationPercent,
|
||||||
|
evalParams.getCandidateShooterVelocityRelative().getElevationAngle().in(Units.Degrees)
|
||||||
|
);
|
||||||
|
} catch(BoundViolated e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
double maxWeight = 0.0;
|
||||||
|
for (Double partialWeight : new Double[]{velocityWeight, azimuthWeight, elevationWeight}) {
|
||||||
|
if(partialWeight != null) {
|
||||||
|
maxWeight = Math.max(partialWeight, maxWeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return maxWeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue