September 21, 2017

Cannonball Tradeoffs with GP

At one point when I was driving around this summer I got curious about whether there were any records for roadtrips. After looking up 'longest roadtrip', I got interested in the speed side of things, and stumbled across the world of road rallies, particularly Ed Bolian's 2013 28:50 drive from New York to LA. This drive in particular is known as the Cannonball Run, and is one of the most famous road rally records around. The whole endeavour is fascinating, from the horde of after-market electronics in the dash (rivalling a small glass-panel aircraft), to the use of scouting vehicles on the ground and in the air on some attempts. If you haven't heard of this stuff before, check out the video below before reading on to get the general idea:

One thing that stood out to me was the trade-off inherent in the record in terms of car selection, driving speed, and fuel economy. For a point to point record, the thing that matters is average speed, not just speed when moving. The obvious strategy would be to use something with a tremendous amount of power and speed (Ferrari, Porsche, Lamborghini, etc), though this doesn't actually turn out to be optimal in practice. Super-cars are easily recognizable by police, as there aren't many of them on the road, and they get terrible gas mileage, meaning that any top-speed benefits are wiped out by more time-consuming gas stops.

Using geometric programs (GPs), I thought it would be neat to look at the tradeoffs in how fuel efficiency, tank size and driving speed affect the overall time for the trip. I wrote a simple model to reflect this:

Let's start out by looking at Alex Roy's E39 M-5 case for his 2006 trip at 32:04. Alex Roy was the previous record holder, and drove this car dressed up as a foreign police car, with friends in a private plane along for the ride spotting from the air. The math is pretty straightforward, as it is just a distance - velocity thing. The only tricky part is working out what the mpg-speed relationship is, though Rhett Allain over at Wired has written something decent about that. I just used his mpg = mpg0 * (v0^2/v^2) relation, which seems about right from my experience, if not a little pessimistic.

Here's my basic GP model:

from gpkit import Model, Variable  
t_total = Variable('t_total','hour','total time en-route')  
d = Variable('d',2800,'mile','Total distance')  
V = Variable('V',48,'gallon','Total tank volume')  
v = Variable('v','mph','cruise speed')  
mpg = Variable('mpg','mile/gallon','Fuel mileage')  
v_ref = Variable('v_ref',65,'mph','Reference speed')  
mpg_ref = Variable('mpg_ref',21,'mile/gallon')  
n_stops = Variable('n_stops',5,'-','number of fuel stops')  
t_refuel = Variable('t_refuel',15,'min','time to refuel')  
speed_lim = Variable('speed_lim',186,'mph')  
fuel_cost = Variable('fuel_cost',2.6,'1/gallon','fuel cost')  
cost = Variable('cost','-','cost of fuel (USD)')  
t_stopped_frac = Variable('t_stopped_frac','-')  
R_tank = Variable('R_tank','mile')  
R_tank_lim = Variable('R_tank_lim',0,'mile')  
constraints = []

constraints += [  
    t_total >= d/v + n_stops*t_refuel,
    n_stops == (d/mpg)/V,
    R_tank == mpg*V,
    R_tank >= R_tank_lim,
    mpg == mpg_ref*((v_ref**2)/(v**2)),
    v <= speed_lim,
    cost == fuel_cost*V*n_stops,
    t_stopped_frac == n_stops*t_refuel/t_total
]

objective = t_total  
m = Model(objective,constraints)  
sol = m.solve()  
print sol.table()  

From this article, I found the reserve fuel tank on Roy's car was 20 gallons, and the internal one I found to be 18 gallon here, giving a total of 48 gallons. I'm pretty sure the model year of the M5 he used was an '03, which means that it gets up to 21 MPG on the highway according to the EPA (EPA test is an average of 48.5 mph, but I take v_ref as 65 as this is what forums suggest). From the book I'm reading on his attempt, it was unrestricted, which meant in theory it could maybe touch up to 186 mph. I got the max fueling stop time of 15 minutes from some of Bolian's writing.

Running the code with these numbers gave the result that the optimal speed is almost as fast as possible, at 159.8 mph, a ridiculous number. This is 4 mph over what is limited, and produces a whopping mpg of 1.6ish, which makes it seem like this is well past reasonable assumptions of where you could actually run the engine at. You can only get a reasonable result if you limit the number of stops to 5, as they run away towards 35, meaning only 80 miles per tank, and a third of the drive is spent stopped, fueling up.

If we bring the number of fuel stops down to 4, the numbers look a lot more familiar, producing an optimal cruise of 87 mph for a record prediction of 33.36 hrs.

Bolian's car at EPA mpg of 22 highway doesn't do much better than the M5, but his was fitted with 67 gallons of fuel capacity thanks to two external tanks. He also drove a little further, another 13 miles to make 2813 miles cross country. For these numbers I got 28 hrs flat as the record time, but it's worth noting that the mpg was pretty off what Bolian reported, I got 8.3 whereas he reported 13.

That's ultimately the biggest uncertainty in all of this, as Allain's article does not appear to correctly capture the variation of mpg with speed. There's plenty of real data out there that doesn't line up well at all with just drag alone, such as this article from Automatic.

It's pretty clear that the best strategy for Cannonball is to just drive as fast as possible in a reasonably fuel efficient car, but I'm sure at some point that geography would dictate a minimum R_tank (maybe around 70-100 miles, though this would still be ridiculous). This is what they knew back in the 80s, when the cars that won were Ferraris, but it's not true now, as stealth is key and outweighs the overall speed benefits.

This is what I really love about GP modelling stuff, that you can quickly explore a problem space to understand what's going on.

  • LinkedIn
  • Tumblr
  • Reddit
  • Google+
  • Pinterest
  • Pocket
Comments powered by Disqus