The International Simutrans Forum

Development => Patches & Projects => Topic started by: jamespetts on December 23, 2008, 12:28:05 AM

Title: [Patch (obsolete)] New cornering algorithm - allows for tilting trains
Post by: jamespetts on December 23, 2008, 12:28:05 AM
Attached is a patch to change the way in which Simutrans handles corners for rail and road vehicles. The aim is to make the handling of corners both more realistic and more interesting for the player in terms of the best network design for cornering.

The present default Simutrans code deals with corners quite simply: it tests to see whether the current direction matches the vehicle's last known direction, and, if it does not match, adds a certain element of friction to the speed calculation. (Ships work the same way, but add a lower element of friction. The system is not used at all by aircraft, which can bank and corner without slowing down at all). The problem with the current system for land vehicles is that it does not draw any distinction between cornering at low and high speeds, or between wide and tight corners: all will slow the vehicle by applying more friction. Moreover, the more powerful the vehicle, the better that it can overcome friction: in real life, powerful vehicles are no better at cornering than less powerful ones.

What I have done instead is, instead of applying friction, I have applied logic to reduce the speed limit whenever a vehicle goes around a corner. That is more realistic in that a vehicle travelling slowly does not need to slow down further to take a corner: the reason that vehicles take corners more slowly is not because it takes more energy to go around a corner (it does, but not to an extent that usually makes enough of a difference to rail or road transport to have a noticeable effect), but because there is a limit to how fast that vehicles can go around corners safely without skidding off the road or tipping over. The speed limit applies only for the time that the vehicle is in the corner, and is proportionate to the speed limit of the original way (the thinking being that the faster speed the track/road, the better designed/smoother that the corners are, and therefore the faster that vehicles can take them). The degree of reduction in the speed limit is increased as the speed of the way increases to reflect the fact that there is a limit on how far that smoother corners can help to make vehicles go around them at ever greater speeds.

More than that, I have made the extent of the reduction in the speed limit depend on how sharp that the corner is. This is what took most of the work (nearly two days of reworking the code). The sharpness is not based just on the extent of the corner in a single tile, and whether it is a 45, 90 or 135 degree bend (yes, 135 degree bends are possible inside a single tile in Simutrans): it is based on the overall bend over the last few tiles, so that, for example, a 45 degree bend to the left followed immediately by another 45 degree bend to the left is treated similarly to a 90 degree bend (although the code detects that the corner has been smoothed to some extent, and applies a lesser speed limit reduction in consequence). More than that: the number of previous tiles taken into account when deciding how sharp that the corner is depends on the base speed limit of the way: the faster the speed limit, the more tiles are taken into account. That means that, as in real life, the faster that one wants to go, the more important that it is to have the way as straight as possible, and the corners as smoothed as possible. For high speed rail, any corner will give a big penalty; conversely, for a slow line used by plodding freight or a local metro train, even fairly sharp corners all over the place will not make any noticeable difference.

Finally, I have implemented some code to simulate tilting trains (in the gameplay mechanics, that is, not graphically: graphical implementation of tilting trains is one of the "denied extension requests" because it is too hard to implement). That code is not fully complete, as I have not yet written the code to read a "tilting" property from a .dat file, but the basic logic is present in the new cornering code to take account of tilting trains, and allow them both to take corners at a higher speed than non-tilting trains, and also take into account fewer tiles in determining the overall tightness of any bend.

The overall effect of this patch will be, I hope, other than adding more realism to Simutrans, to make network design more interesting, in some respects easier, and in some respects more challenging. It will be easier in the early parts of the game, when dealing with old, slow trains and bulk freight, because corners will be far less of a penalty for slow traffic than they are now. It will be more challenging in later parts of the game because it makes the design of higher speed rail networks trickier because corners will be more of a penalty than they are now for high speed traffic. It will make network design more interesting because players will have to design their networks to suit the speed of the traffic that will be using them, and, crucially, redesign their networks as the traffic needs change over time with advancing technology.

One important feature of the history of railways that I am hoping that this patch will help to simulate is the fact that, when railways were first built in the 19th century, relatively slow and underpowered steam locomotives were enormously hampered by hills, but found corners to be of little trouble, since they went slowly enough to negotiate even relatively tight corners at near enough full speed. The railway building strategy, therefore, was to skirt around hills wherever possible. Conversely, modern high speed trains are powerful enough not to be troubled by all but the steepest of gradients, but have to slow down considerably for corners to be able to traverse them safely. The modern railway building strategy, therefore, is to go over hills in a straight line rather than around them. The additional challenge and interest in Simutrans will come when players have to adapt their early networks to meet the needs of modern transit, which may well involve substantial redesigning. That should help to keep the game fresh in the later stages.

I have not changed the cornering system for ships, since the added effort to turn corners is what makes ships slower in turning corners: transport vessels rarely go fast enough to be in any danger of tipping over when turning. I should be very grateful for any comments, questions or suggestions for refinement. I will look into how to read a tilting property from a .dat file, add that to the code, and update the patch when I can.

Edit: A newer, better version, compatible with the latest nightlies  (as of the 5th of January 2009), is now available here (http://forum.simutrans.com/index.php?topic=1157.new#new).
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: Combuijs on December 23, 2008, 10:00:59 AM
Interesting idea, well thought out!
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: Ashley on December 23, 2008, 10:18:55 AM
This sounds like a really well thought out patch, finally giving some reason to make smoother corners on high speed networks (will really introduce a great end-game challenge, in rebuilding networks to construct high speed links). Quite intuitive too, since it works the way one would expect it to.

Now if only we could have weight limited ways too :)
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: jamespetts on December 23, 2008, 10:38:49 AM
Quote from: Timothy on December 23, 2008, 10:18:55 AM
This sounds like a really well thought out patch, finally giving some reason to make smoother corners on high speed networks (will really introduce a great end-game challenge, in rebuilding networks to construct high speed links). Quite intuitive too, since it works the way one would expect it to.

Now if only we could have weight limited ways too :)

