Inspiration

An electric truck depot has a scheduling problem that gets worse as it grows. Our simulated depot has 50 trucks and only 11 chargers, split into three pools because vans and tractors need different plugs. Electricity price swings from $0.09 to $0.32 per kWh through the day, solar only exists at midday, and every truck has to leave on time with enough energy for its own trip. Charging everyone on arrival is simple, but it is expensive, spikes the demand charge, and leaves batteries sitting nearly full for hours.

What it does

Fleet Charge Controller decides which truck takes which bay and when, then charges each truck at the cheapest and gentlest rate that still gets it out on time with exactly the energy its trip needs.

  • Trip energy from physics. Distance, cargo weight, terrain and temperature feed a model calibrated to each truck's published range:

$$E_{trip} = c \cdot f_{cold} \cdot (E_{prop} + E_{stop} + E_{climb}) + E_{aux}$$

The required energy adds a 15 % margin and a 10 % reserve:

$$E_{req} = 1.15\,E_{trip} + 0.10\,C_{plan}$$

  • Two-stage optimiser. A per-pool MILP assigns bays, including plug-in and unplug time. An LP then sets each truck's power inside its window, against price net of solar, the demand charge, the grid limit and a battery-health term.
  • Edge loop. A one-minute guard adds power if a truck falls behind, handling noisy charge and health readings.
  • Nemotron for the humans. Dispatchers type notes such as "Truck 5 is carrying 1.6 tonnes. Truck 30 route is now 280 km." and Nemotron turns them into validated actions. Tavily supplies live weather. Nemotron also explains any decision in plain language.
  • Dispatcher console. One-click scenarios (grid curtailment, cold snap, longer routes) and recommended fixes, with numbers from the same models.

The language models never choose a bay or a charge level. Deterministic optimisation does, so deadlines never depend on a model.

Results

Over 8 simulated depot days against first come, first served:

First come Smart
Cost per day $1,804 $1,095 (-39 %)
Peak power 872 kW 635 kW
Missed departures 0 0
Average charge rate 0.29 C 0.23 C
Truck-hours above 80 % charge 241 127

On cold days with charger faults the saving is 33 %, but both policies miss about 0.5 departures per day. That is the main weakness we found.

How we built it

Python, NumPy, SciPy (HiGHS) and a standard-library web server with a vanilla JavaScript yard view where trailers fill as batteries charge. Nemotron Nano and Super run on Nebius Token Factory, and every model call has an offline fallback. The benchmark is containerised for Nebius Serverless Jobs.

Challenges

  • A single joint MILP for all trucks and bays did not find a solution quickly (a 99.6 % gap after 90 s), so we split it into two stages that solve in about 0.6 s.
  • Reasoning tokens from Nemotron truncated short answers, so we raised token limits and fall back to templates when a response is cut off.
  • A weather extractor returned 0 °C when Tavily had no data, which inflated energy needs by 16 %. It now returns null and the default is 15 °C.

What we learned

Keep the language model out of the control loop and put it where people meet the system: reading messy notes and explaining decisions. The data is synthetic, so the numbers show the scheduler's behaviour, not a real depot's costs.

What's next

A robust planner that needs less margin, real charger protocols, and modelling truck swaps after a charger fault.

Built With

Share this project:

Updates

Submission history