News:

Simutrans Chat Room
Where cool people of Simutrans can meet up.

Physics oddities

Started by jamespetts, June 27, 2009, 03:41:24 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

jamespetts

I am in the process of trying to undertake some balancing work for Pak128.Britain, and am having some difficulties with dealing with early forms of transport, particularly horse-drawn trains. According to this article, a single horse could pull a train loaded with 10 - 13t of coal on the early wagonways. One horsepower is 0.74Kw: because fractional values of kilowatts are not permitted, 1kw is used in PakBritain.

With the gear setting at 100, a single horse cannot even pull one fully laden 2t wagon at 1km/h. For a single horse to pull 5 fully laden 2t wagons, I used a gear of 850 (and Simutrans-Experimental's power factor set at 125% on top of that), and even then, it took about four or five tiles to reach its maximum speed of 4km/h.

There must be something wrong with that. Can anyone who knows more about how Simutrans's physics works comment?
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.

Dwachs

One possible explanation is that Simutrans uses int-types in almost all calculations. In the case of really low-powered convois it could happen that a quantity should be 0.8, which is then rounded downwards to zero. This effect is much less noticeable at high values (ie 100.8 or 100.0 makes not a small difference), but for really small values, the rounding error can be like 50% of the exact value.
Parsley, sage, rosemary, and maggikraut.

jamespetts

Hmm, I looked at the code, and it doesn't use integers at all:


/* Calculates (and sets) new akt_speed
* needed for driving, entering and leaving a depot)
*/
void convoi_t::calc_acceleration(long delta_t)
{
// Prissi: more pleasant and a little more "physical" model *
int sum_friction_weight = 0;
sum_gesamtgewicht = 0;
// calculate total friction
for(unsigned i=0; i<anz_vehikel; i++) {
const vehikel_t* v = fahr[i];
int total_vehicle_weight = v->get_gesamtgewicht();

sum_friction_weight += v->get_frictionfactor() * total_vehicle_weight;
sum_gesamtgewicht += total_vehicle_weight;
}

// try to simulate quadratic friction
if(sum_gesamtgewicht != 0) {
/*
* The parameter consist of two parts (optimized for good looking):
*  - every vehicle in a convoi has a the friction of its weight
*  - the dynamic friction is calculated that way, that v^2*weight*frictionfactor = 200 kW
* => heavier loaded and faster traveling => less power for acceleration is available!
* since delta_t can have any value, we have to scale the step size by this value.
* however, there is a quadratic friction term => if delta_t is too large the calculation may get weird results
* @author prissi
*/

/* but for integer, we have to use the order below and calculate actually 64*deccel, like the sum_gear_und_leistung
* since akt_speed=10/128 km/h and we want 64*200kW=(100km/h)^2*100t, we must multiply by (128*2)/100
* But since the acceleration was too fast, we just deccelerate 4x more => >>6 instead >>8 */
sint32 deccel = ( ( (akt_speed*sum_friction_weight)>>6 )*(akt_speed>>2) ) / 25 + (sum_gesamtgewicht*64); // this order is needed to prevent overflows!

// prissi:
// integer sucks with planes => using floats ...
sint32 delta_v =  (sint32)( ( (double)( (akt_speed>akt_speed_soll?0l:sum_gear_und_leistung) - deccel)*(double)delta_t)/(double)sum_gesamtgewicht);

// we normalize delta_t to 1/64th and check for speed limit */
// sint32 delta_v = ( ( (akt_speed>akt_speed_soll?0l:sum_gear_und_leistung) - deccel) * delta_t)/sum_gesamtgewicht;

// we need more accurate arithmetic, so we store the previous value
delta_v += previous_delta_v;
previous_delta_v = delta_v & 0x0FFF;
// and finally calculate new speed
akt_speed = max(akt_speed_soll>>4, akt_speed+(sint32)(delta_v>>12l) );
}
else {
// very old vehicle ...
akt_speed += 16;
}

// obey speed maximum with additional const brake ...
if(akt_speed > akt_speed_soll) {
akt_speed -= 24;
if(akt_speed > akt_speed_soll+kmh_to_speed(20)) {
akt_speed = akt_speed_soll+kmh_to_speed(20);
}
}

// new record?
if(akt_speed > max_record_speed) {
max_record_speed = akt_speed;
record_pos = fahr[0]->get_pos().get_2d();
}
}
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.

prissi

maximum gear value is 255, since it is an unsigned uint8. Gear 850 is just gear 82, even less than standard gear 100.

jamespetts

Hmm, that doesn't explain the odd behaviour when gear is not set, though.
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.

prissi

Well, the simutrans formula is not physical correct but for gameplay. With less than 1kw you will not move anything.

Apart from that: A horse gives per hour about 4kW and for accelerating 20kW ... 1hp is for a full day workload.

jamespetts

Hmm, I'm not sure that I understand what you mean by the formula being not physically correct but for gameplay, since the lack of physical correctness makes the gameplay worse, rather than better, as explained in my original post. Do you think that the gameplay would be less fun/harder if the calculations were more realistic?

As to the second part about horses: I am afraid that I do not understand that either. You seem to be referring to kilowatt hours, rather than kilowatts. The power of vehicles is measured in kilowatts, not kilowatt hours: I do not understand what you mean by "4kw per hour", since a measure of power is energy divided by time.
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.

Spike

Quote from: jamespetts on June 27, 2009, 03:41:24 PM
According to this article, a single horse could pull a train loaded with 10 - 13t of coal on the early wagonways. One horsepower is 0.74Kw: because fractional values of kilowatts are not permitted, 1kw is used in PakBritain.

This is not quite correct. Power output of animals and humans cannot be calculated so easily, since they can output way more power for short moments - think a weight lifter in sports.

0.74kw is kind of a long term average for horses. And not even that is fully correct since some horse races are better at fast sprints, while others are good for constant low speed pulling.

So better do not compare animal powers in terms of kw (or hp), since reality is way more complicated as it seems ...

Isaac Eiland-Hall

Quote from: Hajo on June 29, 2009, 11:59:10 AM
0.74kw is kind of a long term average for horses. And not even that is fully correct since some horse races are better at fast sprints, while others are good for constant low speed pulling.

Uh-oh. Extension request for 'random variations of power at spawn' in 5... 4... 3... ;-)

