have you found good generic train schedule setup? I have tested one, while it works i am pretty sure there are better setups. Mine setup is like this:
* all input stations (which provide stuff) are named Input
* all drop stations (which requests stuff) are named <Icon> Output
* I have depot section which has a stop for every train have. All depot stations are named Depot
* I have refueling stations all named Refuel
now schedule on trains. All trains will have same generic schedule:
* One and only item in schedule is Go to depot
now Schedule interrupts:
* If no cargo and is stationed in Depot - go to input. It will go to any available input train station and load cargo.
* If has cargo go to <Icon> Output. This uses this parameter variable to set icon based on cargo train has
* If you have no fuel - goto fueling station
* Now interrupt which can happen during interrupt: If no path available and destination is full - got to depot and wait 5 sec
this works but not ideal. trains are going to inputs and unload at output. seems fine. But sometimes they go to inputs and fullly load even if no drop stations require this input. So loaded trains wait in stations or depots. Which is an issue.
so what are your good generic setups?
Re: 2.0 train schedule setup
Posted: Tue Oct 22, 2024 12:31 am
by CarbonPhosphate
So far I have the same, but I've been trying a couple of things to try and stop full trains waiting in the depot:
- Trains with items can't go back to the depot, and will sit in the pickup stations
- Depots are set to low priority, so the full trains at pickups will move first
This works, but to be perfect I don't want full trains waiting at all, so I've tried some circuit stuff:
So far, the dropoff stations send a signal with an item to the circuit network when they want items, and the provider stations have limit=0 if there aren't any dropoffs requesting items
It's not perfect though - if there are multiple pickups, all trains waiting at depots run as soon as any dropoff requests something, and I haven't been able to find an elegant solution to send only one train as they all pathfind in exactly the same tick. I'm thinking I might run a counter to the depot stations so only only one depot station gets the "check" signal to send the train at a time, but it feels really awkward to set up giving each depot its own number. Any ideas?
Re: 2.0 train schedule setup
Posted: Tue Oct 22, 2024 4:23 am
by Sopenas
I was thinking about having global logistic network too for trains and try to calculate needed trains. But my bases usually are huge and when i start to think about size of logistical network I would have in this case - well i do not think this would end well.
I was wondering maybe it would be possible somehow to do purely with train scheduling without global train logistical network.
Re: 2.0 train schedule setup
Posted: Wed Oct 23, 2024 5:47 pm
by cylarc
I feel like I'm close to having this one figured out, but can't nail the last bit.
Setup:
* Providers:
* Train limit: 1
* Label with "<icon> Provider - Fluid
* Use circuits to determine when provider has at least 1 full train of fluid (using 2 cars, 100k fluid)
* Here, we just connect all tanks to a arithmetic combinator, and divide by 100k
* Use this signal to set the train stop to active IF any > 0
Using this setup, a provider only comes online once it has at least one train of fluid
* Requesters
* Train limit: 1
* Label with "<icon> Requester - Fluid
* Create a constant combinator with request amount (e.g. -150k water, etc)
* Connect to all tanks
* Route through arithmetic combinator, divide by 100k -> output will be -N, where N is number of trains needed to fill station
* Use signal to set train stop to active if ANY < 0
Again, the requester will only come online if it requires at least one train of fluid
* Depot
* Name: "Depot - Fluid"
* Send signal to train
* Constant combinator with -1 for all items we want to service, attached to each depot
Train schedule (see screenshot for full details)
* We use the circuit signal to select an item (it'll just iterate through all the items on the line)
* Check if <icon> - Provider Fluid AND <icon> - Requester Fluid" is NOT full
* Dispatch train to go to provider, get full load, then go to requester.
This works _perfectly_ in the simple case of one requester and one provider _per item_. I have tested it with two different fluids on the same network
However, it breaks down as soon as we have more than one provider.
Specifically, when:
* Two providers are online (have >1 train of fluid)
* One requester comes online
In this case, the conditions for the interrupt are satisfied for _two trains in the depot_. Even though the first train gets scheduled, routing to one provider and the requester, the provider doesn't get marked as "full" until the train is actually on the way to that station!
Two trains will get dispatched, one to each provider. The first one will fill and head to the requester, while the 2nd will sit and wait at the provider until the requester needs another train.
I'm not sure there is _any_ fix for this issue with the current circuits/inturrupts. There's no way that I can see to mark the destination requester as "full" until a train has that stop as the _next_ stop, not just in the schedule.
Note: There is a similar race condition that exists with one provider/requester, where the provider has _more than one_ train load in storage (doesn't occur in this blueprint, but would if the fluid capacity was >200k for a provider).
In this case, a train will be dispatched to the provider -> requester.
As soon as the first train leaves the provider, and is on the way to the requester, a 2nd train will be dispatched.
(I'm currently debugging using fluids).
Here's a blueprint string I'm using to test with. Fill the providers with fluid, and turn on the combinator at the depots, and it'll start running. The "requester" combinator on the lower requester is off (to demonstrate the above issue).
It does not check if there is a supplier. so if there is a request for iron ore and the train will just sit there, searching for iron ore forever completely ignoring the requests for copper ore which can be easily fulfilled since the copper mine storage is full.
It does not check how many train are needed to supply it. if there is a demand for 1 load of copper it can and will send all trains to get that 1 load.
Sopenas wrote: ↑Tue Oct 22, 2024 4:23 am
I was thinking about having global logistic network too for trains and try to calculate needed trains. But my bases usually are huge and when i start to think about size of logistical network I would have in this case - well i do not think this would end well.
I was wondering maybe it would be possible somehow to do purely with train scheduling without global train logistical network.
you can connect wires direct to radar dishes. they all share one global logistic network and it will save you some effort having to run wires throughout the base
EDIT: And yes, you can do it easier by calling all the requesters the same name but I find it confusing since I often play with outposts style instead of a bus.
Re: 2.0 train schedule setup
Posted: Thu Oct 24, 2024 8:46 pm
by CarbonPhosphate
Specifically, when:
* Two providers are online (have >1 train of fluid)
* One requester comes online
In this case, the conditions for the interrupt are satisfied for _two trains in the depot_. Even though the first train gets scheduled, routing to one provider and the requester, the provider doesn't get marked as "full" until the train is actually on the way to that station!
Two trains will get dispatched, one to each provider. The first one will fill and head to the requester, while the 2nd will sit and wait at the provider until the requester needs another train.
it's not pretty, but I've figured out a solution to this
I've got a timer counting from 1-60, one number every two ticks (has to be two because one is too short) and each depot station only releases its train while the time is the correct number. It's not the most scalable, but it's at most a 1-second extra delay for every thirty trains you have so it's not too bad.
Basically each depot is given the check signal when its unique number is on the timer, and trains only leave depots when they get that signal. Stops two trains responding to the same request.
It's actually not that bad to give each depot a unique number with the new blueprint parameter formulae
Re: 2.0 train schedule setup
Posted: Sun Oct 27, 2024 6:24 pm
by BiergitKraft
I wanted to deliver multiple items to one train stop on demand.
I solved this by assigning each train stop an individual bit for each item that should be delivered to that stop. All stops are connected to the same logical network. For example a stop needs crude oil and water, I assign it i.e. bit 0 for water and bit 3 for oil. So if the amount of water drops below the threshold, the combinator sends (1<<0) aka 1 Water to the network. If oil is missing, (1 << 3) aka 4 crude Oil is send to the network. The bit chosen is also defining the priority as we will see later.
Other train stops that need oil or water might add a 1 to their assigned bit and all adds up on the logical network.
The Train only has one stop (I didn't add depots so far) to load water or oil or whatever, the rest is made by interrupts. Since we cant use AND in the interrupt conditions to properly mask a single bit, I use a >= comparison to solve this. Additionally we need a condition to make sure the train doesn't run empty. If water >= (1 << 0) and we have cargo loaded, the train will go to the drop assigned to bit 0. This is why the order of the interrupts of the train is important. When the train unloaded the cargo and the amount of items reached the threshold, the combinator will deassert the corresponding bit.
An example for the water train:
[*] water drops 0 and 2 need water, so bits 0 and 2 are 1. So Water = 0b101 = 5.
[*] First interrupt will trigger since 5 Water >= (1 << 2) aka 4 and the train has cargo.
[*] The train will deliver water to stop 2.
[*] Stop 2 is full, so bit 2 will be deasserted. Water will drop to 0b001 = 1.
[*] Second interrupt will not be triggered because 1 Water >= (1 << 1) aka 2 is false.
[*] Third interrupt will be triggered since 1 Water >= (1 << 0) aka 1 is true.
[*] The train will deliver water to stop 0.
[*] Stop 0 is full, so bit 0 will be deasserted. Water will drop to 0b000 = 0.
[*] No interrupt will trigger and the train will return to the schedule, so it will return to the load stop.
This is why the position of the interrupt is important. The highest bit must be the first interrupt or else all the other interrupts would trigger when a higher bit is set and not on top of the other interrupts to be cleared first. The possibility to use AND to properly de-mask unwanted bits would make this much easier.
As I mentioned, I need to add depots, but I liked some ideas mentioned above.
Pros:
[*] I can send multiple sorts of items on demand to the same stop.
[*] changing the threshold is very simple and can be done by adjusting the decider combinator in front of the bit shift arithmetic combinator.
[*] its quite simple and the train will deliver its cargo until its empty as long as all stops are connected to the network and return to the load stop when empty
[*] easy to expand when you chose your bit positions carefully, see last point at cons.
Cons:
[*] I need to connect all stops from which the train should trigger the interrupt to the network
[*] Every stop needs an interrupt (at least I think so, haven't checked out the wildcard stuff.)
[*] changing priority aka bit position might get messy if you cant go lower because you already assigned all numbers down to zero
I think there is more potential to this approach, I will keep on thinking about it.
Re: 2.0 train schedule setup
Posted: Sun Oct 27, 2024 9:13 pm
by falconfused
@Cylarc , I seem to have developed the same interrupt schedule setup as you posted on Wednesday, It's so close to working with multiple simultaneous requesters/providers/materials but I have the same problems about scheduling several trains at once (race conditions). I tried the solution proposed by someone about setting a counter that only allows one train at a time to check the conditions. But that solution still wont work, because as @Cylarc says, the station doesn't get marked as "full" until the train is actually on the way.
After investigating and testing, I now understand that there are two different categories of trains that get assigned to stops. Select a train station and observe the tabs at the top "Trains on the way" and "Trains with this stop". From all the ways I've tried to combine the logic, all of the parameters that are available (including and "Read train count-C" and "Enable train limit") seem to be dealing with the "Trains on the way" type. If I could access the number of "Trains with this stop" I could use that as a check when the interrupt is scheduled.
The Reason it's a problem is that "Trains on the way" only gets updated when the train is in directly coming to that station. and that might not happen as the first stop on the interrupt schedule.
If the interrupt could check "Trains with this stop" which gets updated immediately after an interrupt fires (no matter how far down the schedule a stop is), then we could avoid multiple trains being scheduled on a 1-train-limit stop (in which case they just go to sleep until the stop is open again). Even better would be if we could use the "enable/disable" (AKA "train limit") and make it check the number of "Trains with this stop" instead of using "trains on the way".
I'm new to this whole forum and bug-report/feature-request world, so I don't know how to get this elevated. I just want access to that one variable (Like "Read train count - C" is accessible now, which is the number of "trains on the way"). It seems like not a hard fix, and it would allow a requester-based multi-material system. Please add "Trains with this stop - O" as a possible circuit output of stations!
difference between "on the way" and "with this stop"
10-27-2024, 15-10-00.png (203.23 KiB) Viewed 7142 times
Re: 2.0 train schedule setup
Posted: Mon Oct 28, 2024 5:17 pm
by LightThemeIDE
Edit: ignore my ramblings here just see what I said in my next post.
I found this thread and wanted to share what I have been doing based off of the information provided in this thread so far. I am using radars to carry signals wirelessly across the entire map. Every requester, provider, and depot gets a radar. When a requester needs a resource, it will output a -1 signal of that resource. For my interrupts I followed what @cylarc posted on October 23rd. When a provider station has a train on the way to it, it will output the C signal of 1. I then translate that signal to be a signal of the resource type it is providing. Now back at my depot I have a radar that connects to the first depot stop. When a requester stop asks for a resource it will put out a signal of -1 triggering the interrupt and causing a train to depart. I then have a wire going from my first depot spot to a decider combinator. It checks to see if C = 0 and if so outputs everything with their current input. C cannot equal 0 until after the train has left which means that the provider no has C = 1 which means that the signal of the resource being provided should be 0 preventing any further trains from departing. I am not sure if I am on the right track or not and I need to do a lot more testing but if I get something working I will post a more coherent message
Re: 2.0 train schedule setup
Posted: Tue Oct 29, 2024 4:23 pm
by LightThemeIDE
I think I was able to get things working but I am not a big fan of the result. In a nutshell what I did was make it so that the trains in the depot depart one at a time, left to right, and double check the input signal before triggering the interrupt.
The flow is now
* Trains wait at the depot
* Requester uses logic to determine if it needs a resource and if puts a -1 signal of that resource per train needed
* The signal is put onto the global red wire that is transmitted by the radar
* Back at the depot the negative signal will come through and trigger the logic loop
* If it is said train's turn to leave the depot, and, if there is a negative signal on the global red wire, then output a green check mark of 1
* When the green check mark becomes 1 it will start a 180 tick (3 second (it can be lower I just did this for testing)) timer. If at any point during those 180 ticks the green check mark of 1 goes back to 0, then the timer stops. The green check mark has to be 1 for 180 ticks.
* The timer outputs the green check mark of 1 into a decider combinator on the green wire. This decider also takes the global red wire as an input.
* The decider then checks if any signal is less than 1, and, if green check mark is 1. If both are true then it outputs every signal with its original input count on the green wire.
* The decider's output on the green wire then goes to the train stop which passes the signals to the train.
* The train's "Generic Interrupt 2" will trigger when there is a signal with a negative value, and, it is at the depot, and, the provider is not full, and, the requester is not full
* The train will then go to the provider and pickup resources
* At the provider station there is logic that says, output the number of trains that have me as their next stop as the resource I am providing. By doing this we negate the negative number put onto the global red wire by the requester. This is where the race condition happened as the moment the train would leave there would be a race of which update would tick first, the provider taking the positive output off, or, the requester adding the positive output, or, the train depot seeing the negative number now that the provider was not negating it. This is where that timer of 180 ticks comes in as it ensures all three of those events are propagated to the global red wire.
* Once the train is filled up with the resource it will head to the requester. The requester has the same logic of, output the number of trains that have me as their next stop as the resource I am requesting, so that the global red wire knows how many requests are still in need of fulfillment.
* After the resources are dropped off the train heads back to the depot.
I really hope there is some nerd out there that is going to 200iq this and make it all work with simple magic. I feel like I vastly over complicated this. I think maybe having the trains wait at the stacker of the provider will potentially be more of a simple solution. I am using a depot because I am use to it being that way from my time with LTN. Regardless, wanted to share my success in the hopes it helps
have you found good generic train schedule setup? I have tested one, while it works i am pretty sure there are better setups. Mine setup is like this:
* all input stations (which provide stuff) are named Input
This is the part that bothers me (which isn't your fault of course). I'd like to keep my input stations with the name "<icon>Input", but it seems that currently there is no pattern matching for station names (except in interrupts and then it only matches with the cargo that the trains has currently loaded).
this works but not ideal. trains are going to inputs and unload at output. seems fine. But sometimes they go to inputs and fullly load even if no drop stations require this input. So loaded trains wait in stations or depots. Which is an issue.
Actually trains waiting fully loaded at input stations is a good thing IMHO. It means that your cargo/fluid requests will be fulfilled that much faster. For that purpose, I'd actually make the input step part of the regular schedule and not an interrupt and instead the Depot part would be part of an interrupt (with the condition that the train is empty).
The problem that you cannot have a station name like "<icon>Input", but must use the same name "Input" for all station sadly remains...
Re: 2.0 train schedule setup
Posted: Thu Oct 31, 2024 8:15 am
by bmnk115
I have several factory parts (one producing red circuits, for example).
Each one has:
A delivery station called "symbol In", where symbol is a unique signal symbol
One waiting station "resource W" for each required resource (with a train limit of one, or for more resources of two). The waiting stations deliver signals to the trains: the symbol with a value below 1 Million and the current amount of resources available in this factory part.
I use a train system with one train group per resource with the following schedule:
Go to "resource pickup" and wait till full
Interrupt refueling: refuel if needed
Interrupt go to wait: If at "resource pickup" go to "resource W" and wait until signal resource < 1k
Interrupt deliver: If at "resource W" and signal placeholder < 1M, got to "signal placeholder In" and wait till empty (I think the "if at" condition is superfluous)
I was not yet able to make the "go to wait" interrupt generic as I cannot make the signal resource variable on the currently loaded content.
Even though this system is not totally generic, it allows to use the same trains to deliver to different factory parts (remember with a single drop off station for all goods).
Some properties of the system:
As soon as a train goes from the wait to the delivery station, another train will be scheduled to go to the wait station, so a constant flow of resources is achieved.
If no (waiting) station requires trains with resources, the trains wait in the pickup places to go to the next free waiting station.
Re: 2.0 train schedule setup
Posted: Sun Nov 03, 2024 5:08 pm
by MuggenHor
I have a variation of OP & Cylarc's setup that dynamically sets the train limit.
Requester/Drop-off stations set their limit to the amount of trains that can fully dump their cargo in the station.
Additionally they communicate their required amount of trains minus their train count (trains on the way + currently stopped) to the circuit network. (train count - request count).
Subtracting the current train count is what prevents 10 trains running to a pickup/provider station while there are already 10 on the way to the drop-off/requester station.
Provider/Pickup stations however are slightly more complicated. I set them to the smallest of:
the amount of trains it can fully fill
the requested amount of trains by requester/drop-off stations (as communicated on the circuit network)
I had to use 2 decider combinators to obtain the smallest of these two. Making sure that one of them is on the red and the other on the green network inputs to them:
condition: each G <= each R --> outputs: each input count G
condition: each R < each G --> outputs: each input count R
The output of both is connected to the train stop and then used to set the train limit.
While I don't have the largest base yet and I haven't been to space I've got a fun little system that lets me just have 2 groups for transport, wet/dry. it all uses interrupts.
They are set to go a Parking station by default, everything else is interrupts.
For Pick Up Interrupt, if Empty Cargo & Pick Up is not full & Drop Off is not full, then go to Pick Up until Full Cargo & Drop Off is not full.
For Drop Off Interrupt, If Cargo (item) >0 & Drop Off is not full, then go to Drop off until (item) = 0.
All stations are set with a 1 train limit. If a train get interrupted with something else it will go park and then empty its inventory as space is available.
So my Transport trains just sit in parking until needed. And I can set item priority based on how they stack in the menu (i think that's how it works).