Ahh, I'm planning on doing that, too. As Prissi said in a recent thread, there's already some code for it, but it's not enforced during routing. The reason that it was not developed I suspect is because it was considered potentially too confusing for players to be told that their vehicles would not route if one of the bridges (etc.) along the way had a weight limit of less than the vehicle's weight. The way around that problem, I think, is to impose a less harsh consequence of exceeding the weight limit: instead of refusing to route at all, just make the vehicle go a great deal slower on the weight limited way if it is overweight (perhaps as little as 10% of the speed), with a big, visible notice (in the style of the "NO ROUTE" or "STUCK" notices) saying "VEHICLE OVERWEIGHT FOR WAY". That should add more interest to bridge construction without being too confusing for players (and could also make for interesting alternative track types using the weight limits).

In any event, I am glad that you both like the cornering patch. :-)
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: VS on December 23, 2008, 11:15:51 AM
If it does what you say, I can only applaud.

You keep finding areas of code where no additional input from non-coders is needed... that in itself is a huge advantage!

EDIT: allow me to clarify that - "input" meant further work, as in material input - new images etc.
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: Fabio on December 23, 2008, 12:03:49 PM
I can't wait to see this patch working... it's an awesome change! does it work also for highways?
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: DirrrtyDirk on December 23, 2008, 12:59:30 PM
Fabio, I can only guess but...

Quote from: jamespetts on December 23, 2008, 12:28:05 AM
Attached is a patch to change the way in which Simutrans handles corners for rail and road vehicles.

... my guess is: yes. ;)
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: The Hood on December 23, 2008, 01:54:24 PM
This looks good!  Hope it works...  As for weight restrictions, I agree with the speed restriction for overweight vehicles - it would be less confusing and also this happens in real life anyway (speed restriction should be very low, no higher than 20km/h, or at least that's what gets applied on Britain's railways).
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: prissi on December 23, 2008, 06:02:00 PM
Actually, the is a lot more energy needed to go around a corner due to fixed axes on trains. And tilting is just for the comfort of passenger, the physics of the carriages are not affected. Any trains could go as fast as a tilting train. Only then the comfort limits on the pasengers would be exceeded. (A very commond misconception, but often repetition makes in not any correcter.) You can prove that very simple because on trains like Talgo or X2000 the engines do not tilt ...

Apart form that, please obey coding rules, if you ever want to include your work. Every block must be closed, and on a sepearte line.

if(x) y; is forbidden

if(x) {
  y;
}

is the style. There is a file coding rules in the document folder.

Since calc_akt_speed is the second most time consuming routine in the game, could you please provide some profiling on the effect?

And finally I feel that a history of 16km is completely over the top. Two tiles or may be four is imho ok, this would cover switches and the like adequately. Also the fact that is immediately halves its speed when a it enters a curve is not too pleasent for me.
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: jamespetts on December 23, 2008, 07:16:51 PM
Prissi,

thank you very much for your reply :-) Sorry about the coding styles - I will change that and re-upload the patch when I have finished with weight limits. As to the history, the maximum currently set is 10 rather than 16 tiles, although the array is 16 items large to allow for overhead. There is an element of ambiguity with the distances, because Simutrans (purposely - for playability) uses two inconsistent scales at the same time: there is the routing scale of 1 km/tile, and there is the large scale of the actual trains, buildings, etc. I was aware of those different scales, and quite deliberately chose to align the cornering algorithm with the scale used by the length of the trains, rather than the 1km/tile scale, because that is what makes more sense: it is more intuitive and consistent if the scale adopted for the cornering algorithm is the same as for the length of the trains. Adopting the 1km/tile scale would mean that there would be virtually no interest or challenge in designing track, as almost any turn of any radius would have the same effect as any other: exactly the thing that this patch tries to avoid. With the full history, track has to be smooth in comparison to the length of the train: a far more pleasing and satisfying approach.

To put it another way, in a world where a train can be 10km long, it makes perfect sense for the corner history also to be 10km long. Of course, if there continues to be a substantial difference of opinion over the optimum level of history, I could just make all the values read from simuconf.tab, and let the users and/or pakset authors decide which is preferable :-) As for tilting trains, I take the point about the main reason for having them; that does not alter, however, the fact that tilting trains can take corners more quickly than ordinary trains, and the additional gameplay mechanics to which I refer ought still be included.

As to immediately halving speed, although that is not ideal, I do not think that there is an easy solution, since any attempt to read through the history when deciding whether to impose a speed limit resulted in erratic behaviour, including slowing on straights. Any attempt to read ahead and look for a corner in front would, I imagine, create significant computational overhead, as well as being enormously difficult to code. The original algorithm in any event was not much smoother: it, too, caused vehicles to first start slowing for a corner the moment that they entered a corner. Although this code does not produce movement as smooth as is ideal, that is a cosmetic matter in comparison to the function provided by the code itself. Any increased smoothness of reducing speed to match a new speed limit ought perhaps be implemented in the code for adjusting to new speed limits, rather than the code for setting the speed limits.

Finally, as to profiling, I have not done any formal profiling, although on the tests that I have conducted, performance was not noticeably hampered. The difficulty with profiling is that the version that I have of the source code contains not just the cornering algorithm, but a large number of other changes (to the speed bonus, to obsolete running costs, in respect of weight limits, etc.) that make comparison difficult. Is there a standard model of profiling that you would suggest, or a fixed method that you consider preferable in those circumstnaces?
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: VS on December 23, 2008, 08:30:15 PM
With all respect, the "tilting problem" is a fallacy:

If change in speed is dictated by [wheel] friction, moving car body is useless. The only way to involve something more than bogies I can see is throwing the body away bit by bit, creating a reactive engine opposing the force that pushes the car and its wheels to side ;)

Since tilting is done for passenger comfort, involving tilting as a variable must be necessitated by accommodating some cargo parameters - in other words, if tilting allows higher speeds, trains must slow down because of something going on "on board". Then a question arises, what with other cargos than passengers - glass for instance?

