News:

SimuTranslator
Make Simutrans speak your language.

bidirectional and can_lead_from_rear

Started by Vladki, September 22, 2016, 08:45:04 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Vladki

The wagons in my test have no constraints at all

Vladki

Nice analysis ranran. I think the fix for reordering shouldn't be dependent on whether the coupling is fixed or not. American F class engines (f7, f9) can also form a multiple unit like "kokakola" even with one or two cabless booster units in the middle, but are not permanently coupled.

Also keep in mind that not all vehicles in pak128.cs have properly set if they are bidirectional or not. It is work in progress.

jamespetts

As I posted in the thread to which Ranran referred a moment ago, it is difficult on current information to deduce whether this is better treated as something which requires a relatively minor bug fix (which will not make any serious changes to the code or add new abstractions or similar), or something which requires a substantial new feature, which will have to wait in the long queue of development tasks for new features unless someone would like to do it sooner than I have the time to deal with it.
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.

Vladki

I'm willing to try the coding part. However the question remains how it shoudl be implemented. What do you think about may previous suggestion:

Quote from: Vladki on November 14, 2016, 10:57:22 PM
bidirectional = 0 would be only those vehicles, that cannot run in reverse at full speed: i.e. steam engines with tender
bidirectional = 1 would be all that can run in both directions at full speed even if they have only one cab, i.e almost everything.
CLFR=0 would be set on vehicles that do NOT have a cab in rear: F7, front part of Dm3, front unit of pendolino/TGV and similar units.
CLFR=1 would be set on vehicles that have a cab in rear: i.e. driving trailers, rear unit of pendolino/TGV, rear part of Dm3, reversed F7 (I suppose that they can be run back to back), and all modern diesel and electric engines that have cab on each end, or have a cab in the middle (shunters like this https://cs.wikipedia.org/wiki/Lokomotiva_210). Steam tank engines fall in this category too.

I admit this would require changes in the pakset as well, but will be clear and explicit.
(Funny reordering with brake vans is another topic, but might need to be dealt with at the same time.)

Or maybe even two values - has_front_cab = 0/1, has_rear_cab = 0/1. This could be used also to show what can be in front of train.

jamespetts

Thank you for offering to code this - that would be most helpful.

As to your proposed scheme, I am a little unclear on how some aspects of this would work, especially relating to "can lead from rear". The current intention of this datum is to mark those vehicles which, when at the rear of a train as formed in the depot, can be at the front of the train when running in the opposite direction to allow the train to reverse just by going backwards rather than altering the formation in any way. This is consistent with most of the examples that you give, such as driving trailers, the rear vehicle of multiple units, etc., but you also refer to steam tank engines, which clearly do not fall into this category. I am not sure that I understand the relevance of steam tank engines here. They would not be at the rear of a train (except for an autotrain - but this is best dealt with by having the autocoach with the can_lead_from_rear bit set), but would have to run around the train to haul, rather than propel it, from the front in both directions. The only significance of steam tank engines is that the engine itself does not need to be rotated on a turntable, which is relevant to the bidirectional flag, not the can_lead_from_rear flag.

Can you elaborate a little on the algorithm that you are proposing?
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.

Vladki

If train has a steam tank engines on both ends (i.e. one pulling, and one pushing), it does not need to shunt. Same as if it would have modern diesel or electric engines on both ends.

Ves

QuoteIf train has a steam tank engines on both ends (i.e. one pulling, and one pushing), it does not need to shunt. Same as if it would have modern diesel or electric engines on both ends.
I believe this is already possible by coding CLFR=1 in the for the engine.




Although the reversal of a convoy should be able to work on automatic, perhaps it would be wise to combine this with the consist reassemble feature about to be created.
Now there are so many things about the consist reassemble feature that are still unknown (to me), but what I know is that the future "consist orders" will more or less exactly describe the vehicles of a convoy between each stop. It would be very confusing if the consist orders are in one "order" but the actual convoy is in another "order", just think on the confusion it already is today when replacing reversed trains...
Therefore, to me it seems obvious that a reversing train automatically calls for the consist orders and by some logic changes the consist order to inprint the new order of the train. Not only would it make sense, but it would also allow the player to go in and directly alter the consist order if the new makeup is not the best suited for the situation.

So, how I think it should work in the big picture:
* Player creates a line between some stops.
* The schedule automatically realizes what stops the train has to reverse in order to get to the next stop.
* The player buys some vehicles and initially creates a consist order for the line.
* For the stops that are "reverse stops", the consist order will automatically change the order of the vehicles to the "reverse" direction, displaying the new order to the player at those stops. NOTE, the new direction might have some vehicles reversed while some others not as of today, however it should not be stated that this is "reversed direction" as that implies that there is a "forward" direction to begin with, which actually doesnt really make sense with trains. It should simply just be the new order of the train.
* The player can now alter the consist order for such a "reverse stop" perhaps coupling a new car.
* The player sends the vehicle out from the depot, and whenever it reverses, it will follow the rules of the consist orders and have no "reversed" status as exists today.



Adding to this, I think it should be possible for the player to rotate vehicles in the "consist orders" as well (possibly also in the depot), mainly to help facilitate vehicles with cabs only in one direction, but this is a sidenote.

Ves

I was (very!) unclear, sorry, but I also agree on the rules.

Quote from: Vladki on April 28, 2019, 06:12:47 PM
Quote from: Vladki on November 14, 2016, 10:57:22 PMbidirectional = 0 would be only those vehicles, that cannot run in reverse at full speed: i.e. steam engines with tender
bidirectional = 1 would be all that can run in both directions at full speed even if they have only one cab, i.e almost everything.
CLFR=0 would be set on vehicles that do NOT have a cab in rear: F7, front part of Dm3, front unit of pendolino/TGV and similar units.
CLFR=1 would be set on vehicles that have a cab in rear: i.e. driving trailers, rear unit of pendolino/TGV, rear part of Dm3, reversed F7 (I suppose that they can be run back to back), and all modern diesel and electric engines that have cab on each end, or have a cab in the middle (shunters like this https://cs.wikipedia.org/wiki/Lokomotiva_210). Steam tank engines fall in this category too.
I'm willing to try the coding part. However the question remains how it shoudl be implemented. What do you think about may previous suggestion:

I admit this would require changes in the pakset as well, but will be clear and explicit.
(Funny reordering with brake vans is another topic, but might need to be dealt with at the same time.)

Or maybe even two values - has_front_cab = 0/1, has_rear_cab = 0/1. This could be used also to show what can be in front of train.

Im sure it would be possible to work without has_front_cab = 0/1 and has_rear_cab = 0/1 but those two values seems just so much logical and error resistant. Also, as is pointed out, with the logic in the 2016 quote, it is unclear wether a vehicle can lead the convoy (ie, has a drivers cab at all) and you have to use constraints specifically to point that out.

With those two values, we could immediatedly remove can_lead_from_rear and we can also at various places in the GUI tell the player some key features of the vehicle.
The current constraint system, although quite unflexible, can still coexist with the two new values

True, we would face a massive datfile checking for the british pakset, but if multiple people help with that, it should be doable (it anyways needs to be done for Ranrans new fixed_coupling=1).



My point in my last post was that assembling and disassembling trains in general is such a massive part of the upcoming patch, and "reversing" convoys often includes disassembling and assembling the trains.

Ves

#43
I know of those, but those are kind of edge cases where there is not physically a cab but they function as such in practice. Remember, a "cab" doesnt have to be a proper cab, but could be anything where a person stands and somehow (via vizzle or electricity or something else) communicates with the person or system operating the engine what to do. Or even an artificial point from where the driver can operate the train.
A garrat engine, although compriced of multiple parts with the cab in the middle, is anyway not going to be detachable outside the depot, hence the middle part with the real cab will never ever get to be the first or the last in the convoy. Instead the first (and also the last part if bidirectional=1) should have the "cab_front/ cab_rear=1" parameter.
The image you link to I assume the locomotor and the special car are fixed together (is it some kind of acculumator engine or battery engine?) practically making it the same categories as tender steam engines, only that this is bidirectional=1.
But AFAIK those kind of vehicles are rather rare compared to "normal" vehicles where there actually would be a cab pointing forward in the first vehicle of the train.
Therefore I think naming it "cab" is good enough, although something like "can_lead_convoy_front/ _rear" could also work but is less obvious what it means..

Edit:
Small correction in the text

Vladki

Hello, - this is gonna be long but please read anyway

this seems to be a very complex issue, and as the reversal and recombination seem to be related, it should be thoroughly analysed before any coding is done. So far I see that most heuristics and assumptions about what can go where in the train can be broken by so weird existing vehicles. So I thing the dat files should be explicit, or at least have some way to override the defaults. So I think we have to distinguish 4 things:

- bidirectionality - this should describe only if the vehicle can move backwards at full speed, and nothing else. Defaults should be 0 for road, water and air; 1 for train, tram, narrowgauge, monorail and maglev. Vehicles which are not bidirectional have to be rotated (always) and thus take long time to reverse. Notable exceptions: some ferries are bidirectional; steam engines with tender are mostly non-bidirectional, although there are exceptions from this exception....

- drivers cab (or equivalent) - driver has to be able to see the track ahead of train (except for shunting). So every train (or convoy of non-rail vehicles), has to have a vehicle with cab in the front. Notable exception are garrat engines, which go tender first both ways, but the driver can see over the tender, so it can be coded as if the cab is on the tender. For the reversal, we need to know if there is a cab in the rear as well. So we need two values: has_front_driver_cab and has_rear_driver_cab. Implicit defaults would be: 0/0 for unpowered vehicles; 1/1 for bidirectional powered and 1/0 for unidirectional powered. Powered is if power>0. Any other combination has to be specified explicitly - like driving trailers or rear parts of EMU (0/1), or articulated engine parts (1/0 - 0/0 - 0/1)

- guards (or brakeman's) cab - this was quite new for me when I discovered pak128.britain. Today, all rail waggons (except for museum stuff), have air brakes, and if the train is disconnected during the ride, the brakes would automatically stop the train. So there is no need for special guards car. However before the advent of this safety feature, it was necessary to have the last car staffed with guard and equipped with brakes, so that the guard could stop the disconnected part of train and prevent accident. And as can be seen in the pakset the drivers cab can be also at one end or another, or both. So we need a similar set of values: has_front_guard_cab; has_rear_guard_cab. Sensible defaults would be that non-braked vehicles brake_force=0 have no guard_cab (0/0); and braked (brake_force>0 or undefined) have either automatic safety brakes, or both guard cabs (1/1). Only the passenger brake vans where the position of guards cab matters would need explicit setting. Also there was a time period when rail waggons already had automatic brakes, but the rules still prescribed that there must be a guards van at the rear. Those would need an explicit (0/0) setting. This would have to be fixed in the pakset, and will make the constraint=any mostly redundant. Notable exception - cargo holds on ships/planes - these are not braked, but can be at the rear. But looking at the pakset, they have brake_force undefined so it might work with the default setting. Engines are braked so they have an implicit guards_cab too. Also driving trailers should be braked or there could be a default that a driver's cab is an implicit guard's cab too.

Constraint[next/prev] - these should really be used only to specify compatible couplings, or permanently connected articulated vehicles, and other similar features (brake type, heating type, door control, remote control of engine). Constraint=any should not be needed, presence of driver/guards cab should be used to see if the vehicle can be in front/rear of train. No constraints should be used where the usual hook & screw or any other default coupling of given era is used. There could be one special value: constraint[next/prev]=permanent (or fixed) - which would explicitly state that this coupling can be uncoupled only in depot. I do not see any sensible heurisitic for setting it automatically, except for situation when there is exactly one next/prev constraint. And even that may have many exceptions.

Train (convoi object) should have a flag showing if it is going forward or backward. When running forward, it must have a front_driver_cab in front, and rear_guards_cab at rear, and all constraints satisfied as usual. When running backwards it must have a rear_driver_cab in front, front_guards_cab at rear, all non-bidirectional vehicles rotated, [next/prev] constraints on bidirectional vehicles swapped, and then satisfied. Maybe the flag for running backwards would be more useful on each vehicle, than on the whole train, if reversed train is to be combined with non-reversed one.

The constrains checks in depot, should do the checks above, and not allow dispatching if not satisfied. Also there should be some understandable hints as why the convoy cannot be dispatched.

Now it comes to the hard part - how to do the reversal. Now I will partly repeat:
1. search for rear_drivers_cab from the rear of train.
2. if the last car has rear_drivers_cab (and there are no non-bidirectional vehicles in the train), we reverse without rearrangement - and at quickest time. If there are any non-bidirectional vehicles, they have to be rotated, and put back in their original position, and the longest reversal time will apply.
3. if the rear_drivers_cab is somewhere in the middle or only on the first vehicle, split the at the rearmost rear cab. Check for brake vans (more detail below). Take the front part to the rear, then reverse (switch flag), medium reversal time. Again there must be check for non-bidirectional vehicles. You might ask why split at rearmost? Because if there are several articulated locos, or multiple units in the train, you want to keep them together (e.g. due to remote control cables)
4. If there is no vehicle with rear_drivers_cab, rotate the front vehicle (even if it is bidirectional), and take it to the rear with all its constraints (rotated if needed). If there are multiple engines (power>0) in the front, all of them should go to the end. I hope there are no articulated engines with unpowered front part. Again check for brake vans (below) and rotating all that needs to be rotated. Longest reversal time applies.

We have to deal with the brake vans.... That's the worst.
1. when the train is split and engine(s) detached (point 3. or 4. above), check if the remaining part has_front_guard_cab. If yes, you win, you can move the engines to the rear and reverse as described above
2. if not, check if the last car (which shoud have rear_guard_cab) has also front_guard_cab. If yes, move it to front, then move the engine(s) to the rear and reverse. (This is the usual form of cargo trains)
3. if not, search from the front if there is any car with front_guard_cab, split there and move the front part to the rear, then move the engines to the very rear and reverse. This might be the case of ČSD TL659.0 with extra fuel tank, or if there are any constraints[next] at the rear_drivers_cab - probably very unusual.
4. if there is no car with front_guard_cab, take the last car (with rear_guard_cab), rotate it and put in front.

Situations 3. and 4. probably did not happen in real world, as the train was usually composed in such way that only options 1. or 2. happened. But that was only due to common sense or rules written on paper. Technically you could compose a train that way. We have to be prepared for such situation. The question is how to prevent that (constraints?), or how to indicate to the player, that it is recommended to put a front_brake_van right after the loco.

Uff, please tell me if it is clear what I wrote...

Ves

Nice summary!

Quote from: Vladki on May 01, 2019, 08:59:50 PMTrain (convoi object) should have a flag showing if it is going forward or backward. When running forward, it must have a front_driver_cab in front, and rear_guards_cab at rear, and all constraints satisfied as usual. When running backwards it must have a rear_driver_cab in front, front_guards_cab at rear, all non-bidirectional vehicles rotated, [next/prev] constraints on bidirectional vehicles swapped, and then satisfied. Maybe the flag for running backwards would be more useful on each vehicle, than on the whole train, if reversed train is to be combined with non-reversed one.

Be aware that it might not be obvious what is the front direction and what is the rear direction of the convoy. Using this example picture:

Now describing this locomotor in Simutrans would look something like this:

bidirectional=1
has_front_driver_cab =1
has_rear_driver_cab =0

Putting this in the front of the convoy will so far make it pretty obvious what is the front direction and the back direction, and it would (kind of) be easy to remember when it switches orientation and directions to swap the presented direction. But what if we later on connect another of the same locomotives but reversed, making the two locomotors behave either as one articulated locomotive, or having one engine in each end of the train, now what is actually the front of the convoy? Whatever direction the convoy travels, the first most engine is going in "front" direction even though the original first locomotive might go backwards. And to further add to the confusion, due to the nature of Simutrans (Extended) there would most likely also be a backwardpointing "twin" which with the new settings would look like:

bidirectional=1
has_front_driver_cab =0
has_rear_driver_cab =1

Since this twin in most cases only excists because of the previous limitations of simutrans, its front is considered backwards and vice versa, making it very very confusing when it tries to lead convoys showing arbitrary directions.
Granted, those types of vehicles could in some cases be discarded with the new reassignment feature and once we get the possibility to rotate vehicles in the depot, but this needs to be fail proof anyway.

However, some debug information wether the actual vehicles are internally going forward or backwards could be handy.

edit:
Arguelig, the convoy would internally consist of a list of vehicles so there would technically be a front direction and a back direction dependent on wether it is the first or the last vehicle in the list that will lead the convoy. But that might be easier to just recompile the list on reversal, so it always is the first vehicle in the list that leads the convoy.




Regarding the brake vans:
I must admit I have not really understood what the difference between "has_front_guard_cab" and "has_rear_guard_cab" and what the purpose of them really would be. Is it that the end of a train always must have a corresponding cab pointing backwards in the travel direction or does it have something more to it?
For me it was also new with the brake van logics of pak britain. In Sweden as far as I remember reading you had to have a brake van every 6'th car or so. I dont remember reading anything about needing one in the end of the train explicit. I would honestly feel best if this was not hardcoded, and more so if there where no hardcoded default rules at all, save for my suggestion below with simuconf.tab.
What I do remember though is that the old passenger vehicles where not allowed to run directly after the locomotive due to safety when crashing. There needed to be some "buffer" car in between (typically a goods car). Although that has nothing to do with braking, I would much more prefer gamecoded rules with that, but again, I dont mind if this is not implemented.

Remember, with the new reassignment feature it will be possible to simulate a shunter train running few cars at a time to nearby cargo platforms. Even in Britain I cannot imagine that you would need an additional brake car to shunt three cars, unbraked, to a nearby platform?

If you want the rules, one possibility could be to have a setting in the simuconf.tab file:
train_brake_van_rules=1 (british brake van system)
train_brake_van_rules=2 (no particular system)




Some thoughts to add to the complexity of reversing which I otherwise think looks good:
Quote from: Vladki on May 01, 2019, 08:59:50 PM1. search for rear_drivers_cab from the rear of train.
If we find a vehicle somewhere back in the convoy with a driverscab, but heading the wrong way, should we take that vehicle and turn it around?

Quote from: Vladki on May 01, 2019, 08:59:50 PMI hope there are no articulated engines with unpowered front part
Although I didnt really understand how it would be affected in your suggestion, I think that is a too risky assumption. For example a garret engine could have all the specs about the entire vehicle in the front part, but if, say you can choose between multiple middle parts with different specs, the front part might get coded with 0 power etc.

Vladki

Quote from: Ves on May 01, 2019, 11:10:00 PMArguelig, the convoy would internally consist of a list of vehicles so there would technically be a front direction and a back direction dependent on wether it is the first or the last vehicle in the list that will lead the convoy. But that might be easier to just recompile the list on reversal, so it always is the first vehicle in the list that leads the convoy.

I'm not sure how it is done internally now, but so far it seems to me that the most logical way would be to have a flag at each vehicle if it is running forwards or backwards. I suppose that the whole train is a list of objects, always ordered in the direction of movement. So the list is (would be) reassembled on reversal. This way you would know the rotation of each vehicle. A check for front/rear cab would be swapped if the vehicle is running backwards. That way the algorithm would work the same way on each turnaround. The indication of forward/reverse for the whole train should not be needed.

Also constrains should be affected by reversal flag, to avoid the curent contraint mismatch on reversed trains. Constraint[next] on reversed vehicle would be used as contraint[prev] and vice versa. This is fine for multiple units, or sets of coaches with front and rear brake van. But it breaks if you use it for heating, door control, etc... In those cases the contraint[prev] should be [prev] even after rotation. Sigh....

Quote from: Ves on May 01, 2019, 11:10:00 PMIf we find a vehicle somewhere back in the convoy with a driverscab, but heading the wrong way, should we take that vehicle and turn it around?
No, a vehicle that has cab pointing the wrong way will be ignored. There is a chance than another vehicle would be already turned the way we need (and we will save time on turnaround), or only the first vehicle will be turned around.

Quote from: Ves on May 01, 2019, 11:10:00 PMAlthough I didnt really understand how it would be affected in your suggestion, I think that is a too risky assumption. For example a garret engine could have all the specs about the entire vehicle in the front part, but if, say you can choose between multiple middle parts with different specs, the front part might get coded with 0 power etc.

The idea was that in case we have to rotate the front engine, we should take all engines from the front with it. Think of a train that is pulled by two or more engines with front cab only (or with some cabless boosters). You want to take them all to the other end (and rotate them). So I thought in case 4. after taking the front engine for rotation, and satisfying its constrains, next vehicle should be checked and if it is powered, it should be rotated and moved to the back as well. Garrat is fine, as it has_rear_drivers_cab, so it would be dealt by rule 3. This is about trains like: https://en.wikipedia.org/wiki/EMD_F9#/media/File:Crm_california_zephyr.jpg or . I know it is risky assumption. If someone can come up with something more failproof I'd be happy. Most of these cases might be solved by constraints, like tenders and boosters have some constraint[prev]=front_engine, but this might be broken by cars that can be pulled only by some engine classes (due to heating, door control, etc).


Quote from: Ves on May 01, 2019, 11:10:00 PMI must admit I have not really understood what the difference between "has_front_guard_cab" and "has_rear_guard_cab" and what the purpose of them really would be. Is it that the end of a train always must have a corresponding cab pointing backwards in the travel direction or does it have something more to it?
I'm not sure if there was some technical reason. Definitely not for the brake operation itself. Maybe just that the brake end did not have gangway to the next car? Or it served as a safety buffer like the extra goods van used in sweden?

Regarding the brake vans - I was thinking about it more. Maybe the has_guards_cab might not be needed. This is quite pakset specific, and the current use of constraints, especially for passenger & mail vehicles might be good enough. However the suggestion of simuconf options sounds good to me. I would make it then a little bit different.
For UK system, the option would enforce braked vehicle at the end - just as I descibed before, but without the check for front/rear cab, just check if the brake_force != 0. To allow shunting without brake van, you could be allowed to dispatch a train without one, but it will have speed limit equal to drive_by_sight limit. This however should be somehow presented in depot, with suggested solution. That would also make constraint=any redundant.
For non UK systems (or even all), I would suggest a configurable value of maximum brake distance. If the train is not sufficently braked - not enough brake vans - a warning will be visible in depot - and if dispatched the top speed would be limited to reduce the brake distance accordingly. The brake distance should be only a suggestion to the player, and should be freely configurable. This would help the player with proper positioning of distant signals, or deciding the block length.


Ves

Quote from: Vladki on May 02, 2019, 04:02:32 PM
Also constrains should be affected by reversal flag, to avoid the curent contraint mismatch on reversed trains. Constraint[next] on reversed vehicle would be used as contraint[prev] and vice versa. This is fine for multiple units, or sets of coaches with front and rear brake van. But it breaks if you use it for heating, door control, etc... In those cases the contraint[prev] should be [prev] even after rotation. Sigh....
I dont think that it is wise to switch the constraints around dependent on what direction you drive the train.
It is more obvious if you switch the "prev" and "next" names, with "A-end" and "B-end". That would mean that "constraint_prev..." means the "A-end" which is constrained to the specified vehicles. And the "A-end" should be constrained to those particular vehicles no matter what direction it drives or whatever rotation those might have.

Quote
No, a vehicle that has cab pointing the wrong way will be ignored. There is a chance than another vehicle would be already turned the way we need (and we will save time on turnaround), or only the first vehicle will be turned around.
Yes I see the point and thought the same thing. Rotating the vehicle beforehand should be player responsibility.

Quote
The idea was that in case we have to rotate the front engine, we should take all engines from the front with it. Think of a train that is pulled by two or more engines with front cab only (or with some cabless boosters). You want to take them all to the other end (and rotate them). So I thought in case 4. after taking the front engine for rotation, and satisfying its constrains, next vehicle should be checked and if it is powered, it should be rotated and moved to the back as well. Garrat is fine, as it has_rear_drivers_cab, so it would be dealt by rule 3. This is about trains like: https://en.wikipedia.org/wiki/EMD_F9#/media/File:Crm_california_zephyr.jpg or. I know it is risky assumption. If someone can come up with something more failproof I'd be happy. Most of these cases might be solved by constraints, like tenders and boosters have some constraint[prev]=front_engine, but this might be broken by cars that can be pulled only by some engine classes (due to heating, door control, etc).
I think I understand now. Yes, tricky...


Quote
I'm not sure if there was some technical reason. Definitely not for the brake operation itself. Maybe just that the brake end did not have gangway to the next car? Or it served as a safety buffer like the extra goods van used in sweden?

Regarding the brake vans - I was thinking about it more. Maybe the has_guards_cab might not be needed. This is quite pakset specific, and the current use of constraints, especially for passenger & mail vehicles might be good enough. However the suggestion of simuconf options sounds good to me. I would make it then a little bit different.
For UK system, the option would enforce braked vehicle at the end - just as I descibed before, but without the check for front/rear cab, just check if the brake_force != 0. To allow shunting without brake van, you could be allowed to dispatch a train without one, but it will have speed limit equal to drive_by_sight limit. This however should be somehow presented in depot, with suggested solution. That would also make constraint=any redundant.
For non UK systems (or even all), I would suggest a configurable value of maximum brake distance. If the train is not sufficently braked - not enough brake vans - a warning will be visible in depot - and if dispatched the top speed would be limited to reduce the brake distance accordingly. The brake distance should be only a suggestion to the player, and should be freely configurable. This would help the player with proper positioning of distant signals, or deciding the block length.
This sounds sensible. Although I dont think you should use the brake_cab's parameter to tell if it is secure to have directly after the locomotive (in swedish "Rammsäker" translated to something like "hit-proof"). It would most likely be dificult to get correct and might be a nightmare to illustrate in the GUI.

In the signal info window, one could count the tiles to the next stop signal and display the spacing there... ;D

Vladki

Quote from: Ves on May 02, 2019, 06:19:52 PMI dont think that it is wise to switch the constraints around dependent on what direction you drive the train.
It is more obvious if you switch the "prev" and "next" names, with "A-end" and "B-end". That would mean that "constraint_prev..." means the "A-end" which is constrained to the specified vehicles. And the "A-end" should be constrained to those particular vehicles no matter what direction it drives or whatever rotation those might have.

I think that the naming does not solve the problem. There is no problem with multiple units, where you have something like:
- front_car; constraint[next]=middle_car
- middle_car; constraint[prev]=front_car; constrain[next]=rear_car
- rear_car; constraint[prev]=middle_car
When going backwards, swap next and prev and you are good. If you use A/B you still have to think which direction is A-end. Is it towards the front of train or rear?
The problem is if you would want a car which by itself is perfectly symmetric, but requires to be pulled by engine with some specific feature, let's say electric heating. You want it to be [prev] even if running backwards. If using your A/B notation, it would be A when running forwards, and B when running backwards.  Problem not solved... I just think that constraints are not good for this sort of features. And some completely independent mechanism should be used for that.

Ves

I get the point, and I agree that the constraint system doesnt work perfectly in this sense. Those cases, or features if you want, should ultimately become an independent mechanism IMO.

Ves

QuoteYou guys take the brake van system too complicatedly. This can be explained by a very simple principle. Only whether it can be a tail end. (But it can't come to head.)
In the real world, it may be the front of the vehicles when shunting in the yard.
In that case, it is limited to very low speed. It may occur if the station does not have a shunting facility(turntable and run-round loop), but I think it's not worth simulating it so far (and you will need a lot of coding). It's the same as automobile retreat. So, It is considered impossible in the game.

There are many ways to solve this "problem". The problem with the existing system (constraint_next[X]=vehicle_abc) is that it is very unflexible and might be overwhelming to the pakset author trying to organize thousands of vehicles (as is in pak.britain) and then also to make them bullet proof for the vehicle reassembling feature to come. As Vladki points out, it has its limitations (due to its unflexibility) in certain cases, especially when trying to code different country rules into the constraint system.
Already today with the current system there are occasional bug reports ticking in to the british pakset where some bugs in the constraints have revealed them self.

The problem with adding more "braking van modes" and perhaps other kinds of modes is that it might be very complex to code and the british pakset will have a MAJOR task to update all the thousands of vehicle dat files. But the benefit might be that it is much much more flexible and easier to manage from a pakset author perspective and less prone to pakset bugs.

Vladki

The problem with constraints none/any is that it breaks when the train is reversed. My idea is that vehicles that go backwards have swapped constraints next/prev, and those should be satisfied. (unlike now, when reversed train has broken constraints). That's why I wanted to distinguish brake/caboose in some other way than the constraints. Ideally constraints should be used for different physical coupling methods, and not to simulate laws and rules.

Regarding the rear lights - all Czech passenger waggons have lights on both ends, except for multiple units with fixed coupling. All cargo waggons have a hook for attaching the reflector sign. But I do not know if there used to be some rules about caboose 100 years ago...


Vladki

Constraint groups are an idea that was already proposed and discussed but no agreement was found for suitable implementation.

Pak cs is not a good base for positioning. Most of the vehicle do not have have extended parameters set, so by default are NOT bidirectional. For tests use only the Čsd-y addons

Ves

Regarding the british graphics mismatch, those should become a bugreport in the british forum.

As we have established in the thread, there are multiple ways to go in order to achive the same goal, the goal being to constrain vehicles in certain ways for whatever reason to make them match their operations in real life, being physical coupling limitations, government rules etc.

I would also like something like the constraint groups, and I must say I am intriged by your idea with multiple constraint groups for front and back. As Vladki points out this has been discussed (for ages, unfortunately) before also in the Standard forums and nothing has been agreed on. I have never, though, seen your particular approach to it, so perhaps that could be the convincing factor? I would suggest you post this approach in the Standard version and see if it possibly could be accepted by them, and then we would also most likely get it for the Extended version eventually.

If the Standard game wont axcept this approach, there still is the chance that James would like to implement it.

Vladki

Wow, I am so glad to hear that the pak.cs is aligned properly :)

jamespetts

I see that there has been a great deal of discussion on this since I last had time to look at this thread: my apologies. Thank you very much to all those who have contributed to this discussion, especially Ranran for the coding and design work.

Consist orders

I think that it is better for basic/default reversing not to require explicit consist orders. This is for a number of reasons. Firstly, as Ranran points out, this requires quite a lot of overhead for what should be a simple and default operation. Secondly, the basic design of the consist orders feature is that it should be possible (and indeed normal) for these to be blank (i.e. a NULL pointer), only containing any data where the player explicitly specifies this. This would be unworkable for reversing, which is a default behaviour. Thirdly, where trains reverse is not always determinable in advance, as it is possible (for example) that changes made by a player to the track layout whilst a convoy is running its schedule will affect whether a train needs to reverse at any given station. Even without this inherent indeterminacy, there would be a very large amount of computational overhead (and coding work) to operate and devise an algorithm that could reliably predict where a train would have to reverse.

We will have to take into account reversing when working on the consist order feature. I believe that we already have a datum for whether a convoy is reversed or in its default direction. So long as we have an algorithm that can extract from the current consist order and its reversed datum what its forward order is, it is possible to apply consist orders to trains either in the forward or reverse direction without having reversing as a consist order in itself. It is noteworthy that reversing is in principle an issue for consist orders, however, and this issue will need more careful consideration when that feature comes to be coded.

Front/rear cabs and the "bidirectional" parameter

I believe that I have briefly addressed some of these issues in the other thread about the basic coupling constraints. This is a useful idea. I can see that this does have the potential to improve the sophistication with which various rail vehicles are specified in paksets.

One query about the question of whether a vehicle is bidirectional: in the UK, there was for a time a rather well known train (the LNER "Coronation") running with an observation saloon at the end of it like this:



Obviously, this carriage has to be:

(1) at the back of the train; and
(2) facing in the right direction

for each trip. What would happen in reality is that, at each end of the journey (from London to Scotland), the carriage would be detached from the back of the train, turned on a turntable, and attached to the other end of the train for the return trip. We have one of these carriages in Pak128.Britain, and at present it is marked as "bidirectional=0", which simply forces the whole rake to turn around in a similar way to what happens in Simutrans-Standard, which is the current intended behaviour of setting bidirectional=0 (the vehicle can only face in one direction). How is this meaning of bidirectional=0 intended to be accommodated in the new reordering system?

I note incidentally Vladki's comment on the topic of bidirectionality, and this does seem sensible in principle and consistent with the original intention of this datum.

One comment about the symbol for brake vans. The current system of constraints allows for brake vans or brake carriages that require some specific vehicles (usually passenger carriages) to be placed before them. This is normally the case in Pak128.Britain-Ex for brake ended passenger carriages. Some brake carriages (such as passenger full brake carriages or goods brake vans) do not require any particular thing (or anything at all) before them. I wonder whether this might be represented in the symbols by coding the former type to have the same end shape as an intermediate carriage on the left, and the brake ended symbol on the right? This would clarify how these brake ended carriages are intended to work, I think.

Names for the .dat file parameters

I can see that an explicit reference to a driver's cab may potentially be misleading, especially for very modern driverless trains. Perhaps "allow_at_front" together with the existing "can_lead_from_rear" might suffice - or is there some role for the existing "can_lead_from_rear" datum that you envisage that is distinct from your new driver's cab settings? The "can_lead_from_rear" parameter was always intended to be used specifically where the rear of a train had a driver's cab or some other means of being able to reverse without reordering the consist at all, so it is not immediately clear that a new parameter on top of this for a rear cab should be needed.

Brake vans/guard cabs

I note Vladki's comments about brake vans and what he describes as "guard cabs" (this phrase is not used in relation to UK railways, but may well be a translation of a term that is used on railways in other parts of the world).

The position in relation to brake vans is actually quite complex. Before automatic brakes, trains used to have a brake on the locomotive (usually the tender of a steam locomotive) and one or more brake vans or carriages in the train. One of these brake vans or carriages would normally be at the back of the train so that the guard could know whether the train had divided and see along the whole length of the train. It was also better to apply the brakes at the very rear of the train before applying them in the locomotive so that the couplings of the wagons/carriages behind the brake van did not become loose and run into the brake carriage. This was more important for freight wagons with chain couplings than for passenger carriages with screw couplings, although very early passenger carriages actually had chain couplings (usually with more links than the late 19th century and later standard of three links). Passenger trains, which travelled at higher speeds and therefore needed more brake force, would often have two brake carriages (giving three braked vehicles in the train including the locomotive), and the other brake carriage might be in the middle or at the front of the train, and would be staffed by an "under-guard". However, in the early days, this practice was not universal: in the mid-19th century, for example, the London and South-Western Railway routinely put a single brake carriage in the middle of passenger trains and none at the end.

After the introduction of continuous braking, under guards were abolished, and trains would generally have one guard, who would travel in the rear brake carriage. It was normal for trains to have brake carriages at the front and rear of the train, and for the one at the front of the train to be unoccupied. If a train split on its route, each portion of the train would normally have a front and rear brake carriage. Indeed, the Board of Trade preferred trains to have a brake carriage at each end so that passengers had some buffer zone against a collision, although they seemed to tolerate the practice of adding extra carriages ("swingers" as they were sometimes called) to the ends of trains, usually without an additional brake carriage, to deal with high demand during busy periods.

In modern times (from circa the 1960s/1970s onwards), the idea that the guard's compartment should be at the back of the train was significantly relaxed, and trains started having only a single carriage with a guard's compartment, as here:

47653 18 6 89 1 by dave gommersall, on Flickr

or here:

Indomitable by RobT653, on Flickr

In more modern times (the 1980s/1990s onwards), trains without any guards at all started emerging, which reduced the staffing cost considerably.

There may be something to be said for giving some consideration to how we deal with brake carriages/vans more carefully. One thing that we need to be able to do is work out how many guards are on any given train so as to work out what the staffing cost should be for them (this is not currently done). In particular, we need to be able to distinguish between:

(1) old trains, where every brake carriage had to have a guard, and only brake carriages had any brake force (this is easy);
(2) intermediate era trains, where all carriages have equal brake force, and the whole train has only one guard; and
(3) modern trains, where all carriages have equal brake force and the train has no guard.

Case (2) is perhaps the most challenging. Currently, we deal with the requirement to have a brake carriage at the end of the train simply by using specific constraints for each type of carriage. This is very arduous to code and is very prone to error, but it has the advantage at least of keeping like carriages with like carriages. It does not provide any way of calculating the number of guards for which a player should be paying for any given train, however.

An alternative approach would be to code this more abstractly: but if one were doing that, one would need to be able to specify more clearly which carriages were compatible with which other carriages in abstract terms, and this would require the same sort of more sophisticated coupling constraint (parameters for vacuum brake, air brake, Clark & Webb chain brake, electric train heating, steam heat, etc.) as discussed some months ago on the basic couple constraint thread, and is similar to the constraint group idea proposed by Ranran. If vehicle compatibility were thus defined, the question of what vehicle must be at the rear of a train is fairly easy to solve by simply providing vehicles that cannot be at the rear with the very simple "next[0]=any" constraint as currently used for goods wagons. For the economic purpose of working out how many guards should be required, one would add a single additional parameter "single_guard_cost". This would, if set to a non-zero value, add this amount to the fixed monthly cost of the whole train, but would not do so more than once even if multiple carriages were set with this parameter. In the case of multiple carriages with a different non-zero cost, the mean average would be taken.

The older trains which have guards present in every vehicle with a brake force can be dealt with using the existing code by simply giving these vehicles a higher fixed cost to represent the cost of the guard. Likewise, modern vehicles that require no guard can simply be set not to have a higher fixed cost. One additional thing that might be useful to allow more modern train formations is a parameter that requires a train to have one vehicle somewhere with a "single_guard_cost" parameter that is non-zero, but it does not matter where in the train that this is situated. This would be part of the algorithm for determining whether a train is in a valid formation. One simple way of doing this is to have a .dat file parameter, "requires_guard"; if any vehicle on the train has this as 1, at least one vehicle on the train must have a non-zero "single_guard_cost", or a vehicle otherwise marked as having a guard by the requires_guard parameter being -1 (but set in the .dat file by a more user friendly method, a parameter "has_guard=1", which would then be encoded as requires_guard=-1). One question that I have yet to resolve is how this could be represented to the player in the UI. Perhaps Ranran might have some ideas as to this?

I do not think that a maximum brake distance parameter is helpful; for trains that do not have continuous brakes, this is unnecessary as, in the current code, the train will just have to go very slowly so that it can brake in time for the next signal that might be at danger, which is a penalty enough. For trains that do have continuous brakes, this is not sufficient, as the braking distance is not relevant to whether the train has to have a guard at all (and accommodation for a guard).

Reversal algorithm

Vladki's ideas are interesting, but may need some revision to take into account what we actually do with brake carriages/vans as discussed above. We may need to finalise this before exploring Vladki's algorithms in detail, although an initial overview of them looks promising (although I am not sure why the front vehicle should be rotated even if it is bidirectional).

We will, especially when convoy re-combination is implemented, have to be able to cope with situations such as this:



or this



In both cases, these units would reverse without any re-ordering.

As I believe discussed in the thread on the basic couple constraint, I believe that there is already a flag indicating whether a train is in forward or reverse orientation. This should be retained.

I agree with Vladki that we do need to be able to accommodate double headed trains; I believe that the existing algorithm does this, albeit as hard coded special case.

Next/prev constraints and reversing

This is an interesting question raised by Ves. Currently, on reversal, the next/prev constraints are not affected in any way, and the formation is technically invalid, but this does not matter, as the validity of the formation is checked only in the depot, and a vehicle is automatically re-ordered to its forward state whenever it enters a depot.

With convoy re-combination, this may need to be reconsidered. There are two possible solutions: either automatically reverse the effect of next/prev constraints (and this may require some complexity: I have not calculated all the permutations of this) when a train is reversed, or, using the flag to determine whether the train is reversed, produce a copy of the train, re-order that to the forward direction and then check that copy when considering validity This will need to be considered with some care before we progress much further with the convoy recombination work.

Rendering issues

This is a complex and extremely challenging issue. There are standards for how vehicles should be aligned in this pakset, and they were produced when this alignment did not matter because there was no code for reversing some vehicles but not others. Actually re-rendering every single rail vehicle in the pakset would take many years of work and is not feasible in the foreseeable future.

One possible solution is to have a reverse offset: a certain number of pixels in the x and y directions in which vehicles in a pakset (or a specific vehicle) are shifted in each of its 8 orientations if marked as reversed. I am not sure quite how difficult that this would be to code, and it would take a considerable time to calibrate, but it is likely to be less work than re-rendering the whole pakset. I have not looked into this in any detail to assess the viability.

I am grateful to Ranran for pointing out this unfortunate issue. I am not sure whether any other paksets (Pak256.Ex?) are or are not affected by this.

Constraint groups

This is definitely a good idea in principle. May I suggest that this should work in a more similar way to the way constraints to create more abstract constraint classes to allow for things such as vacuum braked vehicles being unable to couple to air braked vehicles or unbraked vehicles, but being able to couple to other vacuum braked vehicles or vehicles that have both vacuum and air brakes fitted? There may also be some sense in separating the front/rear constraints so that, for example, a vehicle with vacuum brakes requires another vacuum braked vehicle in front, but can connect to an unbraked vehicle in the rear, to make up a partially fitted train (as was common in 20th century goods trains, for instance).
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.

Vladki

On bidirectionality, CLFR and reversal flag.

I think it is more useful to have a reversal flag on each vehicle, rather than whole train. Then the train could consist of some vehicles running backwards (bidirectional=1) and some running forwards (bidirectional=0). Also some splits and joins on the way could produce a train with half running backwards and half forwards. The the constraint swap would be necessary but will provide for consistent constraints at every moment.

Observation car would have of course bidirectional=0 (and middle cars with seats in one way only too), and would be turned around. Otherwise it would be probably coded in similar way as rear brake car, so it will be rearranged to the back of train due to brake van algorithm (although it is not defined yet). This is similar to articulated tram with front_cab only, like Tatra K2, K3 or RT6N. https://en.wikipedia.org/wiki/Tatra_K2. The question is whether to make an exception in the algorithm that if all or more than 2 vehicles (i.e. engine + tender) in the convoy are bidirectional=0, just turn the around the whole convoy (using loop or wye), and keep the same order (as in standard).

Has-rear-drivers-cab and can-lead-from-rear are synonymous. I just felt that it would be good to have similar names for front and rear cab options for consistency. Also then all checks in all algorithms for rear-drivers-cab would also check for front-drivers-cab if the vehicle is running backwards. So how about can-lead-from-rear and can-lead-in-front ?  Current system does not clearly distinguish things that can lead "only" from rear, things that can lead "only" in front and thing that can lead both ways. Now it is defined by implicit combination of constraints, bidirectional, and CLFR options. I want a possibility to be explicit about that, and have all options their own and simple meaning.

What I have maybe not written before is that if the train recombination and shunting is implemented, trains should be allowed to travel even if they do not satisfy the front/rear-drivers-cab and brake van requirements, but only at speed limited to drive by sight. This might be useful to do a short trip without the need for reversal or brake van shunting.

Quote from: jamespetts on May 18, 2019, 11:56:45 AMVladki's ideas are interesting, but may need some revision to take into account what we actually do with brake carriages/vans as discussed above. We may need to finalise this before exploring Vladki's algorithms in detail, although an initial overview of them looks promising (although I am not sure why the front vehicle should be rotated even if it is bidirectional).
This is a special case if you have an engine like american F9A https://en.wikipedia.org/wiki/EMD_F9. It has only front cab. So if it is the only engine on the train it has to be rotated. But if you have another F9A connected back to back with the first one, then just shunt both of them to the end without rotation. And if you have one in front of the train and the other on the rear, you do not have to shunt at all.

Quote from: jamespetts on May 18, 2019, 11:56:45 AMWe will, especially when convoy re-combination is implemented, have to be able to cope with situations such as this:
I'm not sure what is the exact combination on those photos. But I assume they are two DMUs connected together, with some unused cabs facing inside, but also with cabs on both ends (although we cannot see them). Yes those should reverse without shunting - the rear car has-rear-drivers-cab, front car has-front-drivers-cab. I don't see a problem here. In general I would like the algorithm to work for all possible combinations without special exceptions.

I have to think more about brake vans. I'd like to make it as simple as possible, just a few brainstorming ideas
- front brake van (on passenger trains) has lower monthly cost than rear brake van to show that the guard is only in the rear van. Simple... But if two trains are combined they would pay two guards...
- simple rule to follow that the last car (after reversal) has to have brake_force>0, if not take the front car and put it back. Would work fine for the early era without continuous brakes, and for modern era with brakes and without guards. Also will work well for trains with brake in front and rear in the sense that they will not have to shunt the brake van.
- no idea how to enforce at least one guards van anywhere in the train
- trains of the mid-era (various incompatible continuous brake systems, and rear guard still required), would probably have to use the current constraint system.

Vladki

Continuing my thoughts and answering unanswered:

Quote from: jamespetts on May 18, 2019, 11:56:45 AMI note Vladki's comments about brake vans and what he describes as "guard cabs" (this phrase is not used in relation to UK railways, but may well be a translation of a term that is used on railways in other parts of the world).

I don't know what is the proper term, but what I meant is the guards compartment in a car - especially the front/rear passenger brake cars. As far as I understand from the pakset - full brakes (mail) are symmetric, but passenger brakes are different for front and rear (yes they are the same, just rotated). So the question is if it was some strict rule that the guards compartment was at the "outside" and passengers "inside", or just a convenience rule. The has_front/rear_guards_cab was intended to describe which way the guards compartment is oriented. But maybe my proposal of has_front/rear_drivers/guards_cab is too specific and should be named more generally:
can_be_front/rear_when_running_forward/backward...  With can_be_front_when_running_backward = CLFR. Is anybody able to come up with some short but clear enough names?

The reason why these are necessary, is that constraint[next/prev]=any is not sufficient after reversal - if swapping of constraints is done to ensure consistent constraints all the time. Think of a front brake van. It cannot be in the front of train so it should have constraint[prev]=any to ensure an engine in front of it. But after reversal, it would become constraint[next]=any, but that is wrong - it has to be the last car... So therefore we need similar option for guards "cab" as for drivers cab...

Back to the observation car - I think it should be handled in exactly the same way as rear brake van. Imagine someone would put another observation car just behind the engine. Then you would just turn around the engine and leave the observation cars were they are. So they are inherently bidirectional=1. But if the car behind the engine is just regular car, you have to shut and rotate the observation car as you would with rear brake van.

For further examples I would try to use ascii art version of ranrans notation:
<__>   - bidirectional engine
(__) - full brake van, cabless booster engine (EMD F9B)
|__| - ordinary car that cannot be neither front nor rear end
_|=|_ - (semi-)permanent connection (depot only)
_|-|_ - coupling that can be disconected anywhere
<__|=|__) - steam engine with tender
<__|=|__|=|__> - 3-part EMU/DMU/articulated engine including garrat engine
(__|-|__|-|__) - set of passenger cars (front-brake, middle, rear-brake)
|__|-|__|-(__) - two cargo waggons with full brake at the end


Thinking again about the algorithm.
First and very most important is that each vehicle has flag to tell if it is running forward or backward: is_reversed=0/1
This flag swaps the meaning of constraint[next/prev],  has_front/rear_drivers_cab and has_front/rear_guards_cab.
The convoy list is always in the direction of movement so it has to be recreated on every reversal.
Default values are: bidirectional=0 (road, water, air), bidirectional=1 (train, tram, maglev, ...)
if (power > 0) then has_front_drivers_cab=1     <__) - steam engine (non-tank), buses, airplanes, ...
if (power > 0 && bidirectional) then has_rear_drivers_cab=1    <__> - steam tank engine, most diesel and electric engines, ...
if (brake_force > 0) then has_rear_guards_cab=1   |__) - tender for steam engine, maybe an observation car
if (brake_force > 0 && bidirectional) then has_front_guards_cab=1   (__) - full brake van, modern train cars with automatic brakes
I expect that all powered vehicles have brakes at the same time so if it has_front_drivers_cab it automatically has_rear_guards_cab, with driver and guard being the same person.
Other stuff has to be specified explicitly: front/rear brake/observation vans, parts of articulated locomotives, braked cars from era when rear brake vans were compulsory, unpowered control cars (driving trailer)
Three reversal times: short for walking to the other end of train and starting the engine, medium for shunting without turntable, high for shunting with turntable.

