Well I have dived into the code, and physics as well. From what I have understood there are 4 forces affecting the vehicle:

Machine force, Fr=roll resistance, Ff=air resistance, Fs=slope resistance (force).

Ff= speed^2 * air_resistance

- air_resistance is given in dat file multiplied by 100. Default for road is 0.15, which is IMHO quite low in comparison to train/tram/monorail (1.60), narowgauge (1.20), maglev (1.45) and airplanes (1.00). Ships have air_resistance 25 because it includes water_resistance as well. air_resistance for road vehicles (mainly bus/truck) should be IMHO similar to trams, hmmmm lets say 1.50 ?

- I have checked non-default air-resistances defined in pak.britain and found that trains/ner-es1.dat has resistance 1000 (10), and maglevs have 825/882. Perhaps they have been forgotten from some older version and need rescaling roughly by factor of 8

Fr= weight * g_accel * cos(alpha) * rolling_resistance

- rolling_resistance is given in dat file multiplied by 10000. Contrary to documentation it is not in N/kg, but just a constant. It has to be multiplied by g to get N/kg. Thus there is a bug in gui/components/gui_convoy_assembler.cc which displays rolling resistance in depot window as weight * rolling_resistance. But it should be weight * rolling_resistance * g_accell (9.81). I wanted to provide a patch but I did not like defining g in multiple places. g_accel is defined in convoy.cc. If it would be in convoy.h it could be included and used in gui_convoy_assembler.cc. Or is there a better way to do it?

- cos(alpha) is defined to be 1 for simplicity. The error is <1% for slopes <14%.

- default rolling resistances are quite OK for track, monorail (0.0015), maglev (0.0013), ng (0.0017), but I think that 0.0060 for trams is quite high. According to wikipedia, dirty tram track with straights and curves has 0.0050, and this should be the value for straight track. It should be IMHO similar to track or narrowgauge, perhaps a bit higher but not that much. Also 0.0090 for roads is quite high. What I have found on wikipedia, it should be 0.0045 to 0.0080. Water and air vehicles have default rolling resistance 0.0010, but they should have 0 (nothing rolls), except for aircraft rolling on runway/taxiway. Perhaps there is some specific handling of these in the code, I have not checked yet.

- hackney-carriage.dat has specified rolling_resistance=40, while other similar vehicles have 100-180. I think 140 would be appropriate. Wikipedia says stage coach has 0.0385 to 0.073 on dirt road (with/without snow). So 140 might be ok for paved road. Perhaps an option to have additional rolling_resistance for different ways (dirt, gravel, cobblestone, concrete, asphalt; steel rail, welded steel rail, cast iron rail, plateway, ...) could be interesting

Fs= weight * g_accel * sin(alpha)

- there is an error in the comments. if sin_alpha is given multiplied by 1000, and 1000 is 90 degrees up, then sin == 50 (0.05) is not 28 per mille, but 2.8 degrees. At small angles sin_alpha is almost equal to tan_alpha = inclination in % (or per mille). So 5% slope is sin_alpha = 50.

- vehicle_t.get_frictionfactor() is used as sin_alpha. So the values used are quite ok. If we take half height to be 3 m, tile length 125m, we get 2.4% slope. 4m height would give 3.2% slope. Full height slope would then be 6-8m which should be enough for 4.5m high double decker, or train with overhead wire (5-5.5 m above rail) plus the bridge's body.

- vehicle_t::calc_drag_coefficient should IMHO calculate only slope related drag (force), and not use get_friction_of_waytype. Base friction of waytype is already accounted for in rolling_resistance from dat file. Even if specific friction factors for different ways would be implemented, it should not affect Fs, but Fr

- why the calculation of weight_sin is adding 500 (0.5) to weight*sin_alpha

?

I have noticed that air_ and rolling_resistance from dat files, as well as g_accel are defined as float32e8_t. What is that type? To me it looks like some attempt to do floating point calculations using fixed point instructions. Is it reliable? Is it necessary? Would not using doubles or other standard floating point types be better. Are floating point operations so slow that we need something like this? Throughout the code I have seen combination of doubles, float32e8_t's and integers in one formula. Is that safe for calculations?

Anyway, all the errors I have pointed above are not that bad to make truck crawling uphill. The bug must be somewhere deeper in the code... Let's have an example DAF XF with steel trailer. Empty weight = 17t, fully loaded 65t.

Fr=17000*9.81*0.0090=1.5 kN (rolling resistance empty)

Fr=65000*9.81*0.0090=5.7 kN (full)

Ff=(86/3.6)^2*0.15=0.085 kN (air resistance at full speed), probably should be 10x more

Fs=17000*9.81*0.044=7.3 kN (slope resistance for two or more half height slopes in line)

Fs=65000*9.81*0.044=28 kN

So the complete resistance is 28+5.7=33.7 kN. You can see that the air resistance is almost negligible in comparison to the effect of slope and rolling resistance. But still, DAF XF truck has tractive force 38 kN, so there should be 4 kN left for accelerating fully loaded truck on slope. This gives us 0.06 m/s^2, mm not much, but still it should be able to move...

I just wonder if the tractive force is estimated correctly. Unfortunately car manufacturers give usually only power and torque. But to convert torque to tractive force, we need to know the trasmission ratio of the whole path from engine to wheels. Which I could not find yet...