In other words, a decision must be made, if the model:
1) is strictly physics-based and simple - no tilting
2) is strictly physics-based and takes into account cargo - tilting ok, but new parameter for friction varying with carried freight (even if there is only one difference for psg.)
3) aims for "most fun" and follows physics only where it brings something interesting.

At the moment this seems to be (3).
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: jamespetts on December 23, 2008, 08:51:52 PM
VS,

the reason that trains slow down on corners is because the speed around corners is limited by regulations, not because it is harder for trains to push themselves around corners. Whilst there is some extra energy involved in a railway train cornering, that is limited in comparison to the necessity to limit the speed for safety and/or comfort reasons. Trains are almost always powerful enough to take corners far faster than is safe or comfortable to do so (in so far as they are powerful enough to go that fast on a straight section, at least).

As to tilting trains: the only tilting trains that exist in so far as I am aware are for passengers (no doubt because no other cargo is transported at speeds where tilting will make any difference). One would expect pakset authors to reflect this in their designs. Tilting most emphatically does enable trains to take corners faster than non-tilting trains: see here (http://everything2.com/e2node/tilting%2520train) and here (http://en.wikipedia.org/wiki/Tilting_trains) for information: that the reason that they can go around corners more quickly is for passenger comfort does not alter the relevance of the gameplay mechanic.

I don't understand the suggestion for varying friction with carried weight - the whole point of this patch is to replace the idea of corners adding friction with the idea of deliberately limited speeds on corners to ensure safety/comfort, because speed limits and not added friction are overwhelmingly the primary limiting factor in cornering speeds of trains.
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: jbode on December 23, 2008, 09:37:07 PM
Hi, as soon you have friction --> wheel flange is touching the track ... you will have a real serious problem. In normal operation the wheel flange should never touch the rails. Railroad wheels are conical and directly connected, so in curves the different radius (resulting by shifting the touching region of the conical wheels) keeps the train on track. Trains having a side motion around the needed wheel position - this is stabilizing the movement.

Problems coming up when trains are to slow in a banked track (such tracks are then not planned for being slow ;) ), or when moving over switches (most people know the ugly sounds...). Switches are an important reason to slow down traffic. In Germany we had some wheel defects on high speed trains. The main candidate to have caused to much stress on the wheel/axle structure are likely the switches and worn out tracks from other traffic. All other countries have their high speed trains completely separated from normal commuting and freight train system ...

As said above the tilting trains are purely for passenger comfort - to compensate for centrifugal force. The human sense of balance does not allow too much force to the side ... Miscomfort will prevent people from traveling such trains. Even when 95% could not determine why it is feeling peculiar ...
Tilting of trains is not necessary for goods transport. Any good to be carried needs anyway to be packed properly ...

Speed limit to be applied on freight trains are caused by weight (stress on track, needed energy to accelerate and braking distance). Sure not forget the stress on the vehicles ..., but less important ...

Jörg
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: VS on December 23, 2008, 09:46:59 PM
Ok, I have re-read your first post... this makes sense. Apologies for the misunderstanding.

(One problem is that you hide the important bits of information in too much text, but so do I, often...)

That said, perhaps instead of tilting on/off, the safe corner speed (fraction?) itself could be part of vehicle definition, configurable by author? I can imagine that flat railcars can turn faster than doubledeckers.
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: prissi on December 23, 2008, 10:49:03 PM
Actually most trains do not have to slow down in corners on mainline tracks apart from some very curvy riverside track or highspeed (and that means more than 160km/h). Even for devoted highspeed lines like in France or Japan the corner speed is not limiting the total speed, since the track is tilted enough.

Only for mixed operation the track tilting is limited to avoid a starting good train to fall over on the tilted track. But the speed is only limited for comfort reasons. Or how was is possible to go 480 on a track built for 260 for the german ICE? (For the world record 45km was needed ... )

On the same note, the TGC doing the 571 km/h also did many curves with much higher speed than allowed. But alle those records were done near the end of straight stretches because friction is severe in curves, as written before. This gets even worse with higher speeds, since the centripetal forces are stronger and thus friction of flanges and track increase proportional to the applied pressure (with is quadratic to the speed, if memory servers me correctly).

And even the very run of the mill switches can in principle stand 80km/h. Only several switches close together are closing problems, i.e. left and then right. With this in mind one could think about limiting speed for two subsequent direction changes. Thus would require much less overhead and would not destroy the relative smooth movement of the friction code.
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: jamespetts on December 23, 2008, 11:58:01 PM
Prissi,

it may be different in Germany, but speed restrictions due to tight corners are very common on UK railways. As noted in the original post, the fact that older railways were built around hills (incorporating more bends but fewer gradients) is a problem for modern trains, needing fewer bends but not having such a difficulty with gradients. That is part of what I want to simulate with this patch.

It may well be that experimental runs of record breaking trains need straight track so as to minimise energy dissipation, but that is a long way from the constraints of normal operation. Really, to circumvent any disagreements, the sensible thing will be to make the values for the corners adjustable in simuconf.tab so as to let pakset authors and/or end users decide the numbers for the cornering code: there is little point in debating what hard-coded values could be when it is quicker to make the values user-adjustable ;-). It would even be easy to have a "use old cornering algorithm = 1" option to give people the choice between my way of doing it and the old "friction" method.

I am not sure that I follow about subsequent direction changes and the friction code: the idea of using friction as the limiting factor for corners is a problem, since it has the bizarre effect of slowing a train however slow that it is going to start with (and, as you noted in the opening of the post, many trains do not have to slow down at all for corners - if the corner is wide enough, and the train is slow enough, at least), and making the extent to which a train slows on a corner dependant on how powerful that the locomotive is. The code that I have written does take account of cumulative direction changes - that is part of the point of it (to encourage smoother corners). I am not sure how this could be accomplished with less overhead without compromising function.

As to switches - if there is an easy way of detecting when a vehicle is currently passing over a switch, it should be easy to code a speed limit for that, too. What I will do is make all of these settings user-adjustable in simuconf.tab, and upload a new version of the patch (with the corrected coding style) and we can take it from there :-)
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: isidoro on December 24, 2008, 12:53:25 AM
My idea:  why not a combination of Prissi's and James'?

