boskid wrote: Mon Jan 27, 2020 2:53 pm
1 to 1 train delivery.
This is simplest rail setup. There is 1 train stop where items are loaded and 1 where items are unloaded. This setup does not benefit when using "trains_limit". It can be simply controlled by changing amount of trains with same schedule and adjusting train input buffers (maybe couple of sections with rail signals so they can stand behind a train that is being loaded/unloaded).
In case trains limit would be used and set to 1, train leaving pickup(load) station would reserve drop(unload) train stop. When next train would be loaded quickly before first reaches drop train stop and is unloaded, second train would no-path. If trains limit would also be used on second drop train stop, this train after being unloaded would nopath if there are more trains in loop than total slots in both train stops.
Does this need fixing? It can either be viewed as having too few stops for the amount of trains handled, similar to the case of having too many trains for too few segments. Except that the stations are the segments here. Perhaps this is also just a use-case where the user would use no train limit, as per usual. It doesn't strike me as any more offending than trying run 4 trains on 4 rail segments. They jam. Though it probably speaks to having _no train limit_ (i.e. all trains allowed) be the _default_ setting.
I see two potential fixes, the first one complex:
If it has to be addressed, the data each train station holds would need to be expanded: Each train station would need to be aware of the train currently in it and looking to leave (done unloading/loading, ready to depart, but no path). If another train targets this station as it's destination, but before being refused because the max number of trains already is at this station, check if a) there is a train looking to leave the station and b) the train looking to leave accepts the incoming train's current station as a valid input. If it does, outgoing train's new destination is incoming train's origin and they can both depart. Bit of work to setup, if the stations keep their current train in memory not too computationally intensive (wouldn't need to check all stations or trains or anything; just compare candidate to ask if he can come to this station, with the train currently at the station).
The second one prone to error (not recommended, could be used to test in known system):
As soon as a train is able to leave, but can't path, reduce the the CurrentNumberOfTrainsAtStation by 1, even before it left. Odds are, it will unstuck (as it's _likely_ to go to a station that can now dispatch a train towards the fake-open station). Could lead to problems. Would not recommend. But it's quick and dirty, could be used for testing very quickly? Sort of simulates the correct effect if you work within your test setup (only two types of stations: ore provider and ore delivery).
boskid wrote: Mon Jan 27, 2020 2:53 pm
N to 1 train delivery
This use case can be easily achieved by using trains with dedicated schedule. If given pickup train stop is near, prepare for example 2 trains that would contain given station in schedule and common smelter station. That way is is easy to control amount of trains going to each pickup station.
In tested map there are for example 2 stations named "Iron Source 2-1" and "Iron Source 2-2", each with 2 dedicated trains. There is also "Iron Source West West 1" with 7 dedicated trains and "Iron Source West West 2" with 5 dedicated trains. There are more iron sources but i skipped them for this tests. Setup that is here works fine as it is. Amount of trains going to smelters is limited.
Now lets use trains limit on this pickup stations. Each train stop will receive limit equal to amount of trains in loop before change and rename each train stop so they are under same station name "Iron Source".
simple_limit.png
For now there are no major issues if pathfinding since in all cases each train has at least one train stop it can path to in every case. There are some througput issues showing. Trains that came from near pickup train stop, when going to smelter station, will reduce amount of trains related to given pickup train stop. That means that trains that were going to far away pickup train stop, are now rerouted to near train stop (since they are from same station and this train stop is closer/has lower total cost). This means that less trains are going to far train stop and so item input flow is limited to 3 out of 4 train stops. Some trains are simply always waiting on train stop that is near.
I'll need to ask for clarification. You say "That means that trains that were going to far away pickup train stop, are now rerouted to near train stop".
Does this mean that:
a) trains that are _currently_ on their way to far away pickup train stop change their intended destination to a near train stop?
or
b) there are now too many trains slots open for the nearby stops (i.e. maxTrainPerStation is so high that it gets all trains on the network to go there)?
In the case of a), I would argue that a train currently en route to a destination should at no point change it's mind as to what it's destination is. If this is currently the case, what are the benefits of it? It's bound to cause problems with same-name stations, as the pathing will pick the shortest path if it's rerun constantly during travel. Also, is that not unnecessarily computationally intensive?
In the case of b), I would argue that the maxTrainPerStation was poorly set. Now this is not an attack or anything. You're working with an existing train system and trying things out. With a new way of doing trains. I'd argue that all (or even most trains) going to the nearby station is a result of one or two things:
- The nearby train stations accept more trains than is desired. Their desired acceptance should be reduced.
- If the stations still manage to satisfy all trains (load them on time), the stations were initially set up with fewer trains to be long-lasting for some reason. Again, to simulate that intent the number of allowed trains should be reduced.
- If the stations are struggling/unable to satisfy all trains (load them on time), the stations were never designed for such a high volume of trains. Again, to simulate that intent the number of allowed trains should be reduced.
boskid wrote: Mon Jan 27, 2020 2:53 pm
To fix throughput issue, lets simply add more trains with same schedule.
I believe the issues observed above do not warrant adding more trains to fix the throughput issue, but rather playing around with the settings of how many trains are allowed per station. It worked fine with the given amount of trains. It should be possible to approximate the throughput (if the rerouting is not a path change while en route, as I explain in a) above).
The addition of trains is going to lead to the below explained complications, which are to some extent also encountered in current setups. The only novel issue being a no-path error by adding more trains than valid stations, which is an issue created by oversaturating the system. (again, like putting too many trains on a rail system with too few segments; except that segments are stations when working with the same-station-name-maxTrain-paradigm).
boskid wrote: Mon Jan 27, 2020 2:53 pm
In case of low ore consumption, this may give something like this:
low_ore_usage.png
In this case input stacker is too small but in most cases it works fine.
If ore consumption is high, trains will be quickly unloaded and they will be sent to pickup station. Since there are more trains than total slots in all train stops, some of them will no-path right on unload station. This means if all ore pickup stations are full, no more trains will be sent to them. They will instead no-path.
Basic issue of more trains than stations. Resolving for equal amount of trains and stations was proposed above. Resolving for more trains than maxTrainPerStation slots is not possible without adding intermediary stations (stacking/waiting area, to which you'll come in a moment).
boskid wrote: Mon Jan 27, 2020 2:53 pm
high_ore_usage_nopath.png
I did not add repath after limit drops so they are stuck, but this is prototype limitation. They are sitting in smelter station blocking other trains right in case when we need a lot of ore (we are in high ore usage condition). This means now there is need for output stacker - place with fake pickup train stop that is behind CN closed rail signal. This prevents them from going into nopath.
Output or input stacker are useful to work with the system if you use more trains than you have stations. I.e. adding fake stations as you correctly call them.
A tradition stacker for incoming trains (i.e. a set of parallel rails accepting incoming trains, only managed by rail signals and not stations) will work just fine with maxTrainPerStation property. If a station accept 20 trains, and you want all trains to be able to be as close as possible to delivery, you'll need a stacker with 19 slots leading to the unloading station. Each slot in the stacker can accomodate 1 value of maxTrainPerStation. I.e. stacker size + maxTrainPerStation(for all stations on the schedule, both for loading and unloading) give you the total amount of trains able to navigate the network.
This is not fundamentally different to a regular rail network. You can't just add 20 trains out of nowhere without it risking to clog up crossing or segments of your rail. In this case, it doesn't risk clogging up your network, instead it clogs up your stations. I guess that would be a positive, in a sense? It's still ultimately a problem with the rail network itself.
boskid wrote: Mon Jan 27, 2020 2:53 pm
high_ore_usage_output_stacker.png
This output stacker has to be of special kind: any train must be able to exit without waiting for other trains to leave. Doing output stacker without this property means that if blocked train will be first to repath and will see pickup train stop being not full, it will repath, will reserve given train stop and now pickup train stop is again full. Train in front is unable to leave since all train stops are again full.
I'm not sure I understand the design of the stacker. A train unable to find a designation is blocking trains that found a designation. Why was there a train with no correct designation in the way blocking other trains in the first place? If it's the case that the train went out to a destination, stopped and for some reason tries to find a new destination, then I don't understand why that would be the case. A valid destination was found. It should not be removed and the train should keep heading there. Only by direct player interaction or finishing it's journey should the train be able to find it's next destination.
If the problem a result of a station being disabled entirely?
Please elaborate a bit on this point. I'm not entirely sure what's going on here.
boskid wrote: Mon Jan 27, 2020 2:53 pm
For now it was only trains limit on pickup train stops.
Smelters here is using input stacker with train stops. Lets try to use trains limit on them to reduce congestions in case of low ore usage. On each stacker train stop lets set limit of 1 train. This means if train will manage to reserve given train stop, it will have guaranteed place in input stacker and so no congestion should happen. Here small note: train that passed stacker train stop (waypoint), is no longer related to given train stop and so it does not make it full.
This limit on stacker train stops makes back-pressure to happen. Trains that are on ore pickup train stop will not leave until they have guaranteed spot in input stacker. This could be a nice feature since less trains are in transit. Amount of trains in transit is limited by amount of stacker train stops total limit.
I would recommend not using a stacker made out of stations, but to use a stacker made out of signals instead. I'm not sure about the exact size of stacker. Let's say it has 12 lanes. If you put a station on each lane with max train limit to 1, this will reduce throughput, as only 12 trains can move at any given time.
Let's say you have 3 unload stations, and don't use stations for your stacker, but signals. If each station accepts 4 trains, 12 trains can move at any given time. Same as above, without making each spot in the stacker reserved, but dynamic.
If you want more trains moving than your stacker has capacity (reasonable, it's what we do now anyways), you do the same thing as you currently do and guess how many extra trains you can support (by rapid unloading etc). Say you determine it's fine to have 24 trains travel at any one time, because they'll be unloading fast enough, you can say that each station now accepts 8 trains. It's the same as currently assigning extra trains to a line.
Either way, I'm unsure how this is a problem in itself?
boskid wrote: Mon Jan 27, 2020 2:53 pm
Because of prototype limitation (no repath for trains with nopath), i made single disconnected stacker train stop not connected to other rails. By CN it is pulse enabled for 1 tick every 120 ticks. Performance right now is not important.
For what i do not fully understand, trains started to behave weird. Train could enter on stacker lane and instantly repath to adjacent stacker lane. This path would be however all around smelters. They started to block stackers since train in front of them would in that case be almost instalty reserved by other trains far away and train would not be able to reserve given stacker train stop again. Sometimes they also started to nopath, i do not know why (yet?)
I cannot make fake stacker train stop to prevent them from nopath since this would remove back-presssure: all trains on far train stops would always be able to path to it and would leave pickup train stop. To fix this, input stacker of same size as output stacker would be needed (shared input-output stacker would be better).
For now, trains were using input stacker train stops as waypoints. This has nice feature that trains that are going for unload train stops are only after input stacker train stops and so they are near. This means i could setup trains limit on unload train stops. Trains in stacker would start to repath so fake ore drop train stop was required.
I'm not sure I understand either. Perhaps images of what exactly is going on would help. Sounds like the train on the stacker (stacker station, right?) might have skipped parts of it's schedule, until it reached the stacker portion again? Perhaps the oversaturation of the network at this point? Perhaps just a bug? I'm sorry but I really have a hard time "seeing" the situation in my mind here.
boskid wrote: Mon Jan 27, 2020 2:53 pm
Why even using input stacker? Lets set each unload train stop to some nice amount of trains, lets say 3. Here throughput also plummets. Input stacker is now useless. It could be that all 3 slots of limit could be allocated by 3 trains that are far away. This ore train stop is not going to get any ore until this trains will arrive, going through whole map. Doing fake ore drop train stop makes it worse: now some trains could be in input stacker lured by enabled fake train stop. At some point ore train stop becomes not full. Train that is on the other end of map reserves this slot. All trains in stacker are unable to move since all ore drop train stops are full. Train that is going from other end of map meets full input stacker and is unable to reach ore drop train stop.
I can see this being a poor use for the maxTrainPerStation feature and how it would result in bad throughput. There's really nothing more I can say to that. It should most likely not be used in such a way. Preferring intermediate dropoffs (i.e. getting a OreStationEast (for all ore fields) and OreDepotStationEast (storage/exchange location closer to the base) would probably be preferable. Obviously the longer the path, the higher the latency from train departure to arrival. The lower maxAmountOfTrains, the higher the throughput loss. The deadlock in the system is ultimately a result of having more trains than are handled by your stacker and station capacity. Without the maxTrainPerStation property set to a low value, you'd have regular behavior of trains being "stored" somewhere on the rails, in transit, etc.
boskid wrote: Mon Jan 27, 2020 2:53 pm
At this point i stopped testing this concept as at every point it starts to introduce more issues than features it would introduce.
I'm saddened to hear this and would like you to reconsider about it. I hope I have been able to address some of the issues, and while I still need some clarification, I fail to see a genuine problem with the maxTrainPerStation concept. What we figured out is that it has it's own challenges and use-cases. Some situation may be best left unchanged (default behavior: unlimited amount of trains). There may be many issues related to using a pre-existing rail system designed to work another way, adding on trains to fill a perceived shortcoming, and then observing a lot of undesirable behavior.
Respectfully, I think much of it went wrong around here
boskid wrote: Mon Jan 27, 2020 2:53 pm
To fix throughput issue, lets simply add more trains with same schedule.
and caused a whole slew of complications.
As to the part where you said trains are starting to behave "weird", I genuinely don't understand the full scale of the test done. Why they would essentially try to repath to a station they are already on is beyond it. I don't see how it would be possible under the system I proposed. If you have any further insight? I'm absolutely puzzled by it, and would like to solve this odd little problem
I hope you had an opportunity to look at my post preceding yours as well (was probably made while you were typing out your response), and if there are any questions, concerns or problems please bring them up and I'll be happy to work with you towards a solution
Again, thank you for committing time and effort into looking at this proposal. It means much to me, and I'm yet hopeful that the issues unrelated to the rail design itself are fairly minimal. It would be fantastic to add this feature to vanilla factorio; essentially the power of LTN, without the need for depots!
Cheers
![Smile :)](./images/smilies/icon_e_smile.gif)