And now the algorithm. Imagine a fictional train consisting of DMU, some cargo waggons, and a set of pax cars with front/rear brake: <_1_|=|_2_|=|_3_>-|_4_|-|_5_|-(_6_|-|_7_|-|_8_)
0. check if the first and last cars are bidirectional=0, if yes, then just give up and reverse the whole train using loop or wye - vehicle list in convoy will stay the same and high reversal time will apply. DONE. This will most probably be the case for road, water, air and some trams, maybe also for train with observation car if coded as bidirectional=0.
1. check if the rearmost car has_rear_drivers_cab _>. If yes, short reversal time will apply. Reassemble the convoy starting from rear, toggle the is_reversed flag on each bidirectional vehicle. If a non bidirectional vehicle is encountered, do not toggle the flag, but add high reversal time for each non bidirectional vehicle (split the train, turn the car, reassemble). DONE.
2. search for has_rear_drivers_cab from the rear. If found mark the position for splitting as A. Medium reversal time will apply. Mark for reversal. Continue with search for brake van (point 4)
3. if no car has_rear_drivers_cab, this becomes tricky - there may be one or more steam engines with tenders <__|=|__)-<__|=|__), or a bidirectional engine with one cab (half of a twin engine) <__), optionally followed by cabless booster <__)-(__). So basically all powered engines with their constrains have to be detached from the front - and position marked as A. - high reversal time will apply
4. search for has_front_guards_cab from previously marked position A towards the end of train. When found mark second splitting position as B, and mark for reversal
5. if no car has_front_guards_cab mark the last car (which must have rear_guards_cab) and perhaps some its constraints for splitting - high reversal time will apply
6. Now we have train split front - A - B - rear. In the above example it would be: <_1_|=|_2_|=|_3_>-A-|_4_|-|_5_|-B-(_6_|-|_7_|-|_8_)
7. new convoy will be assembled as:
If front was marked for reversal (2) start at A continue towards the beginning and toggle the is_reversed flag.
If front was not marked for reversal (3), start at beginning and continue to A. (vehicles are rotated).
Then start at B and continue to A, and toggle the reversed flag.
If rear was marked for reversal (4), start at end and continue to B and toggle the reversed flag.
If not (5), start at B and continue towards end. (vehicles will be rotated).
You should get: (_6_|-|_7_|-|_8_)-|_4_|-|_5_|-<_1_|=|_2_|=|_3_>

