Skip to content

Instantly share code, notes, and snippets.

@tdunning
Last active July 27, 2020 23:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tdunning/cb0c3e70ceebb23c286ee1b4fbb19c98 to your computer and use it in GitHub Desktop.
Save tdunning/cb0c3e70ceebb23c286ee1b4fbb19c98 to your computer and use it in GitHub Desktop.
### This code builds a simple physical model of the range of an 85kWh Tesla Model S and
### compares it to real data. The data here is digitized from
### https://www.tesla.com/blog/model-s-efficiency-and-range
### The model here accounts for aerodynamic drag, viscous drag, constant
### friction and constant power drain
### First the digitized data
x = read.csv(text="v,range
10.22976354700292, 393.9005561997566
10.838964486991967, 401.4421063918873
11.384646845560354, 408.54972092015214
11.930329204128743, 415.05307850205776
12.488579410357904, 421.4698583552047
13.20166323529072, 427.7475379812978
13.785841703811023, 433.0491331447459
14.445087586737559, 438.2301224270771
15.043152152061941, 441.2268563433788
15.734707270126698, 445.58155724172207
16.350645029357327, 448.5322583789715
16.985830843563917, 450.71421210604836
17.621016657770507, 452.61996915881167
18.256202471977097, 454.1114312001047
18.891388286183687, 454.80192288588853
19.526574100390274, 456.0448079202994
20.161759914596864, 456.4314832643383
20.796945728803454, 456.5695816014951
21.432131543010044, 456.486722599201
22.067317357216634, 455.93432925057397
22.702503171423224, 454.9676408904766
23.337688985629814, 454.3323885395555
23.972874799836404, 453.61427718634036
24.60806061404299, 452.3161528170668
25.219186359529633, 450.4679367381188
25.87843224245617, 449.22275006475536
26.51361805666276, 447.89700602805044
27.14880387086935, 445.57695396381683
27.78398968507594, 443.45023957160265
28.41917549928253, 441.1854268422318
29.054361313489117, 438.9758534477236
29.70879518267167, 436.3404768469821
30.324732941902298, 434.05955264494287
30.959918756108888, 431.325205569239
31.595104570315478, 428.7289568306919
32.230290384522064, 426.1050884247134
32.86547619872866, 423.4812200187349
33.4651271422104, 420.32195498254873
34.13584782714184, 417.5429915209942
34.793242935551454, 413.9885527815594
35.40621945555502, 411.4390450186653
36.041405269761604, 408.40088160121655
36.67659108396819, 404.9484231722975
37.311776898174784, 402.1035974268682
37.94696271238137, 398.9825750071254
38.572524499099984, 395.78099522404113
39.21733434079455, 392.4367138258949
39.85696201384175, 388.7016849532551
40.48770596920773, 385.91847231209573
41.122891783414325, 382.4660138831767
41.734017528900964, 378.89387022872177
42.3932634118275, 375.8925330345148
43.04769728101005, 372.48840902360064
43.66363504024068, 369.31905218585297
44.29882085444727, 365.8113544220712
44.93400666865386, 362.57985333260297
45.56919248286045, 359.210253905978
46.21400232455501, 355.2974676865364
46.839564111273624, 352.44343538529665
47.47474992548022, 349.1843146283971
48.10031171219883, 345.904479120924
48.7451215538934, 342.41749610771575
49.380307368099984, 339.1031360159535
50.002167605784756, 335.4403431965957
50.650678996513165, 332.4467961649976
51.2666167557438, 328.7388558123385
51.921050624926345, 325.90093498376706
52.55623643913293, 322.89039123374965
53.191422253339525, 319.41031313739927
53.82660806754611, 316.0683333782056
54.461793881752705, 312.9473109584628
55.07223219670449, 309.13185118616025
55.732165510165885, 306.4290694446637
56.25711246405562, 303.11470935290134
56.887048808723314, 300.7670376212364
57.52223462292991, 297.8945922083758
58.157420437136494, 294.6630911189076
58.79260625134309, 291.5420686991647
59.427792065549674, 288.3658069445592
60.05335385226828, 285.09057471499136
60.698163693962854, 282.26186044223033
61.33334950816944, 278.9475003504681
61.968535322376034, 276.3236319444896
62.60372113658262, 273.45118653162893
63.238906950789215, 270.6892197884937
63.87409276499581, 267.48533836645686
64.50927857920239, 264.72337162332155
65.11337138152474, 261.54286068911125
65.77965020761557, 259.00610046503164
66.41483602182215, 255.99555671501423
67.05002183602875, 253.1783506370163
67.68520765023534, 250.60972156590054
68.32039346444193, 248.1239514970788
68.95557927864851, 245.44484375623767
69.59076509285511, 242.6276376782397
70.20189083834175, 239.72066768108988
70.8611367212683, 237.35228119885141
71.49632253547487, 234.70079312544158
72.13150834968147, 232.18740338918855
72.76669416388806, 228.8845514921893
73.40187997809464, 227.0777649143883
74.03706579230123, 224.64723418042934
74.71222833607327, 221.85977235966516
75.28337735199446, 219.69410715440682
75.942623234921, 217.38326164598362
76.5778090491276, 215.00797024688734
77.21299486333419, 212.57743951292832
77.84818067754077, 210.36786611842018
78.48336649174736, 208.07543372161786
79.11855230595395, 205.58966365279622
79.70124342477156, 203.2972312559939")
### Next build some training data for the model. Oversample the low range
### to ensure fidelity
data = data.frame(v=c(seq(11,19,1), seq(20,40,2), 50, 55, 60))
### Add power terms
data$v2 = data$v^2
data$v1 = 1/data$v
data$y = 85/approx(x$v, x$range, data$v)$y
### The model is a linear combination
m = lm(y ~ v + v1 + v2, data)
### Now build out data to plot
newx = data.frame(v=c(seq(11,19,1), seq(20,40,2), seq(50,80,5)))
newx$v2 = newx$v^2
newx$v1 = 1/newx$v
newy = 85/predict(m, newdata=newx)
### And plot it
plot(range ~ v, x)
lines(newx$v, newy, col='red', lwd=3)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment