The International Simutrans Forum

Development => Patches & Projects => Incorporated Patches and Solved Bug Reports => Topic started by: jamespetts on March 13, 2009, 12:04:00 AM

Title: The meaning of life minus one
Post by: jamespetts on March 13, 2009, 12:04:00 AM
I have been testing how the speed is calibrated in Simutrans for the development of Simutrans-Experimental, and thought that people might be interested in the information that I have come up with.

At 10kph, the number of ticks per tile is 41. That is: vehicles travel 1 tile per 4.1 ticks of game speed for every kilometer per hour that they travel.
Title: Re: The meaning of life minus one
Post by: prissi on March 13, 2009, 12:16:09 PM
At which setting for the bits_per_month and show_month? Because those two determine the meaning of "tick". Or do you mean the internal ms?

Otherwise: Straight tile, 255 steps, diagonal 127 steps. Speed is (kph*1024)/80kph=kph*12,8. One step takes 1/4096 speed*ms.

=> kph*12.8/(4096*255) = tiles/ms, that means 8,162s per kmh and tile.
Title: Re: The meaning of life minus one
Post by: jamespetts on March 13, 2009, 04:22:00 PM
I did mean internal ms. And thank you very much for the information - 4.096 is very close to the 4.1 that I measured. Very useful - thank you :-)
Title: Re: The meaning of life minus one
Post by: jamespetts on March 17, 2009, 01:04:53 AM
Prissi,

I have now written the code for this: I should be very grateful if you could tell me if I am doing anything terribly wrong. The following code is part of the laden() method in simconvoi.cc:


double journey_time = welt->get_zeit_ms() - last_departure_time;
// Manhattan distance
double journey_distance;

if(fahr[0]->get_pos().get_2d().x < fahr[0]->last_stop_pos.x || fahr[0]->get_pos().get_2d().y < fahr[0]->last_stop_pos.y)
{
         journey_distance = (fahr[0]->last_stop_pos.x - fahr[0]->get_pos().get_2d().x) + (fahr[0]->last_stop_pos.y - fahr[0]->get_pos().get_2d().y) * 255;
}
else
{
journey_distance = (fahr[0]->get_pos().get_2d().x - fahr[0]->last_stop_pos.x) + (fahr[0]->get_pos().get_2d().y - fahr[0]->last_stop_pos.y ) * 255;
}
double unadjusted_speed = journey_distance / journey_time;
uint32 average_speed = unadjusted_speed / (12.8 / 4096);


Have I correctly interpreted your mathematics?
Title: Re: The meaning of life minus one
Post by: prissi on March 17, 2009, 01:28:35 PM
Not completely, as diagonals tiles have a different length than normal tiles. Also I am not sure, why you are calculating with the internal steps. THis should be needed nowhere and just bloats up the numbers. Maybe, if you could tell me what you hope to achieve by this, I could give you hints.

And as I said, the actual speed in game depends very much on your setting of bit_per_month and show_month.
Title: Re: The meaning of life minus one
Post by: jamespetts on March 17, 2009, 01:45:36 PM
Thank you for your reply :-) The reason that I want the average speed is to use as part of the new revenue model in Simutrans-Experimental. The idea is that there will be a new "average speed" graph in the convoy and line windows, and that the speed bonus will be based on the average speed for the previous month (or the current month if not available for the previous month), rather than the vehicle's maximum speed (with the values in speedbonus.tab adjusted accordingly).

Do you think that I should use something other than welt->get_zeit_ms() to obtain the timing data, then? Thank you very much for the offer of hints - much appreciated :-)
Title: Re: The meaning of life minus one
Post by: prissi on March 17, 2009, 02:26:40 PM
I would just suggest to record the last speed between halts as also the last position is recorded. You must be careful, that those numbers survice saving loading (currently they would not). Other than that the fastest possible time is given in the above formula, and empirical factors would be ok too.

For the numbers of tiles driven since last stop you can take the count of route_t -1.
Title: Re: The meaning of life minus one
Post by: jamespetts on March 17, 2009, 02:33:03 PM
Prissi,

I am aware of the saving/loading position: I have created a special separate system for versioning Simutrans-Experimental saved games that gives a specific Simutrans-Experimental version in addition to the normal version, and I have made sure that the timings and average speeds are indeed loaded and saved.

I am not quite clear on what you mean by "the last speed between halts" here. What I am currently planning to do is something very similar to the present system, where the distance and average speed is calculated for each hop.

Thank you for the suggestion for using the number in route_t - 1; I shall try that and see whether that works better (with the above formula, the speeds all seem far too low). One advantage of using a system of Manhattan distance divided by time, however, is that the lesser number of steps in a diagonal tile would seem to be counterbalanced by the fact of using the Manhattan distance, which would not be true of the route distance. Also, using route_t - 1 would seem not to create a sufficient incentive to create direct routes.

Edit: I have now found a formula that works effectively:


const double journey_time = (welt->get_zeit_ms() - last_departure_time) / 4096;
// Manhattan distance
const uint32 journey_distance = abs(fahr[0]->get_pos().get_2d().x - fahr[0]->last_stop_pos.x) + abs(fahr[0]->get_pos().get_2d().y - fahr[0]->last_stop_pos.y);
const uint16 average_speed = (journey_distance / journey_time) * 20;
Title: Re: The meaning of life minus one
Post by: prissi on March 18, 2009, 10:03:34 AM
There is already a function abs_distance() that takes 2D koordinates and gives their manhattan distance btw ...
Title: Re: The meaning of life minus one
Post by: jamespetts on March 18, 2009, 10:06:24 PM
Ahh, I didn't realise that. Thank you. But, hmm, in that case, why is it not used in the vehikel_t::calc_gewinn method, where the following code is used instead:


const koord zwpos = ware.get_zwischenziel()->get_basis_pos();
const long dist = abs(zwpos.x - start.x) + abs(zwpos.y - start.y) - (abs(end.x - zwpos.x) + abs(end.y - zwpos.y));


(Or this in older versions, maintained as a comment:)


const long dist = abs(end.x - start.x) + abs(end.y - start.y);


?
Title: Re: The meaning of life minus one
Post by: prissi on March 19, 2009, 11:20:27 AM
BEcause this is older than the method. Historic reasons. I introduced this when I renovated the routefinder.
Title: Re: The meaning of life minus one
Post by: jamespetts on March 19, 2009, 08:54:37 PM
Ahh, I see :-) I understand now. Thank you.