Battery Life Estimator (UAV) — Lean, Calibrate-and-Go

Predict total and remaining flight time for your UAV from a few past flights. Simple, explainable, and fast to calibrate.

Battery Life Estimator (UAV) — Lean, Calibrate-and-Go
Photo by Iewek Gnos / Unsplash

Lean, calibrate-and-go endurance modeling for multirotors or fixed-wing UAVs.

Start with 5–10 flights, fit a tiny model, and get total and remaining flight time estimates in minutes.

⚡️ Why this exists: Operators need a quick, explainable estimate—not a black box. This MVP is deliberately small and extensible.

What it does

  • Calibrate from a CSV of past flights (payload, speed, wind, flight time)
  • Estimate total flight time for new payload/speed/wind conditions
  • Estimate remaining time using current LiPo per-cell voltage → SOC
  • Explainable coefficients you can inspect, version, and compare

How it works (MVP model)

We model the inverse of flight time (minutes⁻¹) as a linear function:

  • Headwind is positive (increases airspeed/power); tailwind is negative.
  • Remaining time is computed as:

using a conservative LiPo voltage→SOC curve.

Good enough when airframe + mission profile are consistent. You can extend later (hover ratio, density altitude, prop/disk loading, battery aging, interactions).

Quick start

1) Prepare your CSV

Include at least 5–10 lines like:

flight_time_min payload_kg ground_speed_mps headwind_mps
18.5 0.2 8.0 0.0
16.2 0.4 9.0 1.0
14.8 0.5 10.0 2.0

Columns (required):

  • flight_time_min — total flight time (minutes)
  • payload_kg — payload mass in kilograms
  • ground_speed_mps — ground speed (m/s) during steady cruise
  • headwind_mps — positive=headwindnegative=tailwind (m/s)
Tip: Use the steady-cruise portion or mission average. Keep logs consistent across flights.

2) Calibrate the model

python battery_life_estimator.py calibrate   --csv example_flights.csv   --out model.json

Outputs:

  • Coefficients: b0, b1, b2
  • Fit metrics: MAE (min), MAPE (%)
  • Saved model: model.json

3) Estimate total flight time

python battery_life_estimator.py estimate-total   --model model.json   --payload-kg 0.6   --ground-speed-mps 10   --headwind-mps 2

4) Estimate remaining time (with voltage)

python battery_life_estimator.py estimate-remaining   --model model.json   --payload-kg 0.6   --ground-speed-mps 10   --headwind-mps 2   --voltage-per-cell 3.85

LiPo per-cell Voltage → SOC (conservative lookup)

V/cell ~SOC
4.20 100%
4.10 90%
4.00 80%
3.95 70%
3.90 60%
3.85 50%
3.80 40%
3.75 32%
3.70 26%
3.65 20%
3.60 14%
3.55 8%
3.50 4%
3.45 2%
3.40 1%
3.35 0.5%
3.30 0%
⚠️ Under load, measured voltage sags. Choose a conservative landing threshold (many operators target ~3.5–3.6 V/cell under load). Adjust the curve to match your packs.

When is the MVP “good enough”?

  • Your MAE ≤ ~1.5–2.0 min on validation flights of ~15–25 min
  • Missions are similar (airframe, props, weather range, and throttle profile)
  • You need fasttransparent estimates to aid planning

If errors are larger or conditions vary widely, consider v2 features (below).

Sensible v2 upgrades (when ready)

  • Hover ratio (time near hover/throttle band) — biggest gain for multirotors
  • Density altitude / air density (from temp & pressure) — seasonal & elevation shifts
  • Prop/disk loading (airframe/prop changes) — robustness across configurations
  • Battery aging/sag (IR or sag proxy) — stabilize estimates across pack age
  • Light non-linear/interaction terms + Ridge (L2) — polish without overfit
Keep it lean: add one or two features only when metrics tell you to.

Calibration tips

  • Use consistent cruise segments across flights
  • Mix a few payloads and wind conditions to avoid collinearity
  • Keep an out-of-sample subset (or use simple K-fold) to validate MAE/MAPE
  • Re-calibrate after major changes (new props, airframe, or season)

CLI Reference

calibrate
  --csv <path.csv>
  --out <model.json>

estimate-total
  --model <model.json>
  --payload-kg <float>
  --ground-speed-mps <float>
  --headwind-mps <float>

estimate-remaining
  --model <model.json>
  --payload-kg <float>
  --ground-speed-mps <float>
  --headwind-mps <float>
  --voltage-per-cell <float>

Design principles

  • Explainable: linear on inverse time; inspect coefficients directly
  • Small data friendly: works with 5–10 quality flights
  • Deterministic: no randomness; same inputs → same outputs
  • Extensible: drop-in features when metrics require

FAQ

  • Does this handle hover-heavy missions?
    The MVP targets steady cruise. If you hover a lot (inspections, photogrammetry), add hover_ratio in v2.
  • What about temperature or altitude?
    If errors drift with seasons or elevation, add air density/density altitude.
  • Multirotor vs fixed-wing?
    Works for both as a first-order model. Fixed-wing may benefit from a throttle% or aerodynamic term later.
  • How often should I recalibrate?
    When coefficients or MAE/MAPE drift after hardware/season changes—or every few months as a routine.

Safety & operational notes

  • Always maintain conservative reserves; this is a planning aid, not a hard guarantee.
  • Validate on your airframe + packs before mission-critical use.
  • Use pack-specific thresholds if aging varies across your fleet.

Roadmap

  • v0.2: helpers for density altitude & hover ratio extraction
  • v0.3: Ridge option with 1–2 interactions
  • v0.4: pack aging proxy (IR/sag) and per-pack calibration

License

MIT — free to use, modify, and embed.

Contact

Questions or ideas? Open an issue or propose a PR in the repo.
Happy (and safe) flying! ✈️