Author Topic: friction uphill/downhill  (Read 380 times)

0 Members and 1 Guest are viewing this topic.

Offline Vladki

friction uphill/downhill
« on: March 05, 2017, 08:01:36 PM »
I don't know if this is a bug or a feature.... I notice that added friction for going uphill or downhill is not constant, but somewhat accumulative. Thus making even the strongest trucks crawling on bridges like snails. Friction on flat road is 4, but on the hill, it accumulates with every tile, and it takes few tiles to get back to 4. This is really detrimental, if there is a congestion, and trucks have to stop on the slope, or in front of it. I have measured three scenarios.

One tile full height slope up: 4, 51, 38, 25, 12, 4...  (Only 51 is the uphill tile, all the others are flat)
One tile full height slope down: 4, -24, 4...
Two consecutive half height slopes up: 4, 27, 44, 31, 18, 4... (Again only 27 and 44 are uphill)
Two consecutive half height slopes down: 4, -10, -20, 4...
Two half height slopes with one flat in between up: 4, 27, 14, 37, 24, 11, 4... (Only 27 and 37 are uphill)
Two half height slopes with one flat in between down: 4, -10, 4, -10, 4...

I do not understand why the friction behaves like this

Offline jamespetts

  • Simitrans-Extended project coordinator
  • Moderator
  • *
  • Posts: 14762
  • Total likes: 307
  • Helpful: 143
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Re: friction uphill/downhill
« Reply #1 on: March 05, 2017, 09:59:39 PM »
This is intended: the idea is that climbing a large number of consecutive tiles represents climbing a steep hill, whereas more spaced out tiles represents a less steep hill. It is intended as a way of spreading the gradient over a number of neighbouring tiles to simulate more realistic, gentler hills rather than 45 degree angles as we have to use in Simutrans.

Why do you think that this is a problem?
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Offline Vladki

Re: friction uphill/downhill
« Reply #2 on: March 05, 2017, 10:43:16 PM »
It just makes road transport within a city unfeasible. You can see it in the oom-crash.sve. There is a tunnel under the railway station in trnava. Everything is fine as long as roads are empty. But if the crossroads at the exit from the tunnel is blocked, trucks have to stop and wait for clearance. But then they start with high friction, and it takes them ages to clear the crossroads. Next truck gets stuck on the slope, and cause big congestion. I tried many different setups. I have put the crossroads, half level down to have only a half slope at the exit from the tunnel, and then further half slopes on the other side of crossroads, but it did not help much. I tried to use bridge instead of tunnel, so that the trucks are not stuck uphill when waiting for clearance, but then they got stuck ant the other side of bridge due to slow or too many private cars. Making the bridge ramp longer (slope/flat/slope) did not help either. Especially in cities you cannot make the ramp very long. You are glad if you can make it two half slopes in sequence instead of one steep slope. The biggest problem is, that the trucks crawl at 1 km/h a few tiles after they get to flat surface for no apparent reason. Also putting a bus stop at the top of the hill makes a big problem - all trucks get stuck behind the bus on the stop and start crawling at 1 km/h.

And BTW full height slope is not 45°. A double height slope would be. Try raising the land and making a cube. You'll need 4 half-heights to get it as high as wide. So full height slope is 26.6° (i.e. arctan(0.5)), and half height slope is 14° (arctan(0.25)).
« Last Edit: March 05, 2017, 10:55:32 PM by Vladki »

Offline jamespetts

  • Simitrans-Extended project coordinator
  • Moderator
  • *
  • Posts: 14762
  • Total likes: 307
  • Helpful: 143
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Re: friction uphill/downhill
« Reply #3 on: March 05, 2017, 10:58:12 PM »
I am not familiar with oom-crash.sve - may I ask which pakset that that uses? This looks as though it is a calibrational issue.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Offline Vladki

Re: friction uphill/downhill
« Reply #4 on: March 05, 2017, 11:05:16 PM »
I am not familiar with oom-crash.sve - may I ask which pakset that that uses? This looks as though it is a calibrational issue.
http://server.exp.simutrans.com/debug-saves/oom-crash.sve
It uses pak128.Britain-ex - I posted it in another thread with another bug, but can be used to demonstrate this problem as well