A vehicle that has drivers/guards cab in some direction, should not have any constraints in that direction, or constraint=none in addition to some other constraints. It would not make much sense otherwise...
Constraint=any should be redundant and replaced by check that each train has_front_drivers_cab and has_rear_guards_cab.

Vladki

Why the red car cannot be turned on the turntable and put on the other end of train? All the other vehicles would then not need any shunting/turning as they have a green driving trailer. The red car seems to be the observation car from james' example.

My algorithm would be a bit different:
1. and 2. will be the same as yours
3. after reversal by my algorithm would be (__|-|__|-|__|-|__)-\__\-<__>, but then next reversal would make:  <__>-(__|-|__|-|__|-|__)-/__/ .. Although this is quite unusual setting, it might need some adjustments to keep the engines together. Hmm, maybe not. the \__\ will not have_front_guards_cab so it will probably end as <__>-/__/-(__|-|__|-|__|-|__)
4. will be the same as yours
5. will be: (__|-<__|-<__|-<__|-<__|-|__>
6. and 7. will reverse so that it will be order (_orange_)-|_green_|-<_purple_>
8. in my case it will look more like 7. - only one green car and 4 orange
9. will be the same as yours
10. will in my algorithm end up same as 5. However in your case - after reversal it will turn into push-pull train and will not rearrange any more.
11. will do the same as 9.
12. will be the same yours - but note also that after reversal it would have cabs on both ends and will become push-pull train.
Originally I thought that after 2 reversals the train should be back at its original order, but it is not the case, but eventually should find a stable pair of configurations.

Vladki

Sorry for double post.

Just wanted to sum up my algorithm.
In short it is about finding the longest part (optimally the whole) of train that has driver cabs on both ends. Then find in the rest the longest part with brake vans on both sides. Then swap those parts. If such parts are not found, rotate the engine or brake van as needed, together with any constraints they might have

Vladki

#60
Loading already happens while train is reversed. So the time spent in station is the longer of the two (loading or reversal).

Quote from: Ranran on May 21, 2019, 02:46:56 PMI think the turntable reversing time panalty should be proportional to the number of locomotive (count one power as one).
I agree.

I think about adding a check in the beginning that if there is vehicle with power=0 && bidirectional=0 then just use wye.  However wye or loop requires quite some space and was not available at most stations.
It is good that you come up with such crazy train combinations, although a sane railway manager would never make such. But beginner players will surely make their first train to be something nobody of us would understand.

QuoteQuestion, what code do we need to write to renumber correctly in this?  :coffee:
Considering my algorithm, it will split between 8/9. the 9+10 will be considered as the brake van sequence - moved to the other end and rotated. 1 rotated too. Next time 9+10+1 will move together

Ves

I think those examples look great!

Although it is not required before the reassemble branch, I would like to add some thoughts and suggestions for princips in cases where "fixed_coupling" and also "front/rear" cabs are engaged:

Using the same ASCI art as Vladki:

<__>   - bidirectional engine
(__) - full brake van, cabless booster engine (EMD F9B)
|__| - ordinary car that cannot be neither front nor rear end
_|=|_ - fixed_coupling
_|-|_ - coupling that can be disconected anywhere
<__|=|__) - steam engine with tender
<__|=|__|=|__> - 3-part EMU/DMU/articulated engine including garrat engine
(__|-|__|-|__) - set of passenger cars (front-brake, middle, rear-brake)
|__|-|__|-(__) - two cargo waggons with full brake at the end


