Skip to main content
emobility.academy
B.Tech / BEEnergy managementBeginner About 4 weeksMATLAB & Simulink

Remaining Range Estimation Using Driving History

Build a MATLAB and Simulink remaining-range estimator that combines battery state of charge with a rolling average of recent energy consumption in Wh/km. It is tested on IDC, MIDC and WLTP segments and compared with a naive fixed-efficiency estimate.

Tools: MATLAB · Simulink

Remaining Range Estimation Using Driving History: Electric scooter wiring and power-flow trainer board at DIYguru
Representative photo from DIYguru's EV lab, not of this specific project.

The problem

Range anxiety is driven as much by poor range predictions as by small batteries. A 'guess-o-meter' that uses one fixed Wh/km figure overestimates range after a gentle drive and then drops sharply on a highway or a hill. Using recent driving history makes the estimate more honest, but the averaging window, weighting and reserve logic all change how stable and how accurate it is.

Objectives

  • Build a simple longitudinal EV model that produces battery power and SOC over a drive cycle.
  • Implement fixed, moving-window and exponentially weighted range estimators.
  • Test the estimators on concatenated city, suburban and highway segments.
  • Measure estimate error against true remaining range and estimate stability.
  • Recommend a window length and reserve margin with evidence.

What you need

Tools and toolboxes

  • MATLAB — Drive-cycle preparation, estimator scripts, parameter sweeps with sim() and result plots.
  • Simulink — Longitudinal vehicle model, battery energy integration and the estimator subsystem running at a fixed step.
  • Stateflow (optional) — Low-range warning and reserve-mode logic; basic Simulink Switch and Relay blocks are an alternative.

Software

  • MATLAB R2023b or later
  • Simulink
  • Excel/CSV files for IDC, MIDC and WLTP speed traces

Extra parts and data

None beyond the software above.

Key concepts

Energy consumption in Wh/km
Battery energy drawn per kilometre, including regeneration. It varies strongly with speed, acceleration, gradient and auxiliary load, which is why a fixed value predicts range poorly.
Moving-window average
Consumption computed over the last N kilometres. A short window reacts quickly but jumps around; a long one is stable but slow to notice a change in driving.
Exponentially weighted average
A first-order filter on consumption, c_k = α·c_new + (1 − α)·c_k−1, which needs only one stored value and gives recent driving more weight.
Usable energy and reserve
Range is computed from usable energy above a minimum SOC, not from nameplate capacity, and a reserve keeps the display from promising the last few kilometres.