And to the slopes - it is even less. One half height is 16 px high, but the tile size is not 64 but 71.55 (due to isometric). So the full height slope is 24.23° (or 45%) and half height is 12.40° (or 22%). Both are indeed very steep.
https://en.wikipedia.org/wiki/Baldwin_Street
« Last Edit: March 05, 2017, 11:16:40 PM by Vladki »

Offline jamespetts

  • Simitrans-Extended project coordinator
  • Moderator
  • *
  • Posts: 14762
  • Total likes: 307
  • Helpful: 143
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Re: friction uphill/downhill
« Reply #5 on: March 06, 2017, 01:33:21 AM »
Thank you for that - I can see the difficulty. This needs some careful and precise calibration, and it needs to be able to work well for rail as well as road. Currently, for road, the base friction is 4. A single tile of half-height slope increases this to 27, and a second consecutive tile increases it to 44. Do you have any idea of the relative levels of gravitational forces that vehicles have to overcome (relative, that is, to drag on the flat) at different gradients so that more realistic multipliers can be specified here?
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Offline Vladki

Re: friction uphill/downhill
« Reply #6 on: March 06, 2017, 07:57:12 AM »
Thank you for that - I can see the difficulty. This needs some careful and precise calibration, and it needs to be able to work well for rail as well as road. Currently, for road, the base friction is 4. A single tile of half-height slope increases this to 27, and a second consecutive tile increases it to 44. Do you have any idea of the relative levels of gravitational forces that vehicles have to overcome (relative, that is, to drag on the flat) at different gradients so that more realistic multipliers can be specified here?
I will try to refresh my physics knowledge and come with something.

One more thought is to use different scale for height than distance. Now we have a scale of 8 tiles/km used to calculate physics (speed, acceleration) and economics (costs and revenues). Then we have the modelling scale for vehicles, buildings, etc which I don't know exactly but should be somewhere between 16 to 32 m/tile. For height I would think this way. Half height slope has not enough clearance under bridges, but full height does. What about 4 m for half height. That would approximately match with 16 m/tile. But if we make the calculation with 125 m/tile and 4 m for half height slope, we get some gentle 3% (or 6% for full height). Nice slope for road, but still quite steep for rail.




Offline jamespetts

  • Simitrans-Extended project coordinator
  • Moderator
  • *
  • Posts: 14762
  • Total likes: 307
  • Helpful: 143
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Re: friction uphill/downhill
« Reply #7 on: March 06, 2017, 09:22:48 AM »
That is an interesting thought; if you could let me know how the physics work out for that, I should be grateful.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Offline Vladki

Re: friction uphill/downhill
« Reply #8 on: March 09, 2017, 07:44:52 AM »
What units is the friction value in convoy info using?




Offline jamespetts

  • Simitrans-Extended project coordinator
  • Moderator
  • *
  • Posts: 14762
  • Total likes: 307
  • Helpful: 143
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Re: friction uphill/downhill
« Reply #9 on: March 10, 2017, 12:24:37 AM »
The relevant code is:

Code: [Select]
void weight_summary_t::add_weight(sint32 kgs, sint32 sin_alpha)
{
   weight += kgs;
   // sin_alpha <-- v.get_frictionfactor() between about -14 (downhill) and 50 (uphill).
   // Including the factor 1000 for tons to kg conversion, 50 corresponds to an inclination of 28 per mille.
   // sin_alpha == 1000 would be 90 degrees == vertically up, -1000 vertically down.
   if (sin_alpha != 0)
   {
      weight_sin += (kgs * sin_alpha + 500) / 1000;
   }
   //if (sin_alpha > 200 || sin_alpha < -200)
   //{
   //   // Below sin_alpha = 200 the deviation from correct result is less than 2%! Noone will ever see the difference,
   //   // but for the time being, we always save a lot of time skipping this evaluation.
   //   weight_cos += kgs * sqrt(1000000.0 - sin_alpha * sin_alpha); // Remember: sin(alpha)^2 + cos(alpha)^2 = 1
   //}
   //else
   {         
      weight_cos += kgs;
   }
}

