Class MovingShot
- The picture is old. A camera's picture is a few tens of milliseconds old by the time the
code reads it. Since then the robot turned and moved, so the goal is no longer where the
picture shows it.
solve(double, double, double, double, double, double)turns the goal back by the robot's turn and moves it by the robot's motion over that time: the goal NOW. - The piece keeps the shooter's speed. A piece shot from a robot driving sideways at 30 in/s also flies sideways at 30 in/s. If it is in the air for 0.8 s, it lands 24 in to the side. So aim at a point that far the OTHER way: the "virtual goal" = the goal minus the shooter's speed x the flight time. The launcher's speed comes from the virtual goal's distance too (the piece flies that far relative to the robot).
Where the shooter is. The shooter need not be at the robot's centre: shooterAt(double, double)
says where it is (a turret's pivot, or a fixed launcher's exit). That changes three things: the
distance is from the shooter, a turning robot swings an off-centre shooter sideways (more speed for
the piece), and a fixed shooter to one side of the centre must turn the whole robot a little MORE
than "face the goal" so that its own line passes through the goal. onTurret() says a turret
aims the shot (the answer is a turret angle); without it the whole robot turns (the answer is how far
to turn the robot).
One frame for everything, the robot's: x forward, y to the LEFT, from the robot's centre, angles
counterclockwise + (positive = to the left), the same as a TargetObservation. The five-files
robot does all this for you (docs/modules/robot.md, section "Aim", Tunables.Aim.shootOnMove);
this class is the plain math, for your own code and tests.
MovingShot shot = new MovingShot().shooterAt(-4, 0).onTurret().flightSec(0.7, 0).maxLeadIn(24);
// The goal 60 in ahead of the robot's centre; the robot strafes RIGHT at 30 in/s (left speed -30),
// no turn; the picture is 40 ms old.
MovingShot.Result r = shot.solve(60, 0, 0, -30, 0, 0.040);
// r.aimDeg: the turret angle (left of straight ahead: it leads); r.distanceIn: for the launcher's speed
What it leaves out (small for an FTC robot): the turret's own turn during the picture's age, air drag on the piece, and a change of the robot's speed during the flight. Docs: docs/modules/vision.md (section "MovingShot"), docs/tutorials/start/09-shooter-and-camera.md
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final classWhatsolve(double, double, double, double, double, double)gives: where to aim, how far to shoot, and how big the lead is. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionflightSec(double sec, double perIn) How long a piece is in the air:sec + perIn x distance, seconds.maxLeadIn(double in) The most the aim point may move for the lead, inches (a safety cap).onTurret()A turret aims the shot:MovingShot.Result.aimDegis the turret angle.static double[]seenFrom(double bearingDeg, double distanceIn, double camForwardIn, double camLeftIn, double camYawDeg) Where a goal is from the robot's centre, from what a camera sees: {forward, left} inches.shooterAt(double forwardIn, double leftIn) Where the shooter is from the robot's centre: a turret's pivot, or where a fixed launcher's piece leaves.solve(double goalForwardIn, double goalLeftIn, double forwardInPerSec, double leftInPerSec, double turnDegPerSec, double latencySec) Brings a goal seen in an old picture forward to now, leads it for the flight time, and says where to aim the shooter.static double[]toRobotFrame(double fieldVx, double fieldVy, double headingDeg) The robot's speed over the field turned into the robot's own frame: {forward, left}, inches per second.
-
Constructor Details
-
MovingShot
public MovingShot()
-
-
Method Details
-
shooterAt
Where the shooter is from the robot's centre: a turret's pivot, or where a fixed launcher's piece leaves. Inches. Default 0, 0 (the centre).- Parameters:
forwardIn- inches in front of the centre (negative = behind)leftIn- inches left of the centre (negative = right)
-
onTurret
A turret aims the shot:MovingShot.Result.aimDegis the turret angle. Without it the whole robot turns. -
flightSec
How long a piece is in the air:sec + perIn x distance, seconds. Measure it with a slow-motion video (frames from leaving the shooter to reaching the goal, divided by the frame rate).- Parameters:
sec- the flight time, seconds (0 and perIn 0 = no lead: only the picture's age)perIn- extra seconds per inch of distance (0 = the same time at every distance)
-
maxLeadIn
The most the aim point may move for the lead, inches (a safety cap). 0 or less = no cap. Default 24. -
solve
public MovingShot.Result solve(double goalForwardIn, double goalLeftIn, double forwardInPerSec, double leftInPerSec, double turnDegPerSec, double latencySec) Brings a goal seen in an old picture forward to now, leads it for the flight time, and says where to aim the shooter.- Parameters:
goalForwardIn- the goal in front of the robot's centre when the picture was taken, inchesgoalLeftIn- the goal left of the robot's centre then, inches (seeseenFrom(double, double, double, double, double))forwardInPerSec- the robot's speed forward, inches per second (seetoRobotFrame(double, double, double))leftInPerSec- the robot's speed to the left, inches per secondturnDegPerSec- how fast the robot turns, degrees per second, counterclockwise +latencySec- how old the picture is, seconds (0 for a goal worked out from the odometry now)- Returns:
- where to aim and how far to shoot, now
-
seenFrom
public static double[] seenFrom(double bearingDeg, double distanceIn, double camForwardIn, double camLeftIn, double camYawDeg) Where a goal is from the robot's centre, from what a camera sees: {forward, left} inches.- Parameters:
bearingDeg- the camera's bearing to it, degrees, counterclockwise + (left)distanceIn- the camera's distance to it, inchescamForwardIn- where the camera is: inches in front of the centrecamLeftIn- inches left of the centrecamYawDeg- which way the camera faces from the robot's front (a turret's angle for a camera on it)
-
toRobotFrame
public static double[] toRobotFrame(double fieldVx, double fieldVy, double headingDeg) The robot's speed over the field turned into the robot's own frame: {forward, left}, inches per second. The field frame is the library's (x right, y away from your drivers' wall).- Parameters:
fieldVx- speed toward +x (right), inches per secondfieldVy- speed toward +y (away), inches per secondheadingDeg- the robot's heading, degrees, counterclockwise +, 0 = away from your wall- Returns:
- {forward, left}
-