1) <__>=|__)
The fixed connection eliminates the rear cab. Both vehicles would need to turn around for reversal, just like a steam engine.

2) =<__>=
If a vehicle with this configuration is sent out alone, it can not connect to any vehicles outside the depot.

3) =<__>=<__>=
A convoy in this configuration also cannot split or connect other vehicles at either end.

4) <__>-(__)=
(Note the fixed coupling on the rear vehicle)
Altough perhaps unusual, a convoy in this configuration would allow the locomotive to disconnect from the car but not connect on the other end of the car. The car has effectively become only single directional and needs to turn around to be hauled in the other direction.

Vladki

With such a complicated possible configurations, I think if it would not be easier to have a smaller set of "typical" configurations and let everything unusual reverse using wye... with significant time penalty.

Ves

True, the symbols might look bad, however, I mostly used the ASCI-art to illustrate my point.
Thinking about it, what would it look like if you did that with your graphics?

jamespetts

There are a very large number of issues here; I will deal with them under headings for ease of reference.

Bidirectional flag for intermediate vehicles
It should in principle be possible for an intermediate vehicle to have bidirectional=0, should it not? Ranran gives the example of rail vehicles with seats all facing in one direction.

Are you sure that this is ignored at present? I have not looked into it for some time, but this is not my recollection of how it works, albeit that recollection is no longer certain.

