Package com.crossbotics.ftchelper.vision
Class AimController
java.lang.Object
com.crossbotics.ftchelper.vision.AimController
Turns a camera target into a turn power, safely: no target, an old picture, or no bearing all
give 0 (the robot never turns toward a target it cannot see now). (Last season's TagAimController.)
It is a small "PD" controller. P (proportional): the farther off the target is, the harder it turns. D (derivative): if the error is shrinking fast, it eases off so the robot does not swing past the target. Tutorial 07 (docs/tutorials/07-pid-lift.md) explains P, I and D step by step, and Tutorial 18 (docs/tutorials/18-vision-aim.md) uses this class.
AimController aim = new AimController(0.02, 0.003) // P and D on the bearing (degrees)
.deadband(1.5) // close enough
.maxPower(0.5)
.maxAgeMs(150); // ignore pictures older than this
// every loop, while the driver holds the aim button:
drive.drive(forward, strafe, aim.turnPower(camera.target("RED SCORING"))); // ready for the drive's turn
For a turret, use turret.aimAtTarget(target, cameraOnTurret) instead.
Docs: docs/modules/vision.md-
Constructor Summary
ConstructorsConstructorDescriptionAimController(double kP, double kD) Makes an aim controller.AimController(double kP, double kD, LongSupplier clockNanos) For tests: the same, with a clock you control (nanoseconds). -
Method Summary
Modifier and TypeMethodDescriptiondoubleccwPower(TargetObservation target) The same power, COUNTERCLOCKWISE positive (the IMU's sign), e.g.deadband(double deg) Errors smaller than this (degrees) give 0 power and count as aimed.booleanisAimed()True if the last fresh target was inside the deadband.maxAgeMs(double ms) Pictures older than this are ignored (milliseconds).maxPower(double p) The most turn power the aim may use, 0 to 1.offset(double deg) Where the target should sit in the camera's view when the LAUNCHER points straight at it, in degrees (positive = the target appears left of the camera's center).voidreset()Forgets the past (call when the driver lets go of the aim button).doubleturnPower(TargetObservation target) The turn power toward the target, CLOCKWISE positive: the same sign as every drive's turn (drive.drive(f, s, aim.turnPower(t)),tank.arcade(f, aim.turnPower(t))).
-
Constructor Details
-
AimController
public AimController(double kP, double kD) Makes an aim controller.- Parameters:
kP- turn power per degree of error (e.g. 0.02: 10 degrees off gives 0.2 power)kD- turn power per (degree per second) of change in the error; 0 turns the D part off
-
AimController
For tests: the same, with a clock you control (nanoseconds).
-
-
Method Details
-
deadband
Errors smaller than this (degrees) give 0 power and count as aimed. Default 1.5. Without it the robot would twitch back and forth around the target forever. Returns this controller, so you can chain settings:.deadband(1.5).maxPower(0.5). -
maxPower
The most turn power the aim may use, 0 to 1. Default 0.6. Lower = gentler, slower aiming. -
maxAgeMs
Pictures older than this are ignored (milliseconds). Default 150. -
offset
Where the target should sit in the camera's view when the LAUNCHER points straight at it, in degrees (positive = the target appears left of the camera's center). Use it when the camera is not centered on the launcher. Example: a camera mounted left of the launcher sees the target a little to its right when the launcher is aimed, so the offset is negative. Find it with the aim tuner (docs/modules/finders.md). Default 0. -
turnPower
The turn power toward the target, CLOCKWISE positive: the same sign as every drive's turn (drive.drive(f, s, aim.turnPower(t)),tank.arcade(f, aim.turnPower(t))). 0 when there is no fresh target. Call it every loop while aiming.- Parameters:
target- the target from the camera, e.g.camera.target("RED SCORING"); null is fine (gives 0)
-
ccwPower
The same power, COUNTERCLOCKWISE positive (the IMU's sign), e.g. for your own heading math. The D part only changes on a NEW picture, so a repeated picture never fakes motion. -
isAimed
public boolean isAimed()True if the last fresh target was inside the deadband. -
reset
public void reset()Forgets the past (call when the driver lets go of the aim button). Without this, the D part would compare the next picture with one from long ago and give a wrong kick.
-