void weight_summary_t::add_vehicle(const vehicle_t &v)
{
   // v.get_frictionfactor() between about -14 (downhill) and 50 (uphill).
   // Including the factor 1000 for tons to kg conversion, 50 corresponds to an inclination of 28 per mille.
   add_weight(v.get_total_weight(), v.get_frictionfactor());
}

and

Code: [Select]
void vehicle_t::calc_drag_coefficient(const grund_t *gr) //,const int h_alt, const int h_neu)
{
   if(gr == NULL)
   {
      return;
   }

   const waytype_t waytype = get_waytype();
   const sint16 base_friction = get_friction_of_waytype(waytype);
   //current_friction = base_friction;

   // Old method - not realistic. Now uses modified speed limit. Preserved optionally.
   // curve: higher friction
   if(previous_direction != direction)
   {
      //The level (if any) of additional friction to apply around corners.
      const uint8 curve_friction_factor = welt->get_settings().get_curve_friction_factor(waytype);
      current_friction += curve_friction_factor;
   }

   // or a hill?
   // Cumulative drag for hills: @author: jamespetts
   const slope_t::type hang = gr->get_weg_hang();
   if(hang != slope_t::flat)
   {
      // Bernd Gabriel, Nov, 30 2009: at least 1 partial direction must match for uphill (op '&'), but not the
      // complete direction. The hill might begin in a curve and then '==' accidently accelerates the vehicle.
      const uint slope_height = (hang & 7) ? 1 : 2;
      if(ribi_type(hang) & direction)
      {
         // Uphill
         const sint16 additional_base_friction = slope_height == 1 ? 40 : 80;
         const sint16 additional_current_friction = slope_height == 1 ? 23 : 47;
         current_friction = min(base_friction + additional_base_friction, current_friction + additional_current_friction);
      }
      else
      {
         // Downhill
         const sint16 subtractional_base_friction = slope_height == 1 ? 24 : 48;
         const sint16 subtractional_current_friction = slope_height == 1 ? 14 : 28;
         current_friction = max(base_friction - subtractional_base_friction, current_friction - subtractional_current_friction);
      }
   }
   else
   {
      current_friction = max(base_friction, current_friction - 13);
   }
}

The number is a multiplier of the base friction expressed in thousandths, from what I can make out. It was Bernd Gabriel who wrote the code, and it was some time ago, so I am not entirely clear on the details of how it works.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Offline Vladki

Re: friction uphill/downhill
« Reply #10 on: March 21, 2017, 11:48:22 PM »
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...

Offline jamespetts

  • Simitrans-Extended project coordinator
  • Moderator
  • *
  • Posts: 14762
  • Total likes: 307
  • Helpful: 143
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Re: friction uphill/downhill
« Reply #11 on: March 22, 2017, 12:50:41 AM »
Thank you very much for this detailed analysis. I am very busy professionally this week, so do not have time at present to look into this in detail, but one or two brief comments while I have a chance. Firstly, it was not I who wrote the physics code, but Bernd Gabriel, so I am not as familiar with the details as I might have been had I written it. This will need some considerable time for me to consider in detail fully.

Secondly, the float32e8_t is indeed a class for reproducing floating point arithmetic using integers. It is definitely necessary, as the rounding precision of inherent floating point numbers is not deterministic between platforms, leading to network desyncs: finding and fixing this was the most challenging bug yet encountered in Simutrans-Extended, and the whole thing took the two of us at least four months of doing almost nothing else on Simutrans if I remember correctly. It is unfortunately a great deal slower than native floating point types, but nobody has ever been able to come up with anything better.

The tractive force figures are indeed extremely hard to find, and I have had to resort to guessing them. The road goods vehicles do not have tractive effort specified in their .dat files, as these .dat files were produced many years ago: they use the default tractive force values. 'Buses now have the tractive effort specified on the basis of extrapolating from real life data about 'bus acceleration (on the flat). If you can find more accurate data (that, when applied, gives rise to accurate rates of acceleration), then I should be most grateful.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.