sin x
e^(−ct)
x²
dy/dx
θ
sin
cos
Lissajous
r = cos kθ
e^(−ct) cos ωt
ŷ = mx + b
a
c
b
θ
a² + b² = c²
e^(iπ) + 1 = 0
‖v‖ = √(x² + y²)
d/dx x^n = n·x^(n−1)
lim (f(x+h) − f(x)) / h
∇ · F = ∂P/∂x + ∂Q/∂y
P(A|B) = P(B|A) P(A) / P(B)
∫∫_R f dA
[ a b ]
[ c d ]
Σ x^n/n! = e^x
MovingShotSolution solveMovingShot(
Translation3d actualTarget,
Translation3d robotVelocity,
Translation3d fieldAcceleration,
Rotation2d robotHeading,
double chassisOmega) {
// turret tangential velocity from spin
// v = (-omega*dy, omega*dx)
fieldRelVel = new Translation2d(
vx + (-omega * turretDy),
vy + ( omega * turretDx))
.rotateBy(robotHeading);
// ball leaves D seconds after aim
// vt = hub - v(D+TOF) - a D TOF
// - 0.5 a D^2
posOffX = -velX*D - 0.5*accX*D*D;
posOffY = -velY*D - 0.5*accY*D*D;
double driftTOF = dragC > 1e-6
? (1 - Math.exp(-dragC*t)) / dragC
: t;
tofOffX = -velX*driftTOF - accX*D*t;
tofOffY = -velY*driftTOF - accY*D*t;
// f'(t): central finite difference
final double H = 0.005; // 5ms step
dPrime = (tofHigh - tofLow) / (2*H);
virtualTarget = new Translation3d(
actualTarget.getX() + posOffX + tofOffX,
actualTarget.getY() + posOffY + tofOffY,
actualTarget.getZ());
for (int i = 0; i < maxIters; i++) {
double newTof = tof(v, theta, d) * scale;
...
double fieldRelAngle = Math.atan2(
vt.getY() - turretXY.getY(),
vt.getX() - turretXY.getX());
// Newton step: f(t) = LUT(d(t)) - t = 0
double f = newTof - tGuess;
double fPrime = dPrime - 1.0;
nextTof = tGuess - f / fPrime;
if (abs(nextTof - tGuess) < tol) break;
Logger.recordOutput("SOTM/TOF", t);
Logger.recordOutput("SOTM/ExitVel", v);
return new MovingShotSolution(
v, theta, fromRadians(rel), vt, t);
fj
farhan jamil
.
writing
projects
connect
the full log —
writing
Build logs, technical write-ups, and the occasional postmortem.
A GTSAM pose estimator for the field
WRITEUP
mar '26
~ 12 min
pose error, 1σ
±2.1 cm