Step-by-step guide

  1. 1

    Define the vehicle and the test

    Choose example parameters for a two-wheeler: 150 kg vehicle plus rider, Cd·A of 0.6 m², Crr of 0.012, wheel radius 0.27 m and a 3 kWh, 60 V pack with 90 per cent usable energy. Write them in a parameter script (params.m) so every run uses the same values. Define the metrics: range error in km against the true remaining range, and estimate stability as the standard deviation of the estimate's change per kilometre.

    Checkpoint: A parameter script that runs without error and a one-page test plan listing metrics and drive segments.

  2. 2

    Prepare drive-cycle data

    Import IDC, MIDC and WLTP speed traces from CSV into timeseries objects with time in seconds and speed in m/s. Build a long test route by concatenating segments, for example five IDC loops, one WLTP and three more IDC loops, so driving style changes mid-trip. Resample to 0.1 s with interp1 and check for duplicate time stamps. Plot speed against time and compute distance with cumtrapz.

    Checkpoint: A speed-time plot of the concatenated route and a distance figure that matches the sum of the segment distances within 1 per cent.

  3. 3

    Build the road-load model

    In Simulink, feed the speed trace through a From Workspace block and compute tractive force F = m·g·Crr·cosθ + ½·ρ·Cd·A·v² + m·g·sinθ + m·a, with acceleration from a Derivative block or, better, from a filtered difference. Multiply by speed for wheel power. Use a fixed-step solver (ode4 or discrete) at 0.1 s so the estimator later runs at a known rate.

    Checkpoint: Wheel power peaks in the range of a few kilowatts during accelerations and goes negative during braking.

  4. 4

    Add drivetrain and battery energy

    Convert wheel power to battery power with a constant drivetrain efficiency of about 85 per cent when motoring and a regeneration efficiency of about 60 per cent with a cap on regenerative power. Add a constant 50 W auxiliary load. Integrate battery power to energy with a Discrete-Time Integrator and compute SOC from usable energy. A full battery model is not needed here; an energy-bucket model keeps attention on the estimator.

    Checkpoint: Consumption on IDC alone falls in a plausible range for a scooter, roughly 25 to 45 Wh/km with these example values.

  5. 5

    Compute true remaining range

    Run the route repeatedly until usable energy is exhausted and record the distance at which it ends. True remaining range at any moment is that end distance minus the distance travelled so far. Store it as a logged signal so every estimator can be compared with the same reference. Note that the reference depends on the future route, which is exactly what the estimator cannot know.

    Checkpoint: A true-range curve that falls from its starting value to zero at the end of the run, with slope changes where the driving style changes.

  6. 6

    Implement the estimators

    Build a subsystem with three estimators running on the same inputs. The baseline uses a fixed 35 Wh/km. The moving-window estimator stores energy and distance every 100 m in a buffer of N slots (a MATLAB Function block or Delay blocks) and divides their sums. The exponential estimator updates on every 100 m tick with weight α. Each outputs range = (usable energy − reserve) / consumption.

    Checkpoint: All three estimates agree at the start, when the history buffers are seeded with the fixed value.

  7. 7

    Verify each estimator in isolation

    Feed a constant-consumption test where battery power is proportional to speed. All estimators must then give the same range, and the range must fall one kilometre for every kilometre driven. Then step the consumption up by 50 per cent and check that the moving-window estimate settles after exactly N slots and the exponential one follows its expected time constant. Write these as a short MATLAB test script with assert statements.

    Checkpoint: The test script passes, including the exact settling distance of the moving-window estimator.

  8. 8

    Run the full route and log results

    Run the concatenated route with logging enabled and inspect battery power, consumption estimates and range estimates in the Simulation Data Inspector. Look at the transition from city to WLTP driving: the fixed estimator stays optimistic, while the history-based estimators drop. Export logged data with Simulink.SimulationOutput and compute range error and stability for each estimator. Mark the segment boundaries on every plot so readers can see each estimator's response to the change, and save the logged run as a MAT-file for the later sweeps.

    Checkpoint: A three-line range plot against true range, with the history-based estimators visibly closer after the driving-style change.

  9. 9

    Sweep window length and weighting

    Use a script that builds an array of Simulink.SimulationInput objects for window lengths of 2, 5, 10 and 20 km and α values that give matching effective windows, then runs them with sim(). Plot RMS range error against stability for each setting. This trade-off curve is the main result: there is no setting that is best on both, so the choice depends on what the display should prioritise.

    Checkpoint: A trade-off plot with one point per setting and a clearly marked recommended setting.

  10. 10

    Add reserve logic and report

    Add a reserve of a few per cent of usable energy and a low-range warning below a set distance, with hysteresis so the warning does not flicker. Re-run the route and show the warning behaviour. In the report, present the model, estimator equations, verification tests, trade-off plot and recommendation, and state the limitations: energy-bucket battery, flat road unless gradient is added, and no temperature effect.

    Checkpoint: A report with the trade-off plot, a recommended setting and a warning that triggers once without chattering.

Testing & validation

  • Constant-consumption test: all estimators lose one kilometre of range per kilometre driven.
  • Step-change test: settling distance matches the window length or time constant.
  • RMS and maximum range error against true remaining range on the concatenated route.
  • Stability metric for each estimator and setting.
  • Warning logic triggers once with hysteresis and no chattering.

Expected results

A Simulink model and scripts that estimate remaining range from driving history, with a measured accuracy-versus-stability trade-off for several window settings and a recommended configuration compared with a fixed-efficiency baseline.

Take it further

  • Add a gradient profile and see how hills affect each estimator.
  • Add temperature-dependent auxiliary load, for example heating or cooling.
  • Use a speed-binned consumption table instead of one average figure.
  • Replace the energy bucket with an equivalent-circuit battery model and compare.

Viva and review questions

Why not use the nameplate battery capacity for range?

Part of the capacity is kept unused to protect the cell and some energy is lost in the pack's resistance, so only usable energy above the minimum SOC can drive the vehicle.

What is the trade-off in choosing the window length?

A short window reacts quickly to a change in driving but makes the displayed range jump; a long window is stable but stays wrong for longer after the driving changes.

Why did you seed the history buffers?

At the start of a trip there is no history, so the buffers are filled with a typical consumption value to avoid dividing by zero or showing a wild first estimate.

Why a fixed-step solver?

The estimator updates on fixed distance ticks and would run as fixed-rate code in an ECU, so a fixed step makes the simulated behaviour match the intended implementation.

Learn it at DIYguru

These DIYguru courses and programmes teach what this project needs.

Related EV projects

All 100 MATLAB & Simulink EV projects