Let there be a fiction but make that friction depend on both speed and corner history (the friction can even be zero for open curves or low speed).  The idea is to make the train speed look smooth while preserving James' ideas.


Second point (in connection to but apart from this one):

Once the code is built for the history of a vehicle, why not taking into account also slopes?  I don't like the way it looks a vehicle climbing a mountain straight.  It is more natural to build a road snake-like.  I always do that, now for aesthetic reasons.  An example in the image:

Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: jamespetts on December 24, 2008, 01:06:56 AM
Isidoro,

an interesting idea, but that would not address the real problems with having corners increase friction: (1) they will slow all trains, regardless of how slowly that they are already going; and (2) the extent to which corners affect trains will depend on the power of the locomotive. Those are the fundamental reasons that I changed from increasing friction to lowering the speed limit. Smoothness, if desired, can be implemented elsewhere (if it is not too computationally expensive).

The gradient history idea, however, is a very interesting one indeed, and deserves further thought. Perhaps you could code a patch?
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: prissi on December 24, 2008, 10:30:16 AM
The friction does not work the same for all speed, since its enters non-liniear in this equation. But of course the friction could depend on the maximum speed or the current speed (this would just require to change a very few lines in simconvoi.cc).
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: The Hood on December 24, 2008, 10:57:25 AM
Seems to me a combination of the two could be best because
1) friction does apply on corners, so from the pure physics of it, trains will always slow down when cornering unless they have the power to accelerate quickly enough to counteract this
2) trains in commercial operation are made to slow down on corners anyway for safety / comfort reasons

So I propose the following logic:
- to address point (1) above, use a friction component to decelerate the train (as now?) - but maybe this needs to be tweaked to be less severe for lower speeds.
- to address point (2) above, *also* impose a speed restriction around the corner depending on shape of curve (encourages straight/smooth track for higher speeds later in game, so probably ~4-tile history) which is not enforced (or less severe) for tilting trains (for a real life example, take the newly modernised West Coast line in the UK - tilting trains are permitted to travel at 125mph, non-tilting are restricted to 100mph).

This way you are encouraged to allow for higher speeds on your network by building straighter track with smooth curves (e.g. French TGV network) or buy expensive tilting trains (e.g. UK West Coast) to allow higher speeds on existing curvy routes, whilst keeping physical principles intact (routes with lots of corners have always needed higher power locos anyway to get over problem 1). 