jamespetts

Hajo,

ahh, I understand what Prissi meant now! That is very helpful information, thank you. Does anyone have any recommendations as to what power output should be used for shire horses (good at constant low speed pulling) and the slightly less sturdy but faster sorts of horses used for pulling road carriages and trams? Also, should a gear factor be applied for horses pulling things on rails to take account of the reduced friction for railways compared to road ways?
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.

The Hood

just adjust the value of power or gear until the maximum speed shown in the convoy in the depot is the correct speed.

z9999

[off-topic]
BTW, speed in Simutrans-Experimental seems to be different from Simutrans.

Max speed of this convoi is 33 km/h in Simutrans, but is only 3 km/h in Simutrans-Experimental, even if window shows as (max. 31km/h).
It's empty and is not too heavy. I don't know why.


http://simutrans-germany.com/files/upload/speed_test02.sve

jamespetts

The reason is that Simutrans-Experimental attempts to simulate steam locomotive physics more accurately by reducing the effective power when the locomotive is travelling at slower speeds: see here for an explanation. The idea is to simulate more realistically the comparative disadvantages of steam locomotives. However, I will look into reducing the extent of the effect slightly in the next release: it may be that it penalises very low speeds too heavily such that convoys get stuck at low speeds in some cases.
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.

z9999

Thank you for explain.

Different is OK but maybe, Max. speed in depot window shoud be the same as real reachable max. speed, if possible.

jamespetts

Thank you for that suggestion: I'll look into that :-)
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.

gerw

Quote from: prissi on June 27, 2009, 07:42:51 PM
maximum gear value is 255, since it is an unsigned uint8. Gear 850 is just gear 82, even less than standard gear 100.
Gear is a uint16. In former versions it was only a uint8.

z9999

... and standard gear is 64, isn't it ?

prissi

Ok, the 8 bit gear was there until version 5 internally, and indeed 64 is the internal representation. I long forgot about this, it seems ...