Join GitHub today
GitHub is home to over 36 million developers working together to host and review code, manage projects, and build software together.
Sign upPlayer friendly vehicle speed rework #25652
Comments
mlangsdorf
added this to To do
in Extended Vehicle Tune-Up
via automation
Sep 16, 2018
mlangsdorf
added
Game: Mechanics Change
Game: Balance
<Suggestion / Discussion>
Vehicles
[C++]
labels
Sep 16, 2018
mlangsdorf
self-assigned this
Sep 16, 2018
This comment has been minimized.
This comment has been minimized.
CoroNaut
commented
Sep 16, 2018
|
Looking at #19275 may be of some help. |
This comment has been minimized.
This comment has been minimized.
|
19275 has a lot of examples of things not to do, actually. |
This comment has been minimized.
This comment has been minimized.
|
Quick check of units, without delving into the physics.
Slowdown is deceleration, it should have units m/s²
So far, so good. But then
The units don't match up. (?!) Then we have
This checks out. |
This comment has been minimized.
This comment has been minimized.
|
F_(rolling resistance) = veh_mass (kg) * num_times * C_(tire) * v (m/s) |
This comment has been minimized.
This comment has been minimized.
CoroNaut
commented
Sep 17, 2018
I was looking at
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. |
This comment has been minimized.
This comment has been minimized.
|
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. |
This comment has been minimized.
This comment has been minimized.
A. B.
I still don't think this is right; here are a couple questions that might help diagnose: 1 2
What are these values based on, are they C_rr from here? |
This comment has been minimized.
This comment has been minimized.
|
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: |
This comment has been minimized.
This comment has been minimized.
|
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).
Ok so [MarcoM] gives:
And goes on to calculate a concrete example using
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
This does provide justification for the magic number "30m/s" for cars only 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 P85-86 of [NHTSA 811-154] briefly explains how this came about
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:
Thus, C_(rr) is convenient for
but
Going back to [Zuvich], he explains:
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: 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:
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:
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
Or, in metric and coerced into the same form as SAE J2452: Contrast this with MarcoM's pure linear model without any velocity-independent component. It is a straight line from the origin, intersecting the C_drag 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: Don't model rolling resistance at allIf it has a "fairly small effect" anyway, it might not even be worth the effort to model it accurately, etc. Use velocity-independant constant C_(rr)Obtain or extrapolate "typical" values for various wheels from tables on wikipedia/enggtoolbox MarcoM-style pure linear model (A=0, B>0, C=0)Use "typical" C_(rr) values for wheels as a reference point, draw line from origin through ref point Zuvich-style linear model (A>0, B>0, C=0)Use "typical" C_(rr) values for wheels as a reference point (x,y) Zuvich-style, variantFix the ratio between coefficients A:B, store only one value in json quadratic modelEach type of wheel gets json parameters for coefficients A,B,C quadratic model, variantFix 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. |
This comment has been minimized.
This comment has been minimized.
|
Thanks for all the additional research!
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. |
This comment has been minimized.
This comment has been minimized.
|
New comparison chart for speed, all values in mph because that's what I think in:
So the new formula has a bunch of advantages:
Disadvantages:
|
This comment has been minimized.
This comment has been minimized.
Looks correct.
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 ;)
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. |
This comment has been minimized.
This comment has been minimized.
|
I started with this table from my previous formula:
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
The numbers are fudged to get decent results. I'm okay with other numbers as long as most reasonable vehicles get reasonable results. |
This comment has been minimized.
This comment has been minimized.
|
very preliminary code at mlangsdorf#30 |
This comment has been minimized.
This comment has been minimized.
|
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
|
This comment has been minimized.
This comment has been minimized.
|
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. |
This comment has been minimized.
This comment has been minimized.
|
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". 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.
We can approximate the curve with a straight line (black dashed):
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: 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.
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.
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. |
This comment has been minimized.
This comment has been minimized.
|
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. |
This comment has been minimized.
This comment has been minimized.
|
Back of the napkin proposal for determine C_air_drag:
Take the value of the worst column, += 0.2 for any turrets or floodlights (broken or not) Typical values: Width in meters is based on tile width:
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: Typical heights: It's not a perfect algorithm, but it's within the ballpark and can be calculated. |
This comment has been minimized.
This comment has been minimized.
Sure, agreed this rework should not trigger sweeping changes in the design of vehicles overall.
If I understand correctly: for each column, value ranges from 0.2 to 0.5 |
This comment has been minimized.
This comment has been minimized.
|
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. |
This comment has been minimized.
This comment has been minimized.
|
Based on research into typical real world Crr values, here are Crr for existing wheel parts, in the form Concrete Crr values are listed for each wheel at a number of reference vehicle speeds. Full sourced info and explanations below the table.
17" car wheel
|
This comment has been minimized.
This comment has been minimized.
|
Wikipedia has lots of drag coefficient numbers
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.
Probably waaay overkill. Wikipedia: enggtoolbox 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
Besides just the order of parts for a smooth airflow profile, length may also be relevant. |
This comment has been minimized.
This comment has been minimized.
|
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:
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 =) |
This comment has been minimized.
This comment has been minimized.
|
Added guesstimates for armored wheel and roller drum to earlier post; lacked better sources than what I already had on hand.
I might actually be able to source that stuff, or at least find something that sorta validates your guesswork.
Nice. Not even fudged, as far as I can tell.
Are those numbers (column W) actually computed from vehicle prototypes or still just guesstimates?
Actually, getting (almost) all the things to make sense -- totally worth! |
This comment has been minimized.
This comment has been minimized.
|
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". |
This comment has been minimized.
This comment has been minimized.
Got it.
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.
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. |
This comment has been minimized.
This comment has been minimized.
|
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:
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. |
This comment has been minimized.
This comment has been minimized.
|
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. |
This comment has been minimized.
This comment has been minimized.
|
Okay, I've coded drag calculations. They're pretty ugly, but they're done. Code spits out the following values:
Resulting vehicle speeds mostly look sensible, aside from bikes having way too much HP for their engines. |
This comment has been minimized.
This comment has been minimized.
|
current PR is now #26209 in the main repo. |
mlangsdorf
referenced this issue
Oct 22, 2018
Merged
clean up handling of vehicle power to always use watts #26353
This comment has been minimized.
This comment has been minimized.
|
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. |


mlangsdorf commentedSep 16, 2018
•
edited
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.