Relevance of the existing can_lead_from_rear flag
I am not sure that I understand what you mean when you write that it is not clear what "side of the CFLR" has a cab; the can_lead_from_rear flag is intended to mean that, when the train is in the forward orientation, if the very last vehicle has this flag, the whole train can run in reverse without modifying the position or orientation of any vehicle. It follows from that that the rear end of that last vehicle must be assumed either to have a driver's cab or some other arrangement functionally equivalent to a driver's cab (e.g. in a driverless train, which is why the word "cab" should not be used in the .dat file syntax) to enable it to lead the whole train.

Thus, it is not immediately clear to me where the uncertainty lies - the "can_lead_from_rear" flag always indicates the presence of a driving cab (or equivalent) at the rear of the vehicle (i.e., the second of the three graphics in the message of the 18th of May).

If the vehicle also had the "allow_at_front" flag set to true, it would be as the third graphic. If it had only the "allow_at_front" flag set and not the "can_lead_from_rear" flag set, it would be as the first graphic.

It is important to avoid making existing data structures redundant if this can be avoided, as it avoids a lot of unnecessary work both in the code and the paksets.

Whether each vehicle or the whole train ought to have a flag to indicate its reversed status
The existing code already has a boolean flag for whether any individual vehicle is reversed: see line 317 of simvehicle.h.

