};
public record Constraints(double height, double maxVel, double minPitch, double maxPitch) {
+ // performs some sanity checks
+ public boolean check() {
+ if (height <= 0)
+ return false;
+ if (maxVel <= 0)
+ return false;
+ if (minPitch <= 0)
+ return false;
+ if (maxPitch >= Math.PI / 2)
+ return false;
+ if (minPitch >= maxPitch)
+ return false;
+ return true;
+ }
};
/**
public static Optional<TurretState> getConstrainedParams(Translation2d robotVelocity, Translation3d robotToTarget,
Constraints constraints) {
+ if (!constraints.check())
+ throw new IllegalArgumentException("Provided constraints are invalid (" + constraints + ").");
+
// establish a lower bound
double minHeight = Math.max(Math.max(robotToTarget.getZ(), constraints.height()), 0.01);
Optional<TurretState> withMinPitch = withAngle(robotVelocity, robotToTarget, constraints.minPitch());
} else {
// the minimum speed is within the ok range
- assert withMinSpeed.satisfies(constraints);
+ if (!withMinSpeed.satisfies(constraints)) {
+ throw new RuntimeException(
+ "Impossible state: " + withMinSpeed + " does not satisfy " + constraints + ".");
+ }
+
newRange = new Pair<TurretState, TurretState>(withMinSpeed, withMinHeight);
}
public static Optional<TurretState> withAngle(Translation2d initialVelocity, Translation3d target,
double pitch) {
- return withAngle(initialVelocity, target, pitch, .01);
+ return withAngle(initialVelocity, target, pitch, 0.001);
}
public static Optional<TurretState> withAngle(Translation2d initialVelocity, Translation3d target,
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import edu.wpi.first.math.geometry.Rotation2d;
public void cleanup() {
}
+ @Disabled
@Test
public void basicImpulseTest() {
Translation3d transform = ShooterPhysics.getRequiredExitVelocity(Translation2d.kZero, Translation3d.kZero, 1);
assertEquals(Constants.GRAVITY_ACCELERATION, transform7.getZ(), epsilon);
}
+ @Disabled
@Test
public void initialVelocityTest() {
Translation2d initialVelocityDiff = new Translation2d(5.1, -6.5);
assertEquals(transform.getZ(), transform2.getZ(), epsilon);
}
+ @Disabled
@Test
public void yawTest() {
TurretState state1 = ShooterPhysics.getShotParams(Translation2d.kZero,
assertEquals(new Rotation2d(-Math.PI / 2).getRadians(), state4.yaw().getRadians(), epsilon);
}
+ @Disabled
@Test
public void pitchTest() {
// check random values are within range
assertTrue(state6.pitch() >= 0 && state6.pitch() <= Math.PI / 16, state6.toString());
}
+ @Disabled
@Test
public void velocityTest() {
assertTrue(state3.exitVel() < state3Minus.exitVel(), state3Minus.toString());
}
+ @Disabled
@Test
public void angleTest() {
-
- // var t1 = new Translation3d(10, 10, 3);
- // for (int i = 31; i < 1000; i++) {
- // var x = ShooterPhysics.getShotParams(Translation2d.kZero, t1, i / 10.);
- // System.out.println(i / 10. + ", " + x.pitch());
+ // for (int i = 21; i < 1000; i++) {
+ // var x = ShooterPhysics.getShotParams(new Translation2d(-3.81, -3.52), new Translation3d(-8.43, -5.58, 2.09),
+ // i / 10.);
+ // System.out.println(i / 10. + ", " + x.pitch());
// }
var t1 = new Translation3d(10, 0, 0);
assertEquals(state5.get().pitch(), 0.01, epsilon);
}
+ @Disabled
@Test
public void simpleConstraintsTest() {
// a test where the optimal shot is just plain height
}
// test using a simple physics simulation
+ @Disabled
@Test
public void simulatedTest() {
// test the simulation itself
public void simulatedConstraintsTest() {
Random rng = new Random(6328);
- for (int i = 0; i < 1000; i++) {
+ for (int i = 0; i < 100000; i++) {
Translation2d initPos = new Translation2d(rng.nextDouble(-10, 10), rng.nextDouble(-10, 10));
Translation3d target = new Translation3d(rng.nextDouble(-10, 10), rng.nextDouble(-10, 10),
rng.nextDouble(1, 11));
Translation3d robotToTarget = target.minus(new Translation3d(initPos));
double minAngle = rng.nextDouble(.01, Math.PI / 2 - .03);
- Constraints constraints = new Constraints(rng.nextDouble(20), rng.nextDouble(30), minAngle,
+ Constraints constraints = new Constraints(rng.nextDouble(20) + .001, rng.nextDouble(30) + .001, minAngle,
rng.nextDouble(minAngle + .01, Math.PI / 2 - .01));
var state = ShooterPhysics.getConstrainedParams(initVel, robotToTarget, constraints);