As an aside, implementing this could also be used to make the new narrow gauge trains better at cornering than standard gauge (e.g. have less severe speed restrictions for equivalent corners, and maybe reduce the friction deceleration effect).  Narrow gauge trains were used in mountainous regions because they could corner easily and take long curvy routes up hills without so many problems, and this could be encouraged.
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: jamespetts on December 24, 2008, 01:17:49 PM
I suspect that we are not going to reach an agreement on the importance of friction in cornering: I still strongly take the view (see here (http://everything2.com/e2node/Advanced%2520Passenger%2520Train), for example) that the primary limiting factors for cornering is safety and/or comfort, and that the additional drag caused by cornering almost never stops a train from going the full speed that it is allowed to go around the corner without any non-trivial more difficulty than it would have going that speed on the straight.

However, we do not have to agree: a friction factor on corners can be made entirely optional in simuconf.tab. What I can do is add a "cornering_friction_coefficient" line to simuconf.tab, and also a "restricted_speed_cornering" line (1 for on, 0 for off). The first would be the value of the additional friction to be added (as in the original code, which would be executed before the speed limit code; 0 would bypass that block of code entirely), and the second would determine whether any of my new code is executed. I could also smooth the speed limit variation factors (so that track with a speed limit of 395kph does not allow faster cornering than track with a speed limit of 400kph), and make those values customisable in simuconf.tab as well.

The narrow gauge point is interesting - from my understanding, the broader the gauge, the more stable that the train, and therefore the faster that it can take a corner: that is why the GWR used broad gauge in the early years: to enable higher speeds. The advantage of narrow gauge track is that both it and the trains that run on it are cheaper. It is certainly easier to build narrow gauge track around a corner, but I strongly doubt that a narrow gauge train can take a corner of any given radius faster than a standard gauge train: if anything, the opposite would apply.

Because of the physical characteristics of the trains, one can have sharper corners on narrow gauge track than it is possible to have at all on standard gauge track without the axles locking up entirely, but the trains cannot take them any faster than they can at standard gauge. Unfortunately, Simutrans does not enable a sufficiently fine-grained implementation of corner radii to be able to simulate the differences in allowable minimum radii for narrow gauge in a useful way.
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: isidoro on December 25, 2008, 01:40:31 AM
My point about friction was not that, James, I'm afraid.  It is a more practical one.  We want trains to be slowed at corners.  Today's method can be improved.  Your suggestion is: for reasons A and B, I want a speed limit on curves that is a function of some variables: sl(speed, curve radius, etc.)

My suggestion is: once we know the enforced speed, let's work the way back: let's calculate what friction will be needed for the vehicle to get to that speed and apply that friction.  Simple.  If a similarity to real life is wanted, that friction will come from the brakes of the train to slow it down, not from the corner itself...  Would be more natural than a sudden reduction of the speed to half the value.

Now an evil twist: when a car is approaching another car and not overtaking it, the speed reduces to zero.  Can some friction be applied to it instead, enough to make them not crash? (I would like an evil emoticon here, but don't have it  :'( )  I love emoticons so much...

Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: KrazyJay on December 25, 2008, 11:09:37 AM
Don't take it personal James, this is the way simutrans works, I never got used to it either... but I guess eventually there will be a patch that pleases both you (representing the ambitious newbies) and the dedicated old folks (not in age but in yrs spent on this game). And that's what we all need :D
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: jamespetts on December 25, 2008, 04:06:54 PM
Isidoro,

ahh, so you thought to use friction to simulate smooth breaking, rather than to simulate corner friction? Then that makes more sense - but there is a problem: it would likely be very computationally expensive to calculate for each corner exactly what level of friction is required to be added to slow the train to the correct speed within a reasonable time: the current speed of the train, its weight, its power, and the desired speed limit would all have to be computed for each train for each corner; Prissi was already concerned that the algorithm as it is might slow things down (noting that the calculation of a vehicle's speed at any given point is one of the most computationally expensive aspects of the game engine).

Also, I have just checked: any reduction from one speed limit to a lower speed limit involves the vehicles slowing down just as rapidly as they do with this cornering algorithm. It makes sense that, if a corner is treated as imposing a speed limit, the smoothness of reduction of speed in a corner should be the same as for any other speed limit. It would be nice to smooth all speed limit reductions, but I have doubts that it can be done without unduly impacting on performance. If somebody can code something for any speed limit reduction that does not unduly impact on performance, that would be a good addition to Simutrans generally, but ought not be considered a prerequisite for the adoption of this patch, since it addresses an entirely different issue.

I am not sure what you mean about the car thing: do you mean that they stop too suddenly behind other cars? That is not new after my patch, is it? I think that they do that in any event.

KrazyJay,

the patch that pleases everyone is, I hope, the one that is programmed to allow people to set in simuconf.tab how they want things to work, so that all the different preferences can simultaneously be accommodated. If everyone can have what they want at once by adding more options, there is no need to debate or compromise on which setup is the best ;-)
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: Fabio on December 25, 2008, 04:44:09 PM
Couldn't be possible, to look - say - 4 tiles ahead looking for a speed limit (either imposed by tracks, either by corners) and, if so, start reducing gradually the speed?
These limits could be considered by the routing procedure the way signals are, using the smooth breaking used for a red signal.
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: jamespetts on December 25, 2008, 04:55:03 PM
Quote from: fabio on December 25, 2008, 04:44:09 PM
Couldn't be possible, to look - say - 4 tiles ahead looking for a speed limit (either imposed by tracks, either by corners) and, if so, start reducing gradually the speed?
These limits could be considered by the routing procedure the way signals are, using the smooth breaking used for a red signal.


That would be better, certainly - but I'm worried about the impact on performance. If looking a number of tiles ahead is already done in the signalling code, however, it might work. Indeed, the calculation of the speed limit could be done x tiles ahead instead of on the fly, rather than as well as, making the computation not take much longer (except when it first starts, when it will not have any data as to the next tiles). Do you happen to know where the look-ahead part of the signalling routine is in the code?
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: VS on December 25, 2008, 05:17:52 PM
Not much on topic, only on the programming techniques mentioned...

Look-ahead is costly only if you read N tiles for every tile advanced, if you keep "driving" the virtual convoy head in front of it and remember what you passed, you have to read only one tile per advance again... I don't know how to explain this better. But the question can be freely chosen from "is looking at more tiles [from map] per move costly" and "is looking at more data [of any form] costly".

Also the relevant data structures could be implemented as a linked list or some other container that has zero cost for returning from end to front and linear cost for any add/remove operations with items.
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: jamespetts on December 25, 2008, 05:46:31 PM
VS,

ahh, that's a good point. A linked list would also make the curve history functions faster. Does anyone know whether there is a generic linked list class already in Simutrans that I can reuse? Otherwise, I will write a new one.
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: VS on December 25, 2008, 07:22:32 PM
Perhaps the closest thing is slist_tpl...
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: prissi on December 25, 2008, 08:54:39 PM
Lists are evil with modern computer, since they are scattered all over caches and the idex of an element cannot simply calculated. Why not just sum up the last cornering movement with a counter? 45° +1, 90° +2 and decrement by 1 each step. The result would be multiplied with the friction factor. That would make very slow movements in switches, but fast on a single curve and would be very low in computation costs.
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: jamespetts on December 25, 2008, 09:07:09 PM
Prissi,

using the friction factor for setting the speed for cornering at all defeats the whole purpose of this patch, which is to remove the twin problems of (1) the speed being reduced on a corner even if the speed is very low; and (2) the vehicle's power having an effect on how well that it corners (any increase in friction will inevitably do both of these things). I am in the process of implementing VS's suggestion now, and also making the code that I have already written for cornering considerably cleaner, which I hope will make cornering work well and quickly, and also smooth speed limit transitions.

Edit: Incidentally, the lists that I will be using should not be too evil, since they will be trimmed to only a few items (as many as are needed) each hop.
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: isidoro on December 26, 2008, 01:38:13 AM
Quote from: jamespetts on December 25, 2008, 04:06:54 PM
[...]
I am not sure what you mean about the car thing: do you mean that they stop too suddenly behind other cars? That is not new after my patch, is it? I think that they do that in any event.
[...]
No.  It has nothing to do with your patch.  Something talked about elsewhere.

Quote from: jamespetts on December 25, 2008, 04:06:54 PM
[...]
the patch that pleases everyone is, I hope, the one that is programmed to allow people to set in simuconf.tab how they want things to work, [...]
One has to be careful, though.  I cannot fully agree for three reasons:

Quote from: VS on December 25, 2008, 05:17:52 PM
[...] Also the relevant data structures could be implemented as a linked list or some other container that has zero cost for returning from end to front and linear cost for any add/remove operations with items.
I wouldn't use a linked list myself.  I would use a fixed size array with two indices (head and tail) and modulus operation.  Or something similar to Prissi's counting of changes.
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: jamespetts on December 26, 2008, 11:26:44 AM
Quote from: isidoro on December 26, 2008, 01:38:13 AM
No.  It has nothing to do with your patch.  Something talked about elsewhere.

Ahh - can you tell me where it was talked about? I don't think that it was on these English language forums, or else I'd probably have seen it. What is the problem, exactly? What are the steps necessary to reproduce it?


QuoteOne has to be careful, though.  I cannot fully agree for three reasons:

     
  • I get lost when trying to play OTTD with so many options.  I don't know if it is a game or many games in one.
  • Size of executable can have an impact in speed.  And, here, size does matter. ;)
  • Code has to be maintained.  Some options conflicts with others or complicate programming of new capabilities.  Some are even lost in nowadays code and never used again.  For instance, when programming overtaking, driving on the left (optional) made the code larger and more difficult to program.

If the options are in simuconf.tab, only users who know what they are doing are likely to go there in the first place; that will not, therefore, confuse newer players. Pakset authors can then use the program in a more flexible way, determining which options are used. The size of the executable should not be non-trivially increased by my cornering code: it is a drop in the ocean compared with the rest of the code. As to the maintenance of code: there is nothing about the cornering system that is particularly difficult to maintain; I am currently working on putting the new code for cornering and weight limits in a separate method to make maintenance easier. If there is a substantial disagreement between people on how best to do something, that means that there is a substantial demand for both ways of doing things, which is itself a strong countervailing reason to have multiple options.

Edit: Can you explain a little more about the sort of array that you suggest?
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: Fabio on December 26, 2008, 01:22:38 PM
Quote from: jamespetts on December 25, 2008, 04:55:03 PM
Indeed, the calculation of the speed limit could be done x tiles ahead instead of on the fly, rather than as well as, making the computation not take much longer (except when it first starts, when it will not have any data as to the next tiles).

This would be great and also wery realistic, because each vehicle in RL is driven taking into consideration what is expected to be on their way in the next few km. the number itself of tiles ahead could depend on the max teoretical speed for a given vehicle (a high speed train will consider more kms of way ahead rather than a slow truck, because their braking time is different). and if this routine limits the speed in switches as well, this is good, because switches slow down trains in RL as well.
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: corsa319 on December 27, 2008, 12:45:15 PM
Quote from: jamespetts on December 23, 2008, 08:51:52 PM
VS,

the reason that trains slow down on corners is because the speed around corners is limited by regulations, not because it is harder for trains to push themselves around corners. Whilst there is some extra energy involved in a railway train cornering, that is limited in comparison to the necessity to limit the speed for safety and/or comfort reasons. Trains are almost always powerful enough to take corners far faster than is safe or comfortable to do so (in so far as they are powerful enough to go that fast on a straight section, at least).

As to tilting trains: the only tilting trains that exist in so far as I am aware are for passengers (no doubt because no other cargo is transported at speeds where tilting will make any difference). One would expect pakset authors to reflect this in their designs. Tilting most emphatically does enable trains to take corners faster than non-tilting trains: see here (http://everything2.com/e2node/tilting%2520train) and here (http://en.wikipedia.org/wiki/Tilting_trains) for information: that the reason that they can go around corners more quickly is for passenger comfort does not alter the relevance of the gameplay mechanic.

I don't understand the suggestion for varying friction with carried weight - the whole point of this patch is to replace the idea of corners adding friction with the idea of deliberately limited speeds on corners to ensure safety/comfort, because speed limits and not added friction are overwhelmingly the primary limiting factor in cornering speeds of trains.

One of the reasons trains tilt is because if a HST for example went around a tight curve the g forces and aerodynamics would change to cause it to A: come of the rails B: Half of the wheels would come of C: Everyone would be thrown about, the dynamics of trains is explained on this video http://uk.youtube.com/watch?v=BbTD9maVBek hope that makes sense.
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: prissi on December 27, 2008, 01:42:51 PM
Sorry, I am teaching physics at university and I can assure you modern train derail mostly on switches with radius smaller than hundred meters or so. Any other normal track cannot exert the necceesary g-force. Even more, the world fastest trains do not have tilting.

Especially the TGV has a quite "aggressive" track routing, since it can tilt the tracks without taking care of freight trains falling to the inner side when stopping in such a curve.
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: corsa319 on December 27, 2008, 02:02:15 PM
Hi thanks for that answer but did you know that french railways are straighter than almost every railway in BRITAIN! That is why they are so fast also all trains have a limit of speed they can get to before coming off as it is impossible to go round a corner at any speed. Tilting trains only go a small amount faster but it makes up for in time on the long distance routes like the APT-P could have knocked hours of of the west coast mainline. Also many countries in europe have tilting trains like sweden (my partial home) has many and they have some of the fastest trains in Europe.  ???
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: prissi on December 27, 2008, 02:17:02 PM
All really fast trains run on dedicated tracks. Epsecially since crossings, slopes and noise emmission prohibit normal tracks. The X2000 is not especially fast given ICE/Valero, Shinkansen and TGV. Moreover, only the cars are tilting with the X2000, the engine is not as far as I know.

Also the Shinkansen is not very straight, given that Japan is a hilly country. But they allow heigher tilting of track and steeper slopes (some as french) for those high speed only tracks.

Tilting is only for comfort (or should be, the swiss trains I found either the tilting makes me retching). This can be easily seen that heigher corner speeds are allowed for the Talgo (I saw that between Portland and Seattle in the US), which is a passive system. Even more, with tilting the center of gravity on a passive system is farther out from the center, i.e. such trains should fall over more easily. Also in this case the engine was the same as used for the regular trains.
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: corsa319 on December 27, 2008, 02:45:53 PM
Yes also with the shinkansens of japan they rebuilt there whole railway for speed and so it is. One driver was fired for being 2 minutes late and they have never had a crash or derailment... YET!
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: DirrrtyDirk on December 27, 2008, 03:55:23 PM
Quote from: corsa319 on December 27, 2008, 02:45:53 PM
they have never had a crash or derailment... YET!

Well, they had one - during an earthquake.
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: corsa319 on December 27, 2008, 03:58:54 PM
fair enough
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: KrazyJay on December 27, 2008, 06:58:05 PM
I guess the whole discussion is caused by misinterpretation of the definition of tilting. Tilted tracks do help stability and do allow trains to go around corners faster, but tilted trains on flat tracks can go just as fast as regular trains on the same tracks. Tilted trains only serve convenience. Goods and mail don't compain much about car-sickness and nausea, so non-passenger trains are commonly not tilted trains but can drive on tilted tracks.

Still I think the work James has done is good work. It helps us keeping Simutrans in the same age as RL is. Even a little increase in the use of system resources wouldn't make too much of a problem for the vast majority of Simutrans players.
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: isidoro on December 27, 2008, 08:41:04 PM
Quote from: jamespetts on December 26, 2008, 11:26:44 AM
Ahh - can you tell me where it was talked about?
I'm sorry.  I've tried to find it to no avail.  It was a topic talking about that the way a road vehicle stops when reaching another is very unnatural.  It works like this:  when a road vehicle enters a new tile and that tile is occupied by another vehicle in the same direction, it stops abruptly.  In that topic, it was suggested to look for a way in which the following vehicle would adapt its speed to the one in front of it and just queue.

Incidentally, I remember that Zeno participated in that thread.  It was funny to me that the thread had so many things in common with Zeno's paradoxes about the continuity of movement.   ;D

Quote from: jamespetts on December 26, 2008, 11:26:44 AM
Edit: Can you explain a little more about the sort of array that you suggest?

Simple.  With a linked list you have to store the data and one/two pointers to link the following/preceding cells.  Too much memory.  And you have to reserve and free a lot of cells.  Too complicated.  Since the size of the array would be small, it is easier to put a fixed size circular array (even of chars) and two (even one) indices to tell us where the head of that circular array is.

[-][-][7][6][8][-][-][-]
       ^H    ^T

H stands for Head and T for tail (in the example above, H=2, T=4).  It's very easy to add/remove items at both sides and if you pack everything in a char array, you can have a 6 items array for the price(size) of two ints.

But I recognize that I'm too low-level biased...  :police:

Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: VS on December 27, 2008, 09:56:37 PM
On the data structures - it is probably silly in the end. Division isn't something to be afraid, especially if it's power of two :P




If you are still interested in the list idea:

First I indeed thought items could be popped and appended (deque?). But it can be improved really simply. You could join end with front, and then simply "rotate" or "move forward around it" two heads, one writing the way in front, one reading it. Once you create this structure, no changes to memory except the values itself. Also backward pointers are not needed since heads always move forward.

You could even create this in a flat array and store value and offset of next item, so that all items are +1 and at the end -N and manipulate index with this... many ideas. But they require always only dereference and addition, no?
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: jamespetts on December 27, 2008, 10:03:20 PM
Update: I am currently working on a new data structure at present, which I am making in template form so that it can be used generally in Simutrans (and, indeed, anything else opensource). It is designed to be an ultra-light array based list of 32 or fewer items (a fixed sized array is used: the number can simply be manipulated in the code, of course). I will post it when it is done.
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: jamespetts on December 28, 2008, 12:11:12 AM
I have now written a very lightweight class in a header file, but cannot for the life of me get the program to compile: whenever I add:

#include "../tpl/fixed_list_tpl.h"

to one of the existing files, I get dozens of cryptic errors, stating that I am missing a semicolon before the first line of code below the #include statements, even though there would never be a semicolon there normally, and there was no semicolon there before. Removing the reference to my new file allows it to compile. I get the impression that the file is somehow not properly included for compilation, but I cannot find a way of adding it: when I try Project>Add Existing Item (in MS VC++) and add fixed_list_tpl.h, it has no effect (and is actually the only header file added in that way: the others seem to work fine without explicitly being added!).

For reference (for the low-level fans), here is my code:

/* A very light 32 or less element list
* using a fixed sized array with a
* head and tail node. Template type.
*
* Author: jamespetts. Released under the terms
* of the Artistic Licence. Intended for use
* with Simutrans, but may be used elsewhere.
*/

#include <typeinfo>
#include "../simtypes.h"
#include "../simdebug.h"

template<class T> class fixed_list_tpl
{
fixed_list_tpl() : size(0), head(0), tail(0)   { }

public:

T get_element(uint8 e)
{
if(e > size)
{
return NULL;
}
else
{
uint8 i = add_index(head, e);
return datum[i];
}
}

void clear()
{
size = 0;
head = 0;
tail = 0;
}

void trim_from_head(uint8 trim_to)
{
if(size <= trim_to)
{
return;
}
else
{
head = add_index(head, trim_to);
size -= trim_to;
}
return;
}

void trim_from_tail(uint8 trim_to)
{
if(size <= trim_to)
{
return;
}
else
{
tail = subtract_index(tail, trim_to);
size -= trim_to;
}
return;
}

uint8 get_size()
{
return size;
}

void add_to_head(T datum)
{
uint8 i = subtract_index(head, 1);
data[i] = datum;
head = i;
if(tail == head)
{
tail = subtract_index(head, 1);
}
else
{
size ++;
}
}

void add_to_tail(T datum)
{
uint8 i = add_index(tail, 1);
data[i] = datum;
tail = i;
if(head == tail)
{
head = add_index(tail, 1);
}
else
{
size ++;
}
}

bool add_to_head_no_overwite(T datum)
{
if(size < 32)
{
add_to_head(datum);
return true;
}
else
{
return false;
}
}

bool add_to_tail_no_overwrite(T datum)
{
if(size < 32)
{
add_to_tail(datum);
return true;
}
else
{
return false;
}
}

uint8 get_index_of(T datum)
{
uint8 tmp = 999;

for(i = 0, i < 32, i++)
{
if(data[i] == datum)
{
tmp = i;
break;
}
}

if(tmp > 31)
{
return NULL;
}
else
{
uint8 index = subtract_index(tmp, head);
return data[index];
}
}

private:

T data[32];

uint8 size;

uint8 head;

uint8 tail;

//These methods are used for automating looping arithmetic
uint8 add_index(uint8 base, uint8 addition)
{
uint8 tmp;

if((base + addition) < 32)
{
return base + addition;
}
else
{
tmp = (base + addition) - 32;
}

if(tmp < 32)
{
return tmp;
}
else
{
//There could be a sophisticated system of trimming here,
//but it would take extra work/memory/processing power, and
//is only used internally, so not worth it. This code should
//never be reached.
return 31;
}
}

uint8 subtract_index(uint8 base, uint8 subtraction)
{
uint8 tmp;

if((base - subtraction) < 32)
{
return base - subtraction;
}
else  //Will be > 32 if has gone to < 0, as unsigned ints are used: overflow.
{
tmp = (base - subtraction) + 32; //Should re-set the overflow
}

if(tmp < 32)
{
return tmp;
}
else
{
//There could be a sophisticated system of trimming here,
//but it would take extra work/memory/processing power, and
//is only used internally, so not worth it. This code should
//never be reached.
return 31;
}
}
}


I should be very grateful for any ideas on how to make it compile properly with the other code.
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: isidoro on December 28, 2008, 02:43:41 AM
I'm deeper low-level still  8)   ;)

Perhaps the missing semi-colon is at the end of the template class definition?

One suggestion: why making the 32 part fixed and not variable/adjustable, yet constant.
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: VS on December 28, 2008, 10:18:48 AM
Yup, my C++ reference says there should be a semicolon after final } of template.
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: jamespetts on December 28, 2008, 11:39:57 AM
Isidoro/VS,

excellent, thank you, that did it. And I will take your suggestion, Isidoro, and make the number a const so that it can be changed by changing a one line definition, instead of a number of values.
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: VS on December 28, 2008, 12:22:45 PM
You could even make it a template parameter?
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: jamespetts on December 28, 2008, 12:30:33 PM
Quote from: VS on December 28, 2008, 12:22:45 PM
You could even make it a template parameter?

Hmm... how would I make a const a template...? Or have I misunderstood you? (The class is a template class...)
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: VS on December 28, 2008, 12:47:59 PM
...
template<class T, int N=32> class fixed_list_tpl
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: jamespetts on December 28, 2008, 12:57:44 PM
VS,

ahh, excellent idea - thank you :-) Makes it much more flexible and efficient. I hadn't even realised that that was possible with C++ until now.
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: jamespetts on December 30, 2008, 10:23:39 PM
I have finally perfected my fixed list design (attached as a header file - feel free to use under either the Artistic Licence or the GPL v. 2 for anything), but am having trouble applying it to the reading ahead of the way in Simutrans. I have attached a patch with my code as it currently stands, but, as will be apparent from trying it, it does not work reliably: the speed ought be smoothed, but this does not appear to work well in practice; also, corners are often either ignored or under-estimated in severity, and the speeds set for them too high. I suspect that the problem might be in the synchronisation of the various different sets of data (the tile itself, whether any given tile is a corner, the speed limit for that tile, and the previous direction if it is a corner), although working out how to synchronise them is not in the least easy.

I should be most grateful if anyone could take a look at the code and give me some pointers as to how to progress from here; I have spent much time on this speed smoothing code, and I very much hope to be able to move onto more straightforward things (such as adding a cumulative effect for consecutive slope tiles as requested earlier in this thread), and for adding weight limits to bridges and tunnels. Any assistance would be greatly appreciated.

Edit: Updated versions of the files attached: see post below.
Title: Re: [Patch] New cornering algorithm - allows for tilting trains
Post by: jamespetts on January 01, 2009, 04:57:29 PM
Update:

I have now found and fixed a number more bugs in the fixed list class: an updated version has been added to the post above. I have also replaced the original patch with a heavily updated one, although I am still having considerable problems making the corner smoothing (and, indeed, any degree of look-ahead for the speed limit at all) work, and would very much appreciate any help.

I have attempted to solve the synchronisation issues by putting the speed limit data in a hashtable with a pointer to the particular tile in respect of which it is the speed limit as the key, and then retrieving that data by obtaining it from the hashtable using the pointer to the current tile, obtained the usual way for every hop. I still have a fixed list for a fixed number of future tiles, and a method for setting the target speeds (in the hashtable) by reading that list sequentially. I have found that, for some reason, the current tile seems to jump backwards in relation to the route index, and so have written code to repopulate the lookahead table backwards from the current position whenever it jumps behind what is still stored. The code in the modified patch is also considerably cleaned of old commented-out code that should make it much easier to read.

However, the program still does not work reliably. The trains will sometimes slow to a crawl on the straight (the correct speed for a hairpin bend), and take 90 degree corners at full speed. Any assistance in making this work would be very much appreciated indeed, especially as I have now spent about four days doing almost nothing else.

Edit: A further problem: testing it informally against the default 101 binary (r2197) for speed on a fairly large save game in Pak128, the speed seems greatly reduced: fast forward does not even double the speed on the modified version. I have some doubts that any speed limit smoothing will work within a reasonable level of performance because of the enormous complexities that I discovered when attempting to read ahead in the code (it is not as simple as has been suggested above of simply looking for the speed limit a number of tiles ahead and reading from that number of tiles down the list: the routing system appears to be internally inconsistent in unpredictable ways, and a record must be kept of whether all of the previous tiles were corners and what the direction of their previous tile was in order properly to compare for corners, all of which records must be synchronised with each other and with the current position (the latter of which appears to behave erratically and requires regular re-synchronisation). Adjusting for those complexities in the read-ahead code is probably what causes the performance impact.

I should still be very grateful for anyone to look at the code (and the light-weight fixed sorted list is available for anyone's use), but I have doubts about the future of speed limit smoothing due to the performance impact of the necessarily enormous code. If anyone can look at my code and find a way of doing it better with less of a performance impact, I should be extremely pleased. My view at this stage is that, unless anyone can rework the code to minimise the performance impact, the best way forward is to revert to a modified version of my original code (using the fixed sorted list) for speed limits, without smoothing, but still applying a system which checks the overall angle of the bend within a given number of steps and reduces the speed limit accordingly instead of (unrealistically and somewhat bizarrely) applying additional friction to the corners (which has the anachronistic effect of slowing all vehicles, even if they are already travelling extremely slowly, and making more powerful vehicles less affected by corners than less powerful ones). The speed would not be smoothed, but it is not in any event in the default code for changes of speed limits due to anything else, so the effects of the modified code would not be greatly different to the present situation in respect of speed limit transitions. Despite the sudden slowing, I still maintain that the original code is preferable to the default code in that it is more intuitive, more realistic, and gives players more interesting incentives to smooth their high-speed networks (but not so much the low speed ones, in respect of which there would be fewer incentives to make them straight: just as in reality).