Brake vehicles
I believe that I have already responded to Vladki's suggestions as set out in the 19th of May in an earlier message, proposing a specific alternative algorithm and noting that it should not be hardcoded that brake vans should always be at the rear, but should be a pakset level setting as at present. Likewise, whether any given observation car should be able to be placed behind the engine (etc.) should be a pakset level matter and not hardcoded. We want a system that works at a high level of abstraction wherever possible to give the greatest flexibility and minimise unnecessary coding work, unnecessary work for pakset authors and unnecessary work in understanding by players.

As to the front/rear constraints after reversal, it is very simple for an algorithm simply to take into account reversal in assessing the constraints, as already discussed, so that next constraints are treated as prev. constraints and prev. constraints are treated as if they were next constraints in any reversed vehicle.

Status of constraint=any
I see no immediate reason to change the way in which this works fundamentally. Generally, it should be possible for pakset authors to continue to get the existing behaviour or something close to it (or something that will always or almost always be better than it) by using the existing settings and can optionally choose to get the new behaviour by using new settings/parameters.

Reversing algorithms
We still need to finalise fully how we deal with brake vans before dealing with this. The algorithm itself will need to be reasonably predictable by users, and so should be simple in all but complex cases.

Rendering issues
It is extremely odd that it is even possible for the pixel shifting to be different for each vehicle. There must in principle be some deterministic algorithm that results in this difference and thus some means of automatically reverse-engineering this.

