News:

Simutrans Sites
Know our official sites. Find tools and resources for Simutrans.

Calculation of acceleration

Started by The Hood, June 18, 2009, 09:27:03 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

The Hood

I was wondering if anyone could provide me with the formula simutrans uses to calculate acceleration / speed.

What I want to know (mathematically) is how gear, power, and weight combine so that I can calculate the number of tiles it takes a convoy to reach top speed on straight, flat track. 

Can anyone help?

Dwachs

this is in the source code, in simconvoi.cc, convoi_t::calc_acceleration, lines 448ff
Parsley, sage, rosemary, and maggikraut.

The Hood

Given I can't read C code, but am used to other languages, will I be able to understand that and be able to turn it into a formula for something like Excel?  If it's going to require deep knowledge of C, then can someone decode it into maths for me please?

Dwachs

#3
this code should calculate the number of tiles a convoi can drive on full-speed in one game month, to give you an impression about the involved scaling of quantities:

tiles_per_month = (kmh_to_speed(max_kmh) * ticks_per_tag) >> (8+12); // 12: fahre_basis, 8: 2^8 steps per tile


  • kmh_to_speed - just a transformation: (((speed) << 10) / 80)
  • max_kmh - max speed in kmh
  • ticks_per_tag - ticks per month, configurable in *.tab, default 18
  • << and >> are shift operations:  a<<b = a * 2^b, a>>b = a/ 2^b

here is the most relevant part of the code for you:

/* deacceleration due to friction */
deccel = ( ( (akt_speed*weight)>>6 )*(akt_speed>>2) ) / 25 + (weight*64)
/* resulting acceleration */
accel = (sum_gear_und_leistung - deccel) / weight


  • akt_speed ... current speed
  • sum_gear_und_leistung ... sum over all vehicles in convoi of their gear multiplied by their power
  • weight ... weight of the convoi
So I guess, assuming no friction would give

min_number_of_tiles_til_top_speed = ( kmh_to_speed(max_kmh) )^2 / ( 2* (sum_gear_und_leistung/weight -64) *2^20 )

which would yield a lower bound on the needed tiles
Parsley, sage, rosemary, and maggikraut.

The Hood

Thanks.  I'm assuming that no friction is incurred on straight track then?

Dwachs

No, even there, friction (deccel in the code above) depends quadratically on the velocity, which makes it impossible to calculate the quantity you want.

Parsley, sage, rosemary, and maggikraut.

The Hood

Oh OK.  One more question - what are the units of akt_speed?  km/h?  tiles per tick? anything else?

Dwachs

#7
akt_speed is measured in internal units, the methods kmh_to_speed and speed_to_kmh do the transformation between internal unit and km/h.

you could also use an N-term approximation:

tiles = 0
for i=1 to N
v0 = kmh_to_speed(max_kmh) * (i-1)/N
v1 = kmh_to_speed(max_kmh) * i/N

tiles = tiles + (v1^2-v0^2) / 2 / (sum_gear_und_leistung/weight -64 -v0^2 / 6400) / 2^20
end

This gives a lower bound on the number of tiles. Using -v1^2 in the denominator gives upper bounds. Just play with different values of N (10,100,1000..).

However, max_speed must be chosen smaller than the maximal possible speed of the convoi given its weight and power, otherwise this sum tends to be infinity I suspect.

Parsley, sage, rosemary, and maggikraut.

The Hood

