Closed mlangsdorf closed 5 years ago
Looking at #19275 may be of some help.
19275 has a lot of examples of things not to do, actually.
Quick check of units, without delving into the physics.
~
slowdown ( m/s )
~
Slowdown is deceleration, it should have units m/s²
slowdown = [ F_(aero_drag) + F_(roll_resist) ] / veh_mass
(m/s²) (kg·m/s²) (kg·m/s²) (kg)
F_(aero_drag) = 0.5 * AirDensity * C_(aero_drag) * FrontArea * v²
(kg·m/s²) (kg/m³) (m²) (m/s)²
So far, so good.
But then
F_(roll_resist) = veh_mass * num_tires * C_(tire) * v
(kg·m/s²) kg (m/s)
The units don't match up. (?!)
Then we have
acceleration = F at wheel / mass
(m/s²) (kg·m/s²) (kg)
F at wheel = [ (engine power * gear ratio) / (wheelradius * engine rotation rate) ]
(kg·m/s²) (kg·m²/s³) (m) (1/s)
speed = engine rotation rate * wheel radius / gear ratio
(m/s) (1/s) (m)
Thus:
acceleration = engine power / current speed / mass
(m/s²) (kg·m²/s³) (m/s) (kg)
This checks out.
F_(rolling resistance) = veh_mass (kg) num_times C(tire) * v (m/s) C(tire) isn't dimensionless, it's in units of Hz (1/s) which is weird but what can you do. Rolling resistance is weird stuff, and I'm abstracting a bunch of complicated stuff (wheel, axle, and motor inertia, among others) into it. It also has a fairly small effect on most vehicles: dropping it to 0 doesn't change the speed of an electric bike, and raises the cruise and top speeds of a sports car by about 20 mph.
19275 has a lot of examples of things not to do, actually.
I was looking at
A more detailed model could take account of gear ratios and transmission losses
which reminded me of 19275 because I personally thought the gearing was awesome when playing with it. It also has unfinished code which is probably what you were looking at.
I liked gearing from 19275, but the overall approach was bad, the hostility to the players was bad, the single huge PR that demonstrably could have been broken up into multiple smaller commits was bad, the decision to arbitrarily turn int values into floats was bad, breaking multi-engine vehicles was bad, and the code is stale and doesn't correspond to current CDDA very well. I look at it, but mostly as a reminder of things not to do.
So I'm currently poking around with modeling gear ratios correctly, and it's fairly complicated. The engine no longer delivers constant power, but some amount of torque (that should vary with RPM but I'm not going there) so the actual power is linearly dependent with RPM. I'm sure it's not worth it for this pass of the code: step 1 is getting horse power to deliver reasonable amounts of speed for a reasonable amount of vehicle mass. This version at least lets small scooters use 10HP motors and get reasonable performance, this is step 1.
Rolling resistance is weird stuff, and I'm abstracting a bunch of complicated stuff (wheel, axle, and motor inertia, among others) into it.
A. Did you mean "friction" rather than "inertia"? Inertia = resistance to change in velocity. I only find sources with rolling resistance equations dependent on velocity, not on acceleration.
B. "motor": anything to do with inefficiencies e.g. friction losses in the engine should be abstracted as part of engine efficiency rather than as part of rolling resistance. "axle": We don't actually require player to explicitly build a powertrain, so this could be handwaved either into engine or wheel side of things, or just ignored altogether.
F_(rolling resistance) = veh_mass (kg) num_tires C(tire) * v (m/s) C(tire) isn't dimensionless, it's in units of Hz (1/s) which is weird but what can you do.
I still don't think this is right; here are a couple questions that might help diagnose:
1 Is this derived solely based on [MarcoM], or is there some other source for this?
2
(roughly 0.002 for small tires to 0.0075 for armored tires)
What are these values based on, are they C_rr from here?
In reverse: C_rr is partially derived from https://www.engineeringtoolbox.com/rolling-friction-resistance-d_1303.html, partially derived from MarcoM's stuff, and partially the synthesis of a lot of reading up on the subject for realizing that it's too complicated for an accurate solution so I would prefer to go with a simple solution.
I can't find an independent confirmation of MarcoM's F_(rolling resistance) = Crr V, nor where he got his approximation that Crr is net Cair drag 30. The speed numbers look roughly correct with that formula, but I'd be happy to get another, better set of values.
Friction in general is proportional to mass gravity acceleration some constant. I'm basically merging the (constant) gravity acceleration into the constant, then dividing out velocity because the rolling resistance does very with speed to some extend. So if you like: F(rolling resistance) = mass (kg) * accel(gravity) m/s^2 c_rr k speed (m/s) where crr is dimensionless, k is 0.1s/m, and Crr is accel(gravity) c_rr * k. Where did k come from? Dunno, it makes the dimension analysis come out nice.
First, real quick re: considering rolling resistance for each wheel separately, then combining their effects.
Rolling resistance of each wheel depends only on the share of vehicle weight it is supporting, not total weight.
We simply sum up the contribution from each wheel, because rolling resistance a scalar, not a force applied at each wheel (more elaboration embedded below).
I can't find an independent confirmation of MarcoM's F_(rolling resistance) = Crr V, nor where he got his approximation that Crr is net Cair drag 30.
Ok so [MarcoM] gives:
F(rr) = - C(rr) × v At approx. 100 km/h (60 mph, 30 m/s) they are equal ([Zuvich]). This means C(rr) must be approximately 30 times the value of C(drag)
And goes on to calculate a concrete example using C_(rr) = 30 × C_(drag)
, but this is accompanied by the admission that:
To be honest, I have my doubts about this last constant [Crr]. I couldn't confirm its value anywhere. Be prepared to finetune this one to get realistic behaviour.
This what really gets me uncomfortable: the source itself is not confident about this; it doesn't agree well with other resources I looked at -- which is why I asked if you had other sources to confirm this.
We can look in [Zuvich] to find the exact snippet cited by MarcoM
Aerodynamic loads only become equal to rolling resistance at 50-60 mph for modern passenger cars
This does provide justification for the magic number "30m/s" for cars only
But there is no validation for choice of pure linear model, which is actually the cornerstone of MarcoM's logic that enabled use of the magic number -- by cross reference v.s. aero drag -C_(drag) × v × |v|
All other sources I looked at start by giving the basic equation for rolling resistance as:
F(rr) = C(rr) × N
N is the normal force, when considering the vehicle as a whole this is simply vehicle weight C_(rr) is dimensionless coefficient of rolling resistance.
P85-86 of [NHTSA 811-154] briefly explains how this came about
ignoring vehicle inputs, the equilibrium (i.e., fully warmed up) rolling resistance of a new radial tire varies primarily with applied load, inflation pressure, and speed. Investigations such as those by Clark et al. during the 1970s indicated that the equilibrium tire rolling resistance of radial passenger tires was not linear with pressure or speed, but did appear linear with load.
This allows rolling resistance to be expressed as an equation analogous to that for friction, but we have to use caution when interpreting it. Unlike friction, rolling resistance is not a force! [NHTSA 811-154] cites several sources when stating that it is the loss of energy (or energy consumed) per unit of distance travelled -- units J/m -- therefore, although dimensionally equivalent to N, it is a scalar with no direction. It also goes on to explain the advantages of having the equation in this form:
The coefficient Cr transforms the “energy per unit distance” measure of Fr into terms of “energy per unit distance and unit load” on the tire.
Thus, C_(rr) is convenient for
calculating the expected rolling resistance of a tire [...] for a “given application” (i.e., for a given vehicle with known wheel corner loads).
but
no simple relationship exists between rolling resistance and pressure or speed that would allow the calculation of similar coefficients for these two inputs.
Going back to [Zuvich], he explains:
Important factors affecting the coefficient of rolling resistance include tire type (radial versus bias ply), temperature, inflation pressure, material, design, slip, velocity, and load. Because of these many inter-related factors, it is virtually impossible to develop a method of considering all these variables.
So, yes, it's complicated. But an important point to take from this is: in most places where a single value of C_(rr) is given, such as in tables ar [enggtoolbox] and [wikipedia], that value encompasses all of this multitide of factors. It's a representative value for C(rr) under whatever particular conditions that people have measured them at -- generally the "typical operating conditions" for that type of wheel/tire, or certain more adverse scenarios (e.g. snow, wet/rough/loose surface). These measured values of C(rr) are really only valid for the (range of) velocities that they were measured at.
This is true even for several tire testing standards -- SAE J1269, ISO 18164 and ISO 28580 all involve tests performed at various predetermined speeds, with no means for extrapolating results to other speeds. They only facilitate comparing efficiency of different tires under some typical road/highway use cases.
These values are not intended to be adapted for / plugged into some model or equation for the purpose of deriving C_(rr) under other, different conditions -- caution required if we do so.
Moving on to more complex formulae, a good place to start is SAE J2452 which unlike other aforementioned standards actually measures rolling resistance over the course of a coastdown (i.e. neutral gear, no brakes) starting at 115km/h and slowing down to 15km/h. The tests results are fed into a model with the formula:
F_(rr) = P^α × N^β × ( A + Bv +Cv² )
where P is tire pressure and N is the normal force
So, a quadratic relationship with velocity. mathworks documentation for their modeling tools gives default values for the coefficients, which gives a rough idea of the proportion of contribution from constant, linear, and quadratic components:
P = 250,000 Pa
α = -0.003
β = 0.97
A = 0.0084
B = 0.00062 s/m
C = 0.00016 s²/m²
Note the comparatively larger constant, speed-independent factor, which is missing from MarcoM.
[enggtoolbox] offers a formula for air filled tires on dry roads that is also quadratic:
C_(rr) = 0.005 + (1 / P) (0.01 + 0.0095 (v/100)² ) (velocity in km/h)
So, ignoring the 0.005 it's roughly α=-1, β=1, A=0.01, B=0, C=0.000012312
These models that vary with pressure and velocity are parabolic curves when plotting C_(rr) vs vehicle speed, with y-intercept > 0 and minimum at, or left of Y-axis. ([enggtoolbox] has a nice graph).
And revisiting [Zuvich], he offers that
there are several good, empirical estimates. [One such estimate] treats velocity as the significant variable, and provides linear speed dependence: C_(rr) = 0.01 ( 1 + V/100 ) where V = speed (mph)
Or, in metric and coerced into the same form as SAE J2452: F_(rr) = N × ( 0.01 + 0.0002237v ) α=0, β=1, A=0.01, B=0.0002237, C=0
Contrast this with MarcoM's pure linear model without any velocity-independent component. It is a straight line from the origin, intersecting the Cdrag curve (a parabola with min at origin) at v = 60mph -- so his model is likely to severely underestimate C(rr) at low speeds and slightly overestimate it at higher speeds. The net effect of this is counter to the expected behavior (rolling resistance dominates at low speeds, aero drag dominates at high speeds) which may explain why he found a need to "finetune" his C_(rr).
Where to go from here? Some options:
If it has a "fairly small effect" anyway, it might not even be worth the effort to model it accurately, etc. Advantage: no implementation! Balance note: compared to "full realism", slight buff of all vehicles, impact mainly at low speeds
Obtain or extrapolate "typical" values for various wheels from tables on wikipedia/enggtoolbox Advantage: simple implementation; easy to obtain/derive values Disadvantage: unrealistic: does not vary with vehicle speed Balance note: will be accurate at some "typical" speed, far too high at slower speeds, too low when faster
Use "typical" C_(rr) values for wheels as a reference point, draw line from origin through ref point Advantage: reduced implementation complexity Disadvantage / balance: already discussed
Use "typical" C_(rr) values for wheels as a reference point (x,y) Draw line throught ref point with gradient k(y/x) where 0<k<1 so that y-intercept > 0 Advantage: reduced implementation complexity, acceptable accuracy Disadvantage: some effort needed to derive json params
Fix the ratio between coefficients A:B, store only one value in json
Each type of wheel gets json parameters for coefficients A,B,C Advantage: most realistic Disadvantage: complex implementation. sourcing/setting values for the params will be hard.
Fix the ratio between coefficients A:B:C, store only one value in json
I think the Zuvich variant, with coefficients A and B in fixed proportion, seems most promising -- pretty much same code complexity as MarcoM with better accuracy.
Thanks for all the additional research! So what you're suggesting is:
F_rolling = mass_veh * accel_g * C_rr_true * ( 44.7 + v ) * 0.0002237 = C_rr_net * ( 44.7 + v )
where C_rr_net = mass_veh * accel_g * C_rr_true * 0.002237
(technically C_rr_net = sum_all( C_rr-tire × tire's share of mass × accel_g ) but
approximate as equal mass per wheel for the rough spreadsheet calculations)
(add a fudge factor of 1.25*wheel count/(4+.25+wheel count) to account for extra
inertial mass of additional wheels; its 5/6 for a bike, 1 for a car, 1.07 for a 6-wheeler,
and ~1.2 for a tank)
F_drag = 1/2 * air_density * C_drag * area_cross * v^2 = C_air_net * v^2
F_wheel = Power_engine / v
Power_engine / v = C_air_net * v^2 + C_rr_net * v + 44.7 * C_rr_net
0 = C_air_net * v^3 + C_rr_net * v^2 + 44.7 * C_rr_net * v - Power_engine
solve for v via the cubic equation, which is gnarlier now that we've got all 4 constants but no big deal.
Since accel_g, C_rr_true, and 0.0002237 are all constant for each tire, we store C_rr_tire in JSON as accel_g C_rr_true 0.0002237 and just multiply it be vehicle mass to get C_rr_net.
New comparison chart for speed, all values in mph because that's what I think in:
Vehicle | CDDA Safe | Top | Newest Cruise | Top | New Cruise | Top | Ratio Newest:New | ||
---|---|---|---|---|---|---|---|---|---|
Electric Scooter (small motor) | 11 | 15 | 54 | 56 | 54 | 56 | 100.00% | ||
Electric Bike (very small motor) | 2 | 3 | 24 | 25 | 25 | 26 | 96.00% | ||
Electric Scooter | 35 | 48 | 93 | 97 | 93 | 97 | 100.00% | ||
Electric Bike (small motor) | 12 | 15 | 52 | 54 | 52 | 54 | 100.00% | ||
Scooter | 21 | 45 | 68 | 80 | 67 | 80 | 101.49% | ||
Motorcycle Sidecar | 32 | 77 | 60 | 72 | 60 | 71 | 100.00% | ||
Superbike | 91 | 194 | 110 | 131 | 109 | 130 | 100.92% | ||
Golf Cart (small motor) | 48 | 78 | 48 | 50 | 46 | 48 | 104.35% | ||
Golf Cart | 48 | 78 | 85 | 88 | 82 | 85 | 103.66% | ||
Hatchback | 64 | 192 | 83 | 100 | 77 | 93 | 107.79% | ||
Electric Car | 159 | 313 | 122 | 127 | 111 | 116 | 109.91% | ||
Solar Car | 58 | 125 | 87 | 91 | 82 | 85 | 106.10% | ||
Car | 63 | 192 | 84 | 102 | 75 | 91 | 112.00% | ||
Sports Car | 314 | 937 | 169 | 203 | 151 | 183 | 111.92% | ||
FBI Car | 167 | 504 | 111 | 133 | 101 | 123 | 109.90% | ||
Cube Van | 75 | 310 | 62 | 75 | 58 | 70 | 106.90% | ||
RV | 71 | 309 | 59 | 71 | 52 | 63 | 113.46% | ||
School Bus | 94 | 309 | 64 | 75 | 58 | 69 | 110.34% | ||
Luxury RV | 77 | 309 | 68 | 81 | 56 | 67 | 121.43% | ||
Flatbed Truck | 85 | 309 | 74 | 90 | 68 | 81 | 108.82% | ||
Armored Car | 138 | 504 | 81 | 98 | 79 | 94 | 102.53% | ||
Humvee | 138 | 504 | 81 | 98 | 80 | 96 | 101.25% | ||
Swat Truck | 76 | 309 | 54 | 66 | 47 | 57 | 114.89% | ||
APC | 70 | 309 | 52 | 64 | 48 | 58 | 108.33% | ||
Military Truck | 105 | 504 | 65 | 78 | 58 | 70 | 112.07% | ||
Semi Truck | 102 | 504 | 62 | 75 | 54 | 65 | 114.81% | ||
Tanks: Mobile Gun System | 69 | 309 | 44 | 56 | 47 | 56 | 93.62% | ||
Tanks: Atomic Mini Tank | 132 | 784 | 75 | 79 | 66 | 69 | 113.64% | ||
Tanks: Light Tank | 93 | 1153 | 69 | 84 | 66 | 79 | 104.55% | ||
Tanks: Main Battle Tank | 60 | 1262 | 59 | 72 | 59 | 71 | 100.00% | ||
Tanks: Light Tank (Turbine) | 93 | 1153 | 67 | 91 | 64 | 85 | 104.69% | ||
Tanks: Main Battle Tank (Turbine) | 111 | 2329 | 70 | 95 | 69 | 91 | 101.45% | ||
Tanks: Stryker ICV | 70 | 309 | 44 | 58 | 60 | 71 | 73.33% | ||
Forgotitdm's Buddy | 247 | 627 | 77 | 80 | 64 | 66 | 120.31% | ||
Kurzedmetals's Buddy Variant | 159 | 313 | 64 | 66 | 52 | 55 | 123.08% | ||
Vastin's DeathMobile Mk1 | 146 | 392 | 60 | 64 | 63 | 66 | 95.24% | ||
Rose's RoseRide | 113 | 392 | 47 | 50 | 60 | 63 | 78.33% | ||
TheMurderUnicorn's Murderizer | 143 | 392 | 69 | 73 | 63 | 66 | 109.52% | ||
Shard's Valhalla's Gate | 192 | 2672 | 46 | 49 | 78 | 82 | 58.97% | ||
TheMurderUnicorn's Puttter | 150 | 309 | 127 | 151 | 125 | 149 | 101.60% | ||
Submarine's Hybrid Humvee II | 97 | 313 | 76 | 79 | 75 | 79 | 101.33% | ||
RbN420's Fancy Truck | 171 | 696 | 62 | 74 | 73 | 84 | 84.93% | ||
Megabike | 314 | 937 | 187 | 222 | 185 | 220 | 101.08% | ||
sDan20's Super Truck | 105 | 504 | 59 | 77 | 69 | 85 | 85.51% | ||
Dialo.Malison's Loot Scooter | 177 | 312 | 127 | 131 | 120 | 125 | 105.83% | ||
Loaded Car | 63 | 192 | 77 | 95 | 68 | 84 | 113.24% | ||
Rose's RoseRide Twin | 113 | 392 | 62 | 65 | 82 | 86 | 75.61% | ||
Shard's Valhalla's Gate (mega) | 192 | 2672 | 60 | 64 | 93 | 97 | 64.52% |
So the new formula has a bunch of advantages:
Disadvantages:
what you're suggesting is: \<snip>
Looks correct.
approximate as equal mass per wheel for the rough spreadsheet calculations)
Actually for most stock vehicles, all wheels on the vehicle are of the same type, no need to approx, just C_rr_true = C_rr_tire is perfectly accurate ;)
C_rr_tire in JSON as accel_g C_rr_true 0.0002237
I'm thinking store C_rr_tire in JSON as accel_g * C_rr_true, and leave both 0.0002237 and 44.7 as magic numbers in the code; leaves us a way to tweak A:B or make other overall adjustments without having to edit json for all wheels.
I'll dive the spreadsheet later. What criteria are considered when setting C_rr_true for the different wheel types?
I started with this table from my previous formula:
Tire Size | c |
---|---|
10" Small | 0.002 |
17" Normal | 0.005 |
24" Wide | 0.006 |
32" Armor | 0.0065 |
60" Tread | 0.005 |
which is arguably derived from https://www.engineeringtoolbox.com/rolling-friction-resistance-d_1303.html plus some fudge, then divided by 10 to approximate accel_g (I used 9.81 for a while but the numbers were uglier than I'd want in JSON) and multiplied by 0.8 because that was the fudge factor that got the SWAT track to a 55 mph cruise speed.
Final table
Tire Size | c_rr_true |
---|---|
10" Small | 0.00016 |
17" Normal | 0.0004 |
24" Wide | 0.00048 |
32" Armor | 0.00052 |
60" Tread | 0.0004 |
The numbers are fudged to get decent results. I'm okay with other numbers as long as most reasonable vehicles get reasonable results.
very preliminary code at https://github.com/mlangsdorf/Cataclysm-DDA/pull/30 doesn't work, doesn't compile, doesn't do anything.
Adding comments as I work my way through the spreadsheet:
Is wheel size / circumference getting plugged into other formula anywhere in your spreadsheet?
Vehicle height needs to be based on parts present on the vehicle, to be implemented with consistency
Currently the model is assuming infinite perfect gearing, so wheel size drops out of the math and I'm mostly keeping it around for when I tackle accurate torque and gearing.
Thanks for the review. Still need to figure out an algorithm for approximating C_air_drag.
Oh, I see you're taking Crr values from an existing table and plugging it into the linear model as a parameter. That's not it; what we actually want to do is tune our linear model so that it produces outputs that are reasonable, i.e. those values from tables are what we use to validate our model against.
Once we have managed to set parameters (coefficients A, B) so that the model returns values of Crr that match reality, we can use that parameterization to compute Crr values at any given speed.
So, consider the 17" Normal, which represents "typical car tire". A quick google search finds recommended tire pressure is usually between 30 and 35 PSI.
Using the enggtoolbox graph as basis, plot the Crr curve for 30-35 PSI ( 2.0-2.4 bar ) -- thick cyan
Taking the part of the curve within "normal" speed limits shows general consensus with the numbers from enggtoolbox's table, as well as wikipedia, so we know we're on the right track.
C_(rr) | |
---|---|
0.0062 to 0.0150 | Car tire measurements |
0.0100 to 0.0150 | Ordinary car tires on concrete |
We can approximate the curve with a straight line (black dashed):
C_(rr) = 0.0075 + 0.0000625 × v (km/h)
= 0.0075 + 0.000225 × v (m/s)
= 0.000225 (33.33 + v)
So A = 0.0075 , B = 0.000225.
Once we've done this for different wheel types, we can look for a compromise ratio A:B that works decently across the board (with a bit of fudging), and that'd allow reducing to one JSON variable:
C_(rr) = C_rr_tire × K1 × ( K2 + v )
where K1 and K2 are magic numbers and only C_rr_tire goes into JSON.
I'll help with this, gimme a few days to look into it.
Just for comparison, I've also plotted Zuvich on the above chart (red dotted) -- it looks closer to tires at 22-25 PSI ( 1.5-1.7 bar ), or perhaps it was intended to include some additional velocity-independent drivetrain losses that are not accounted in the enggtoolbox tire-only formula.
0.8 because that was the fudge factor that got the SWAT track to a 55 mph cruise speed.
SWAT truck might be underpowered to begin with:
Let's not assume that vehicles in their current state have sane or good design -- it could be that this rework exposes flaws that weren't evident before.
Still need to figure out an algorithm for approximating C_air_drag.
Ah, right, air drag is still a placeholder, so we should probably save any final fudging for when both air drag and rolling resistance are in place, then fudge both jointly for the desired balance.
So redesigning vehicles is something I want to be very careful about doing. One of the weirder parts about Mugling's big vehicle's rework was the random reassignment of vehicle engines.
The security van and the SWAT truck do look underpowered, but my first plan would be to fudge to get them to barely capable of making highway speeds rather than giving them new engines.
Back of the napkin proposal for determine C_air_drag:
Get the bounding box.
Starting at the left front, for each column:
C_air_drag = 0.35, +0.1 if first part is a protrusion
C_air_drag += 0.2 if next part isn't a non-broken half board
C_air_drag += 0.3 if there isn't a non-broken windshield before any seats or full boards
C_air_drag += 0.3 if any non door, non trunk parts do not have non-broken roofs
C_air_drag -= 0.2 if length of bounding box is twice width of bounding box
C_air_drag -= 0.1 if final tiles are half boards or trunk doors
Take the value of the worst column, += 0.2 for any turrets or floodlights (broken or not)
Typical values: Motorcycle: 0.95 Car: 0.25 Pickup: 0.45 Armored Car: 0.45 Luxury RV: 0.65 Schoolbus: 0.45 Tank: 0.85
Width in meters is based on tile width:
Tiles | Meters |
---|---|
1 | 0.9 |
2 | 1.3 |
3 | 1.7 |
4 | 2.1 |
5 | 2.5 |
6 | 2.65 |
7 | 2.8 |
8 | 2.95 |
9 | 3.1 |
10 | 3.25 |
11 | 3.4 |
Justification: most motorcycles are less than 1 m wide, but not much less. Cars are around 2 to 2.5 m wide, and semi-rig trucks around about 2.8 m per the Mack truck site. M60 and M-1 tanks are around 3.5 m wide and 11 tiles in game.
Height is based on tallest part: saddle or seat, no roof: 1.4 seat or saddle, with roof: 1.5 aisle, with or w/o roof: 2.1 has full boards: +0.5 has turrets or floodlights: +0.2 has solar panels: + 0.1
Typical heights: Motorcycle: 1.4m Car or SUV: 1.5m Solar/electric car or SUV: 1.6m Pickup: 1.5m Armored car: 1.7m Luxury RV: 2.8m Schoolbus: 2.1 m Tank: 2.8m
It's not a perfect algorithm, but it's within the ballpark and can be calculated.
So redesigning vehicles is something I want to be very careful about doing. [...]
Sure, agreed this rework should not trigger sweeping changes in the design of vehicles overall.
Back of the napkin proposal for determine C_air_drag
If I understand correctly: for each column, value ranges from 0.2 to 0.5 Then what, add/average all the columns?
I had to run and didn't finish that, actually. The intent is some kind of algorithm that encourages quarter panel, windshield, roofed seat, windshield, trunk door as the optimum solution for minimum C_air_drag (around 0.3, appropriate for a moderately streamlined modern sports car). Damage, turrets, rams, additional height, lack of windshields, lack of roofs, etc. would increase it, topping probably around 2 (equivalent to a flat plate perpendicular to airflow). I'll do another pass tomorrow.
Based on research into typical real world Crr values, here are Crr for existing wheel parts, in the form
Crr = C_tire × 0.000225 (v + 33.33)
where C_tire is the parameter varying from wheel to wheel.
Concrete Crr values are listed for each wheel at a number of reference vehicle speeds.
Full sourced info and explanations below the table.
Wheel | Crr | 15kmh 9mph | 50kmh 31mph | 80kmh 50mph | 100kmh 62mph | 130kmh 80mph |
---|---|---|---|---|---|---|
wheel_caster | Crr = 29.0000 × 0.000225 (v + 33.33) | 0.2447 | 0.3081 | 0.3625 | 0.3988 | 0.4531 |
wheel_wheelchair | Crr = 1.9500 × 0.000225 (v + 33.33) | 0.0165 | 0.0207 | 0.0244 | 0.0268 | 0.0305 |
wheel_barrow | Crr = 1.6200 × 0.000225 (v + 33.33) | 0.0137 | 0.0172 | 0.0203 | 0.0223 | 0.0253 |
wheel_bicycle | Crr = 0.4500 × 0.000225 (v + 33.33) | 0.0038 | 0.0048 | 0.0056 | 0.0062 | 0.0070 |
wheel_small | Crr = 1.5000 × 0.000225 (v + 33.33) | 0.0127 | 0.0159 | 0.0188 | 0.0206 | 0.0234 |
wheel_motorbike | Crr = 1.9000 × 0.000225 (v + 33.33) | 0.0160 | 0.0202 | 0.0238 | 0.0261 | 0.0297 |
wheel | Crr = 1.0000 × 0.000225 (v + 33.33) | 0.0084 | 0.0106 | 0.0125 | 0.0138 | 0.0156 |
wheel_wide | Crr = 0.5750 × 0.000225 (v + 33.33) | 0.0049 | 0.0061 | 0.0072 | 0.0079 | 0.0090 |
wheel_armor | Crr = 0.6000 × 0.000225 (v + 33.33) | 0.0051 | 0.0064 | 0.0075 | 0.0083 | 0.0094 |
wheel_wood | Crr = 2.1500 × 0.000225 (v + 33.33) | 0.0181 | 0.0228 | 0.0269 | 0.0296 | 0.0336 |
wheel_wood_b | Crr = 2.0500 × 0.000225 (v + 33.33) | 0.0173 | 0.0218 | 0.0256 | 0.0282 | 0.0320 |
wheel_metal | Crr = 0.3750 × 0.000225 (v + 33.33) | 0.0032 | 0.0040 | 0.0047 | 0.0052 | 0.0059 |
hd_steel_drum | Crr = 0.1250 × 0.000225 (v + 33.33) | 0.0011 | 0.0013 | 0.0016 | 0.0017 | 0.0020 |
wheel
As per earlier post
Reference IRL values 0.01 - 0.015 enggtoolbox 0.0062 - 0.0150 green seal via wikipedia typical tire pressure 30-35 PSI / typical road/highway speeds
Crr = 1.0000 × 0.000225 (v + 33.33)
| 15kmh | 50kmh | 80kmh | 100kmh | 130kmh |
| 9mph | 31mph | 50mph | 62mph | 80mph |
| 0.0084 | 0.0106 | 0.0125 | 0.0138 | 0.0156 |
wheel_wide
Reference IRL values 0.006 - 0.01 enggtoolbox 0.006 - 0.01 Bosch Automotive Handbook, 4th ed. via hpwizard 0.0045 - 0.0080 Michelin truck tires via wikipedia typical tire pressure 85-105 PSI / typical road/highway speeds
Crr = 0.5750 × 0.000225 (v + 33.33)
| 15kmh | 50kmh | 80kmh | 100kmh | 130kmh |
| 9mph | 31mph | 50mph | 62mph | 80mph |
| 0.0049 | 0.0061 | 0.0072 | 0.0079 | 0.0090 |
wheel_motorbike
Reference IRL values 0.0160 to 0.0300 Cossalter pp. 41-42 about 0.02 wikipedia, which cites Cossalter typical tire pressure 32-42 PSI / typical road/highway speeds
Crr = 1.9000 × 0.000225 (v + 33.33)
| 15kmh | 50kmh | 80kmh | 100kmh | 130kmh |
| 9mph | 31mph | 50mph | 62mph | 80mph |
| 0.0160 | 0.0202 | 0.0238 | 0.0261 | 0.0297 |
wheel_small
This wheel is used on both scooters and golf carts. This poses a bit of a conundrum: scooter tires are similar to motorcycle tires, whereas golf cart tires are generally short, squat and wide. Size and shape of tire cross section, contact patch, etc are rather different.
Sources for both types were hard to find.
For golf cart tires, typical inflation at 18-22 PSI. Starting from car tire as the basis
Crr = 1.5000 × 0.000225 (v + 33.33)
| 15kmh | 50kmh | 80kmh | 100kmh | 130kmh |
| 9mph | 31mph | 50mph | 62mph | 80mph |
| 0.0127 | 0.0159 | 0.0188 | 0.0206 | 0.0234 |
For scooters I'd expect values closer to the motorbike wheel.
wheel_bicycle
Reference IRL values biketechreview has measured data for many bicycle tires from different manufacturers. tests are on metal drum; they suggest that values may increase 50%-100% on actual road surfaces. 0.00470 is 150% of the average of all tire values from their CSV 0.00626 is 200% tests done at 120 PSI / 51kmh
0.004 enggtoolbox, for bicycle tire on asphalt road wikipedia cites biketechreview
Crr = 0.4500 × 0.000225 (v + 33.33)
| 15kmh | 50kmh | 80kmh | 100kmh | 130kmh |
| 9mph | 31mph | 50mph | 62mph | 80mph |
| 0.0038 | 0.0048 | 0.0056 | 0.0062 | 0.0070 |
wheel_barrow
Typical inflation at 20-30 PSI. Starting from car tire as the basis
Crr = 1.6200 × 0.000225 (v + 33.33)
| 15kmh | 50kmh | 80kmh | 100kmh | 130kmh |
| 9mph | 31mph | 50mph | 62mph | 80mph |
| 0.0137 | 0.0172 | 0.0203 | 0.0223 | 0.0253 |
wheel_wheelchair
Kwarciak et al perform coastdown tests from 2-1 m/s 0.0157 from their data point of approx 3.5N rolling resistance for CSSI tire under 223.6N load
Crr = 1.9500 × 0.000225 (v + 33.33)
| 1m/s | 2m/s |
| 0.0151 | 0.0155 |
| 15kmh | 50kmh | 80kmh | 100kmh | 130kmh |
| 9mph | 31mph | 50mph | 62mph | 80mph |
| 0.0165 | 0.0207 | 0.0244 | 0.0268 | 0.0305 |
wheel_caster
Shopping cart wheels.
hamilton white paper uses coefficient of rolling friction with dimension of length 0.303" for hard rubber wheel at 3mph on steel floor 0.1515 converted to Crr @ 4" diameter 0.2273 after multiply by 150% to compensate for steel floor vs road surfaces
Crr = 29.0000 × 0.000225 (v + 33.33)
| 3mph |
| 0.2263 |
| 15kmh | 50kmh | 80kmh | 100kmh | 130kmh |
| 9mph | 31mph | 50mph | 62mph | 80mph |
| 0.2447 | 0.3081 | 0.3625 | 0.3988 | 0.4531 |
wheel_metal
hamilton white paper gives, at 3mph on steel floor: 0.019" forged steel 0.021" cast iron 0.002 taking average, converted to Crr @ 20" diameter 0.003 after multiply by 150% to compensate for steel floor
Crr = 0.3750 × 0.000225 (v + 33.33)
| 3mph |
| 0.0029 |
| 15kmh | 50kmh | 80kmh | 100kmh | 130kmh |
| 9mph | 31mph | 50mph | 62mph | 80mph |
| 0.0032 | 0.0040 | 0.0047 | 0.0052 | 0.0059 |
wheel_wood_b
Baker p. 28 gives, for stagecoach on stone pavement 35 pounds resistance per ton of load 0.0175 converted to Crr
Horse carriages travel at 10-15mph
Crr = 2.0500 × 0.000225 (v + 33.33)
| 10mph | 15mph |
| 0.0174 | 0.0185 |
| 15kmh | 50kmh | 80kmh | 100kmh | 130kmh |
| 9mph | 31mph | 50mph | 62mph | 80mph |
| 0.0173 | 0.0218 | 0.0256 | 0.0282 | 0.0320 |
wheel_wood
Based on banded cart wheel, nerfed to account for more deformation of the un-reinforced wheel
Crr = 2.1500 × 0.000225 (v + 33.33)
| 10mph | 15mph |
| 0.0183 | 0.0194 |
| 15kmh | 50kmh | 80kmh | 100kmh | 130kmh |
| 9mph | 31mph | 50mph | 62mph | 80mph |
| 0.0181 | 0.0228 | 0.0269 | 0.0296 | 0.0336 |
wheel_armor
Based on wide wheel, nerf slightly for lower inflation. Pretty much guessing, but good bet that its performance is closer to wide wheel than normal car wheel.
hd_steel_drum
Basis: hamilton white paper, same computation as metal wheel except at 60". TBH it's probably a bit tenuous to use figures from a caster manufacturer for road roller drum, but that's the closest thing I could find.
Wikipedia has lots of drag coefficient numbers
(around 0.3, appropriate for a moderately streamlined modern sports car).
Could go slightly lower, considering recent models of production cars are starting to achieve below 0.3, with some even attaining less than 0.25.
topping probably around 2 (equivalent to a flat plate perpendicular to airflow)
Probably waaay overkill.
Wikipedia: 0.54 Mercedes-Benz G-Class 0.57 Hummer H2 0.6+ "typical truck" (pickup truck?)
enggtoolbox 0.6 - 0.8 Bus 0.8 - 1.0 Truck 1.1 Bicycle Upright Commuter 1.8 Motorcycle and rider
And even those numbers for bus/truck are likely to be dated -- using very "classic", blocky designs with sharpish edges. Modern, optimized designs can achieve pretty stunning performance improvements with just very small changes -- here's a double decker bus with C_d = 0.35
quarter panel, windshield, roofed seat, windshield, trunk door as the optimum solution
Besides just the order of parts for a smooth airflow profile, length may also be relevant. This shows a long cylinder has lower drag than short cylinder, so that seems to suggest a limo would be better than a car, or a longer bus better than a shorter one.
I SWAG'd the c_rolling_resistance for treads at about 5, because that was the number that gave tank designs reasonable speed. Revising the formulas with your new C_rr values (and thank you again, so much, for all that research!) and my new C_drag approximations and height and width values, we're now at:
Vehicle | Safe | Top | Safe | Top | |
---|---|---|---|---|---|
Electric Scooter (small motor) | 11 | 15 | 45 | 47 | |
Electric Bike (very small motor) | 2 | 3 | 20 | 21 | |
Electric Scooter | 35 | 48 | 78 | 81 | |
Electric Bike (small motor) | 12 | 15 | 43 | 45 | |
Scooter | 21 | 45 | 56 | 67 | |
Motorcycle Sidecar | 32 | 77 | 59 | 70 | |
Superbike | 91 | 194 | 91 | 108 | |
Golf Cart (small motor) | 48 | 78 | 37 | 39 | |
Golf Cart | 48 | 78 | 66 | 69 | |
Hatchback | 64 | 192 | 102 | 122 | |
Electric Car | 159 | 313 | 136 | 141 | |
Solar Car | 58 | 125 | 84 | 87 | |
Car | 63 | 192 | 101 | 121 | |
Sports Car | 314 | 937 | 175 | 209 | |
FBI Car | 167 | 504 | 113 | 134 | |
Cube Van | 75 | 310 | 97 | 116 | |
RV | 71 | 309 | 71 | 84 | |
School Bus | 94 | 309 | 86 | 100 | |
Luxury RV | 77 | 309 | 70 | 82 | |
Flatbed Truck | 85 | 309 | 94 | 110 | |
Armored Car | 138 | 504 | 101 | 119 | |
Humvee | 138 | 504 | 80 | 93 | |
Swat Truck | 76 | 309 | 78 | 91 | |
APC | 70 | 309 | 61 | 72 | |
Military Truck | 105 | 504 | 90 | 106 | |
Semi Truck | 102 | 504 | 85 | 99 | |
Tanks: Mobile Gun System | 69 | 309 | 62 | 73 | |
Tanks: Atomic Mini Tank | 132 | 784 | 61 | 65 | |
Tanks: Light Tank | 93 | 1153 | 52 | 66 | |
Tanks: Main Battle Tank | 60 | 1262 | 41 | 54 | |
Tanks: Light Tank (Turbine) | 93 | 1153 | 49 | 74 | |
Tanks: Main Battle Tank (Turbine) | 111 | 2329 | 52 | 78 | |
Tanks: Stryker ICV | 70 | 309 | 66 | 80 | |
Forgotitdm's Buddy | 247 | 627 | 105 | 109 | |
Kurzedmetals's Buddy Variant | 159 | 313 | 89 | 93 | |
Vastin's DeathMobile Mk1 | 146 | 392 | 85 | 88 | |
Rose's RoseRide | 113 | 392 | 76 | 80 | |
TheMurderUnicorn's Murderizer | 143 | 392 | 88 | 91 | |
Shard's Valhalla's Gate | 192 | 2672 | 26 | 28 | |
TheMurderUnicorn's Puttter | 150 | 309 | 108 | 128 | |
Submarine's Hybrid Humvee II | 97 | 313 | 90 | 94 | |
RbN420's Fancy Truck | 171 | 696 | 85 | 97 | |
Megabike | 314 | 937 | 185 | 221 | |
sDan20's Super Truck | 105 | 504 | 88 | 107 | |
Dialo.Malison's Loot Scooter | 177 | 312 | 108 | 112 | |
Loaded Car | 63 | 192 | 96 | 116 | |
Rose's RoseRide Twin | 113 | 392 | 92 | 96 | |
Shard's Valhalla's Gate (mega) | 192 | 2672 | 26 | 28 | |
Theundyingcode's Lootcycle | 186 | 287 | 123 | 127 | |
DrakeDragon8's Deathmobile | 85 | 335 | 75 | 78 |
which puts us in a pretty good place, I think: cars move at reasonable speeds (safe 100 mph, max 120 mph matches my experience), the superbike is reasonably fast (91 mph safe speed because the aerodynamics are horrible), busses and RVs can make highway speeds while safe (70-78 mph, even for the SWAT truck), tanks are manageable (40-60 mph safe speed, depending on design), and the only player submitted design that has a problem is shard's Valhalla's Gate, which is a 97 ton monstrosity that should have problems.
It's a lot of work just to get electric scooters to make sense but I think it's worth it =)
Added guesstimates for armored wheel and roller drum to earlier post; lacked better sources than what I already had on hand.
treads
I might actually be able to source that stuff, or at least find something that sorta validates your guesswork. Blob parts, on the other hand...
Revising the formulas ... puts us in a pretty good place
Nice. Not even fudged, as far as I can tell.
my new C_drag approximations
Are those numbers (column W) actually computed from vehicle prototypes or still just guesstimates?
just to get electric scooters to make sense
Actually, getting (almost) all the things to make sense -- totally worth!
Column W isn't computed from vehicle prototypes, in the sense I haven't actually written the code and I didn't go through each prototype to be sure I was correct. But I did look at the pseudo-code and calculated the numbers from my best memory of the designs. So still guesstimates, but fairly close ones.
It's weird that an armored wheel has less rolling resistance than a normal tire, but whatever.
If you can get estimates for caterpillar treads, there are 5 things well eventually want:
The medium term plan is to distinguish between the road wheels and the track itself, so it would be helpful to have the numbers for the road wheels on pavement in addition to the track on pavement.
Also, while I'm vaguely thinking ahead: is there a way to use C_rolling to estimate the static friction of the tire? It might be useful in the future to be able to cap acceleration that way: "yes, you can put a v12 on a motorbike. But the tires spin out at more than 7000 N of force, so it's not as useful as you'd think".
Column W [...] still guesstimates, but fairly close ones.
Got it.
It's weird that an armored wheel has less rolling resistance than a normal tire, but whatever.
The armored wheel actually has several things going for it, compared to the 17" normal wheel:
Intuitively we think the larger wheel has more inertia, larger contact patch -> more friction, etc which is generally correct, but that intuition does not extend to rolling resistance. The best ELI5 explanation I've seen (from here) is along the lines of "energy wasted because the tire is squishy". More rigorously speaking there is [Wong] which cites 90-95% contribution due to tire deformation being the most dominant vs other contributing factors.
is there a way to use C_rolling to estimate the static friction of the tire
No, not really. Friction contributes a small part of rolling resistance, but trying to go backwards to get friction from Crr probably isn't going to work.
Very preliminary first pass of the code is complete. Todo:
Consumption values have gone wild. This is the relative results of the vehicle consumption tests:
Vehicle | Pavement | Dirt | Pave Stop | Dirt Stops |
---|---|---|---|---|
beetle | 24.55 | 30.65 | 27.32 | 4.45 |
car | 24.70 | 42.61 | 4.81 | 4.17 |
car_sports | 8.35 | 14.56 | 17.68 | 1.72 |
electric_car | 13.67 | 21.05 | 14.46 | 2.22 |
suv | 18.52 | 37.82 | 16.76 | 3.40 |
So an SUV has 18x the range under the early version of these numbers as it used to have. That's possibly going to come down as the values improve, but there's probably going to be plenty of space to increase nominal consumption/combustion conversion inefficiency and still keep the current vehicle ranges.
Sorry, I've been meaning to get back to this, but keep getting distracted by other things.
Is mlangsdorf#30 updated? Would love to pull and have a look, etc.
Okay, I've coded drag calculations. They're pretty ugly, but they're done. Code spits out the following values:
Vehicle | Height (m) | Width (m) | Width (Tiles) | C_air_base |
---|---|---|---|---|
Bicycle: | 1.40 | 0.90 | 1 | 0.75 |
Electric Bicycle: | 1.40 | 0.90 | 1 | 0.75 |
Motorcycle: | 1.40 | 0.90 | 1 | 0.75 |
Motorcycle Chassis: | 1.40 | 0.90 | 1 | 0.75 |
Motorcycle: | 1.40 | 1.30 | 2 | 0.75 |
Quad Bike: | 1.40 | 1.70 | 3 | 0.75 |
Quad Bike Chassis: | 1.40 | 1.70 | 3 | 0.75 |
Scooter: | 1.40 | 0.90 | 1 | 0.75 |
Electric Scooter: | 1.40 | 0.90 | 1 | 0.75 |
Superbike: | 1.40 | 0.90 | 1 | 0.75 |
Tandem: | 1.40 | 0.90 | 1 | 0.75 |
Unicycle: | 1.40 | 0.90 | 1 | 0.85 |
Beetle: | 1.50 | 2.10 | 4 | 0.65 |
Bubble Car: | 1.50 | 2.50 | 5 | 0.35 |
Car: | 1.50 | 2.10 | 4 | 0.25 |
Hatchback: | 1.50 | 2.10 | 4 | 0.25 |
Sports Car: | 1.50 | 2.10 | 4 | 0.25 |
Atomic Sports Car: | 1.50 | 2.10 | 4 | 0.25 |
Electric Sports Car: | 1.50 | 2.10 | 4 | 0.25 |
Electric Car: | 1.50 | 2.10 | 4 | 0.25 |
Solar Car: | 1.60 | 2.50 | 5 | 0.35 |
SUV: | 1.50 | 2.10 | 4 | 0.25 |
Electric SUV: | 1.60 | 2.10 | 4 | 0.25 |
Electric SUV with Bike Rack: | 1.60 | 2.10 | 4 | 0.25 |
Golf Cart: | 1.50 | 1.30 | 2 | 0.75 |
Golf Cart: | 1.50 | 1.30 | 2 | 0.75 |
Hearse: | 2.00 | 2.10 | 4 | 0.25 |
Technical: | 2.30 | 2.10 | 4 | 0.70 |
Ambulance: | 2.80 | 2.80 | 7 | 0.40 |
FBI, Emergency: | 1.70 | 2.10 | 4 | 0.40 |
Fire Engine: | 2.20 | 2.50 | 5 | 0.60 |
Fire Truck: | 2.80 | 2.80 | 7 | 0.40 |
Police Car: | 1.70 | 2.10 | 4 | 0.40 |
Police K9 Unit: | 1.70 | 2.10 | 4 | 0.40 |
Police SUV: | 1.70 | 2.10 | 4 | 0.40 |
Police K9 Unit: | 1.70 | 2.10 | 4 | 0.40 |
Police K9 Transport: | 1.70 | 2.10 | 4 | 0.40 |
SWAT Truck: | 2.20 | 2.80 | 7 | 0.40 |
Primitive Tractor: | 1.40 | 1.70 | 3 | 0.75 |
Automatic Tractor: | 2.20 | 1.70 | 3 | 0.65 |
Plow Tractor: | 1.40 | 2.50 | 5 | 0.75 |
Reaper Tractor: | 1.40 | 2.50 | 5 | 0.75 |
Planter Tractor: | 1.40 | 2.50 | 5 | 0.75 |
Mechanized Infantry Carrier: | 2.80 | 2.50 | 5 | 1.00 |
Mechanized Infantry Carrier: | 2.80 | 2.50 | 5 | 1.00 |
Armored Personnel Carrier: | 2.80 | 2.50 | 5 | 1.00 |
Armored Personnel Carrier: | 2.80 | 2.50 | 5 | 1.00 |
Humvee: | 2.30 | 2.50 | 5 | 0.40 |
Humvee: | 2.30 | 2.50 | 5 | 0.40 |
Military Cargo Truck: | 2.10 | 2.50 | 5 | 0.45 |
Flatbed Truck: | 1.90 | 2.50 | 5 | 0.45 |
Pickup Truck: | 1.50 | 2.10 | 4 | 0.45 |
Semi Truck: | 2.00 | 2.95 | 8 | 0.45 |
Truck Trailer: | 2.00 | 2.65 | 6 | 0.35 |
Heavy Duty Cargo Truck: | 2.10 | 2.50 | 5 | 0.25 |
Animal Control Truck: | 2.00 | 2.10 | 4 | 0.25 |
Automatic Street Sweeper: | 2.20 | 1.70 | 3 | 0.60 |
Excavator: | 2.00 | 1.70 | 3 | 0.60 |
Road Roller: | 2.10 | 2.50 | 5 | 0.65 |
Forklift: | 1.50 | 1.30 | 2 | 0.75 |
Trencher: | 2.00 | 1.70 | 3 | 0.60 |
Armored Car: | 2.30 | 2.50 | 5 | 0.40 |
Cube Van: | 2.60 | 2.80 | 7 | 0.25 |
Low-End Cube Van: | 2.60 | 2.65 | 6 | 0.25 |
Hippie Van: | 2.10 | 2.10 | 4 | 0.25 |
Ice Cream Truck: | 2.60 | 2.80 | 7 | 0.40 |
Luxury RV: | 2.80 | 2.80 | 7 | 0.60 |
Mobile Meth Lab: | 2.60 | 2.80 | 7 | 0.25 |
RV: | 2.60 | 2.80 | 7 | 0.25 |
Schoolbus: | 2.10 | 2.50 | 5 | 0.25 |
Security Van: | 2.60 | 2.80 | 7 | 0.25 |
Wienermobile: | 2.80 | 2.80 | 7 | 0.60 |
Resulting vehicle speeds mostly look sensible, aside from bikes having way too much HP for their engines.
current PR is now #26209 in the main repo.
Starting to rebalance consumption, which made me realize that part of the solution to the having to store battery power in 1/2 HP units is change it to be explicitly stored in joules.
Fuel consumed will be engine consumption load time / fuel energy density, calculated once each turn in vehicle::thrust().
My current version of the code has some consumption numbers that are about 6x what they should be, because they don't take into account time.
CDDA currently calculates vehicle speeds in a way that is not really connected to reality. Light weight, low powered vehicles are too slow, heavy vehicles are too fast, and the maximum speed of a vehicle is based solely on engine power and is much much too high for large engines.
Change the formulas to better relate to reality.
Describe the solution you'd like
Basically implement a somewhat simplified version of this: http://www.asawicki.info/Mirror/Car%20Physics%20for%20Games/Car%20Physics%20for%20Games.html
We keep the current system of calculating engine power. However, instead of calculating drag deceleration as:
we calculate slowdown based on air resistance and rolling resistance. ie,
Similarly, instead of calculating safe velocity, max velocity, and acceleration as
we calculate
The net result is this:
From here, we can adjust some of the numbers or vehicle designs: the electric scooter could drop to using a 10 HP small electric motor, instead of a 50 HP electric motor, and putter along at 50+ mph instead of maxing out at 15 mph. With 1/5 the power draw, the battery life of the electric scooter would increase by 5x. Similarly with the golf cart and electric bicycles.
In general, this change would regularize vehicle speed: small vehicles with small or moderate engines generally go faster, heavy vehicles with large engines are a little slower but almost all keep reasonable cruise speeds (only the RV, SWAT trucks, and APC can't make 55 mph at cruise speeds) while drastically limiting the crazy top speeds that CDDA is notorious for.
Describe alternatives you've considered
A more detailed model could take account of gear ratios and transmission losses, but this is good enough for now.
Additional context
See https://docs.google.com/spreadsheets/d/1jPrZc4Tzl7S6rp63ek_09L1mB1wAVSyYtKORyUMyhCw/edit#gid=0 for the tables of values I used for this analysis.