The amount of work that it would involve to re-render the entire Pak128.Britain pakset is so far beyond what is feasible that it is virtually inconceivable that this will ever be done in any conditions that are ever likely to occur. As to adding an offset in the .dat files - is this a known solution that allows Pak128.Britain vehicles to work in the same way as Pak128.CS vehicles?

Integration with vehicle management
Can I ask what consideration has been given to how well that the ideas being discussed here would, when implemented, fit in with the vehicle management branch when work on that is completed? This is of no small importance.
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.

ACarlotti

Quote from: jamespetts on May 29, 2019, 07:44:33 PMAs to the front/rear constraints after reversal, it is very simple for an algorithm simply to take into account reversal in assessing the constraints, as already discussed, so that next constraints are treated as prev. constraints and prev. constraints are treated as if they were next constraints in any reversed vehicle.

There is one important detail that you don't mention here. Currently 'prev' constraints assume coupling to the rear of another vehicle, and 'next' constraints assume coupling to the front of another vehicle. We would need to modify the .dat file definition to allow specifying a particular end of the adjacent vehicle in constraints. There is then the question of whether the existing format should be assumed to speficy coupling at a specific end (both vehicle in the same orientation) only, or whether it should allow the adjacent vehicle to be in either orientation.

Vladki

Regarding the misaligned reversed vehicles. Here are the templates of pak128.CS. Although they are old, designed for track with higher ballast, now they are used with offset 0,4. You can compare them with pak128.britain and see if you might find what is wrong. https://forum.simutrans.com/index.php/topic,3206.0.html