OK thanks.  I might change tack from the tiles to max speed approach (I was trying to use it as a way of getting acceleration right on pak128.Britain), but definitely helpful, as I need to make sure each convoy has enough power to reach a sensible speed (presumably can easily derive that from calculating the akt_speed at which accel = 0?

Dwachs

The max_speed a convoi can go at full load is displayed in the depot gui.
Parsley, sage, rosemary, and maggikraut.

The Hood

Clever - I'd never noticed that - is it new?  Then again I haven't played for 2 years!

Even so I would still like a formula so I can just use it in a spreadsheet rather than recompiling sources and reloading simutrans every time I change the power or gear...  I think I can probably do what I want now.

Fabio

Quote from: Dwachs on June 18, 2009, 12:47:02 PM
akt_speed is measured in internal units, the methods kmh_to_speed and speed_to_kmh do the transformation between internal unit and km/h.

so this could allow also mph and knots for ships, right?

VS

#12
From James, earlier, somewhere else:
QuoteThis should be fairly easy to acheive at the UI level
Unfortunately it isn't only calling arbitrary conversion everywhere instead of calling conversion to kph. Throughout the code, internal units and kph are mixed. You can define internal_to_whatever, but that will not fix anything since in some places are hardwired computations in kph which won't go away just like that.

I already tried once and it is probably not impossible task, just really really unsatisfying to the coder, since relatively a lot of work would go into chasing all the places and ensuring nothing critical is broken - and what you get? Different number and three letters.

My projects... Tools for messing with Simutrans graphics. Graphic archive - templates and some other stuff for painters. Development logs for most recent information on what is going on. And of course pak128!

Dwachs

Quote from: The Hood on June 18, 2009, 12:57:29 PM
Even so I would still like a formula so I can just use it in a spreadsheet rather than recompiling sources and reloading simutrans every time I change the power or gear...  I think I can probably do what I want now.
max_kmh = sqrt( (power/weight-64) * 6400 ) * 80/1024

this formula is correct for large values of max_kmh. Due to rounding errors it can happen, that this formula gives small max_kmh (1 or 2 km/h) but in simutrans the vehicle cannot move.
Parsley, sage, rosemary, and maggikraut.

The Hood


jamespetts

Couldn't you just replace the speed_to_kmh(uint32 speed) and kmh_to_speed(uint32 kmh) macros with functions like:


enum speed_type { kmh, mph, knotts };
uint32 speed_to_units(uint32 speed, speed_type = kmh);


and only activate the second parameter in cases where only the UI is affected?
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.

Fabio

Quote from: VS on June 18, 2009, 01:19:16 PM
I already tried once and it is probably not impossible task, just really really unsatisfying to the coder, since relatively a lot of work would go into chasing all the places and ensuring nothing critical is broken - and what you get? Different number and three letters.

I can believe it's unsatisfactory! I would say, though, that for sure the code would be cleaner if the conversion happened only when UI is involved. It could even allow different units in the same setup (e.g. kph for vehicles and knots for ships).
maybe those more involved in unit change (Britts and Americans) should look into it: for sure for them it would be more satisfactory ;)

VS

#17
I don't think both of you understood what I meant. It is impossible to write this cleanly by doing only display stuff. First the program would have to use consistently internal units everywhere. Then you can just generalize the conversion routine for more speed units. Otherwise you'll have to write stuff like

internal_to_units(kmh_to_internal(value), unit_type)

which isn't exactly the epitome of "nice" (I would rather go with "pointless" in that case). There is also the danger of losing precision in chained conversions, no idea if it's significant enough or not... of course anyone can probably go and make it just work like this, without much regard to cleanliness.

In short, the issue is not only making it work, but also making it serviceable under the hood.

My projects... Tools for messing with Simutrans graphics. Graphic archive - templates and some other stuff for painters. Development logs for most recent information on what is going on. And of course pak128!

Fabio

VS, my point is that changing the cose to use internal units consistently would help cleanliness, regardless of multiple units. So it could be worthy per se.
on the other hand, it would make multi-unit possible if not easy, so that those more interested in multi-unit should first help changing kph to int units all through the code and then adding multi-units UI.

VS

Oh! I'm sorry, I didn't realize what you meant here.
Quote from: fabio on June 18, 2009, 03:05:12 PM
I would say, though, that for sure the code would be cleaner if the conversion happened only when UI is involved.

My projects... Tools for messing with Simutrans graphics. Graphic archive - templates and some other stuff for painters. Development logs for most recent information on what is going on. And of course pak128!