#Train timings

1 messages ยท Page 1 of 1 (latest)

dapper python
#

So my brain is flipped for some reason and I need a rubberduck who can ask the right question that I can't, if you don't mind. I'm going to edge detect on the rear of the train b/c the front is actually braking distance and I want to ignore that

#

The greater network will consist of only merges. I can automate any timing detection, warm up circuits and such.

#

I guess it's reserved stuff? But my brain refuses to figure out which controls which

#

Or if they both do

#

I know the mergers are important, detecting when trains hit each merger. So probably it's just "trains already on, must reserve"?

clear pivot
#

What exactly are mergers?

dapper python
#

The return lines are merges, rather than intersections.

#

The other part is controlling for speed, without having control lol

clear pivot
#

Could train limits/number of trains at station be used to determine if trains are entering a merge?

dapper python
#

Mmm, I could enable/disable waypoint but I'd rather not as it'd be global anyhow

#

I think I'm globally wiring as it is, I don't see a way around that. But I'm trying to get the control mechanisms down to what I actually need

#

Which, I suppose, is that once a train is already on the tracks, I don't put another train on in a way that it crashes, yeah?

clear pivot
dapper python
#

lmao hopefully the track takes care of that

clear pivot
#

Right...

dapper python
#

These are where things get a little more complicated and I want to abstract though

#

I don't think the difference between the first station and the last station is enough that I should pay attention to it

#

I think I can group those up, and find minimum and maximum travel time, with a warmup circuit

#

That's what led me to think about the mergers though. That's where the thing actually happens, or doesn't

#

I should be able to release a copper train at the same time as an iron train

#

exact same time, and I don't need to process any further than the merge

clear pivot
#

to my knowledge, thats not a vanilla feature

dapper python
clear pivot
#

need to experiment with this. That might be your alternative for signals engithink

dapper python
#

Oh it 100% is lol

#

I only need detection

clear pivot
#

so if train goes past, then activate previous rail

dapper python
#

Okay so trains already on the tracks have to reserve. That means they know when they're going to hit the merger

#

That merger then has to block the other track

#

But only for the time frame when it'll be problematic

#

Speed is dealt with on "clearing the other side"

#

Which is the split

clear pivot
#

so if train leaves station, lock all other stations. free lock when merge completes

dapper python
#

So it could release if the new train can clear the next "block", IE distance to split, before the train already on the tracks clears

#

That's speed control, oh yeah

#

Wait it's ONLY clear time??

#

Time to clear block if slow train is in front. Time to hit merge if slow train will be behind

#

Shit this is accidentally almost LTN as well

#

Okay and min/max times are only needed for one of the calculations too, now we're getting somewhere

#
  1. Group sources and sinks for circuit, warmup tests extreme range of groups on many-to-many. There is only one relevant merge, this is still ostensibly a 2-track system.
  2. Once trains are on the tracks, they are on the tracks until they get off.
  3. Minimum time is the fastest the train can hit the merge. If the merging train will arrive behind the train on the tracks, you can send a train behind the reserved train.
  4. Maximum time is the slowest a train will clear to their split, given the grouping.
  5. Group timings are all relative and can be checked during warmup
#

So I need gates for time to hit merger, and time to hit split?

dapper python
clear pivot
#

I dont think you need time, just conditionals

dapper python
#

Right, I'm just thinking about how to repeat this information down the tracks

#

The big thing is the science trains, right? I don't want the space science train to shut down my entire factory the whole time

#

When it takes off, it has time to next merger/split. I think either decision does similar things but has to be handled differently?

#

Full speed trains, between two mergers, will take the same amount of time. So I don't have to do it for blue, then purple, then yellow. They need to know their time to full speed once they're on, maybe

#

When space science passes through yellow, the yellow sci ore trains have the min-behind/max-ahead thing. Then when it passes through purple, same thing, this time yellow is also doing the same thing. There's a window I can't release trains

#

Yes, there it is. There is a window around each science train, where I can't release new trains

#

The mergers need to know when they're blocked. They send that info to the group

dapper python
#

So this is interesting. Gates stop detecting trains when the trains nose crosses. The only thing they actually detect is braking distance, which is also a speed detector

#

For a group of trains that are all the same size, the longer the braking distance(simple counter on gate signal) the faster it's going

dapper python
#

How far should I actually push this? I feel like I can save a lot of circuits by dumping a little bit of precision

dapper python
#

I need my FIFO too. This circuit is getting big. Rip

dapper python
#

Aight, it's not the most automatic, but I think I can determine the important timers and remove the circuits after @clear pivot

dapper python
#

This gap is pretty reliably 8 ticks different

dapper python
#

Yeah, from dead stop, this is 8 ticks farther. I would've thought that time got ticked on at the end. Maybe it does and it's still 8 ticks?

#

This pair I'm looking at is 937 versus 945 ticks. So I guess it's final speed, as max would be 11 tiles and I moved 10

pliant citrusBOT
dapper python
#

Ah dang, it's a little messy, because I have trains waiting. It's not complete

#

These trains have already departed.

#

The ones at the mines also have departed already and are no longer being circuit controlled at that point. I'm thinking to prevent departure but that is going back to global stuffs

#

I will have trains waiting at both ends so I have to address this. Any ideas?

clear pivot
#

honestly, would probably just be simpler to have many gates just circuited with each other

#

@dapper python

#

If you are going global network route, may as well implement the equivalent rail signal equivalent

dapper python
#

Actual red light lmao

#

You know it's not the worst

#

I don't think there will be damage

#

it's very slow damage

clear pivot
#

What are the remaining problems @dapper python

dapper python
#

Fine tuning?

clear pivot
#

So just timings?0

dapper python
#

I think so

#

Yeah like this train is LONG gone

#

lmfao almost 800 ticks too much

dapper python
#

lmao so for the duration they push against the gates, they don't seem to be doing any damage. I think this is actually going to work out

velvet sigil
#

so i was wondering, can you set signal colour on signals?

#

i know, dumb question that is probably already answered

dapper python
#

You can force closed

velvet sigil
#

but not force open?

dapper python
#

Correct, you wouldn't want that anyhow

velvet sigil
#

damn

#

no i was thinking about one of the messages

#

where you wished for way to detect trains

dapper python
#

Forcing open is invariably more than 1 train per block

#

Oh yeah, I should update. I have a neat red/green circuit

pliant citrusBOT
dapper python
#

Uhhh shit ignore the guys on the right, those are unrelated

#

omg it's not repeating like I wanted it to, my everything was off. I removed 3 combos and fixed the behavior to do what it's supposed to

dapper python
#

I don't know why I always seem to get what I want as far as trains, at night, but here we are lol

dapper python
#

@clear pivot So I have one last generic problem, and I guess it might not even be a problem? High speed merges at distance, and combining complex networks. Copper merges all the way over on the right, and it'll happen at full speed b/c it's like a KM away. I have further distances to consider later. I guess the problem I've yet to specifically identify is how to do the delays across multiple merges?

#

Oh I guess it's just "all farther trains" isn't it....

#

I have to measure some trains at some weird places then, and transmit some of the information a long ways. I might have a use for entrainglement!

#

That's neat too b/c I can have multiple places block the same input, I'm only transmitting one bit.

clear pivot
dapper python
#

lmao yea

pliant citrusBOT
dapper python
#

@clear pivot Quantum Entrainglement makes it so damn simple, I'm only transmitting one bit, "red light," so it's actualyl a perfect use case

#

It's combinator free, no power needed

#

And completely generic. You can place them wherever and it'll block that specific spot.

dapper python
#

@clear pivot I'm realizing the only difference between a merge, and a crossing, is that a crossing actually has less competition time? It's only the train itself for the moment it's there, the acceleration time doesn't matter anymore, just presence. However, the distance at which the releases are being controlled is getting impractical to measure

#

I can put stuff wherever but it's a guess, I save and let time tick, diagnose crashes, adjust

clear pivot
dapper python
#

lol yeah in 2.0 crossings are irrelevant, only merges matter

clear pivot
#

Crossings will still be useful

#

Especially for high throughput scenarios as you@can make use of track above and below

dapper python
#

Tracks crossing will be useful, it's just that they have no impact on train flow anymore

#

Only merges have an impact on flow

#

ofc, crossings aren't strictly necessary

dapper python
#

@clear pivot Ahhh I finally understand why it's not syncing like I thought it should. Distance gets added twice, and both times are added onto the return side. When the limit goes to 1, the train goes on the entrance track, that's easy enough to sync. But the return trains do not have the same length of cycle. The inbound from start time being totally synchronized with a simple clock, means that it arrives at the station later based on distance, stays for the same time, and then spends more time coming back. So if inbound is sync'd on a simple clock, return is automatically going to desync itself

dapper python
#

The one in the video was like 1 second behind, so it's not going to have the same sync on the next train

pale merlin
#

you have to know how long a train can take to clear it out of the track safely.

dapper python
#

Yeah, I have a python program that can calculate all my timers for me

pale merlin
#

basically the exit ones are different from entrance one.

dapper python
#

Yeah, and the problem is that it's not on the same cycle length

#

The farther ones get the distance added twice so the frequency changes

pale merlin
#

exactly, so each line will have a different length

#

how do you prevent trains from going to the wrong station?

dapper python
#

Flash limit 0/1

pale merlin
#

they are only ever designed to go from A / B if you use timing

dapper python
#

Yeah, each station has a specific time it turns on

#

They won't repath if they never slow down for a signal

#

Tbh they won't re-station unless there are open limits, and there never are

pale merlin
#

its basically a timing issue, for each train station A -> B you need to know the distance, and you can calculate the time.

dapper python
#

Distance in tiles, unload time, cycle time

#

And yes I generated that with a script

pale merlin
#

problem is does this system also keeps track of trains already moving?

dapper python
#

I got through red, green, and blue, with a naive scheduler and gates

pale merlin
#

well I mean does it keep track of when a train should be on the track from B -> A? so it wont launch a train that's already moving?

#

Wait let me rephrase that.

#

When B Launch 1 train, how do you know it won't launch a train which is too close to each others path?

dapper python
#

I must not understand something about what you're asking. It remembers nothing. There's a clock on a cycle, and schedule slots are every 130 ticks. I send a train every 5th schedule slot, so the limit combo is just "when schedule slot equals" and all of them are 5 slots apart

dapper python
pale merlin
dapper python
#

Right, 5*130 ticks apart

pale merlin
#

maybe should be higher, for return trains?

dapper python
#

That's what works in blue

#

There are certain cycles I have to hit

#

Some of the copper stations need a train every 25,960 ticks, because that's how fast it takes to consume a train's worth

#

Others are twice that

#

Others are on a 33,600 tick cycle

pale merlin
#

Noted, just going by return and train crashes.

dapper python
#

Yeah, that's the thing. If they sync up in one direction, they will not be on the same sync, on the other side

#

The simple schedule runs into problems when you involve long distances

pale merlin
pale merlin
#

also the cycles for each should be in here as well.

dapper python
#

(Maximum interval because of train count, cycle time/100 ticks)

pale merlin
#

The biggest issue I keep in my head is
Depot -> Diff station . Easy.. One to many rails.

But many to one, is too hard to do, you get trains leaving at any moment. they cannot leave without clearing a certain section

dapper python
#

Yeh, the funny part to me is why exactly it doesn't work any more, when it did before mostly

dapper python
#

I can sync either side no problem

pale merlin
#

well if you redesigned the rails you get issues, and have to readept the schedule

dapper python
dapper python
pale merlin
dapper python
#

Right, which I don't think is something I'd like to use

#

I'm trying to avoid any and all extra steps I can

pale merlin
#

you just have to extend the schedule .
A -> B how long did it take.
Station -> How long unload + additional wait timer from other trains to prevent crashes
B -> A (Depot) how long ?

dapper python
dapper python
#

If I send a train at 100, 200, 300, 400, 500

#

Those trains will get back at 1100, 1220, 1340, 1460, 1580

#

Whatever sync, will be different

pale merlin
#

so the clock ingame desyncs?

dapper python
#

No, the distance is counted twice on the one side because of how the trains are called, by stations

#

They're called at 100,200,300 etc., but they arrive at 200, 310, 420

#

Stay for however long, then leave and also take extra time then

pale merlin
#

oh you mean based on depot #1 and depot #2? ๐Ÿค”

pale merlin
dapper python
#

These trains are all called at the same interval, they arrive at a different interval

#

I am

#

It's this extra few tiles

#

It's not much, that's why i could ignore it in RGB

#

Once they're at speed it's like a quarter of a second extra coming, and going

pale merlin
#

yeah the finetuning is the hard part engithink

dapper python
#

I can't adjust schedule based on distance either

#

I could greenlight at station with longer counters, I suppose

#

I just feel like there's some simple trick I'm missing with frequencies. I could adjust ALL of the unload timers

#

I could give them a little more track before they rejoin the main

pale merlin
#

im more thinking in the way of modulo distance, where distance equal to train + topspeed.

#

if its reached the train should be able to leave, and do its thing to leave without crashing

dapper python
#

There may be a way to detect conflicts based on comparing schedule positions. The higher these numbers, the farther the station

pale merlin
#

yeah I was thinking like segmenting , and you already did that nice, like how many tiles does it need in order to not crash in other trains

dapper python
#

I'm fairly sure I'm close lol, I've put a fair bit of work into this

#

I think you may have given me the tool I need

#

each schedule signal is also distance

pale merlin
#

exactly, maybe

#

how many signals do fire?
as in your depot has how many triggers from going?

dapper python
#

I have tentatively found a way to keep all of them on the same cycle

#

There's something with having shared factors

#

if they're all base 10, for instance, if you send one at 1,11,21,31, and the modulo is also based on 10, say it's 500, then it won't ever sync up with one that's going at 3, 13, 23, 33, with base 400 cycle

pale merlin
#

I was going by another idea as well ,
groupings of trains to leave at once.
Like distance groups , one leave
mid group one train leaves
close distance group one train leaves.

And if they do not get to the station on time they have to wait till next group trigger.

Maybe thats what you mean with distance.

dapper python
#

So far, I've stuck to nearest-to-farthest, which accomplishes that grouping. But that's one thing that's on the table

#

They still can show up in the wrong order, too

#

My copper mines naturally timed with that iron mine, was soo nice

#

They're -1 but it doesn't matter, they're always -1

pale merlin
#

do you do any triggers on the unloading / smelting station? or once left from depot they are free running?

dapper python
#

The only control is limit 0/1 when the stop in question is scheduled to call a train

pale merlin
#

so the station calls a train? engithink ?

dapper python
#

This conversation has been super useful to me, I'm really crunching the problem down. I have to adjust the schedules

#

lol yeah, each requester calls at their scheduled time

pale merlin
#

np ๐Ÿ™‚ I understand 80 % of it.

dapper python
#

Hehe, I'm definitely into some deep, dark waters

#

I know I have the space on track for it though

pale merlin
pale merlin
dapper python
#

That's one of them! XD The track can handle it, I square!

#

There's so much extra room even with those trains that were on the fastest cycle

pale merlin
dapper python
#

I did really like the sync of simultaneous release and track spacing

dapper python
#

lol except there are zero brakes

pale merlin
#

yep

dapper python
#

But yeah that happens all the time on multi-track rail networks

pale merlin
#

in an ideal world, your track is reserved for you and all the timings are perfect and nobody has to wait on anything engithink because parking is guaranteed

dapper python
#

Yeah that's the world my RGB builds live in

#

So interestingly, I can do "time passed and circuit condition"...if there's only a few troublesome merges, I might just be able to stop those

#

The circuit condition would be just an extra timer though, and UPS optimization is a huge part of this. So that's why time passed first, it's not supposed to be doing the circuity stuff

pale merlin
#

yeah I leave you to it ๐Ÿ™‚

dapper python
#

Thanks so much for the help!

dapper python
#

Okay I found a cycle where some slots exist

#

Bah, they disappear when I extend the check to more depth of cycles.

#

Some still exist on that cycle at timing 5

#

That's (conflicts,slots) for various timings.

#

w/ base 10, slots exist on interval two, and slots exist on interval 5, so I'm more sure about the factors thing.

#

Yeah, this is what's happening

#

Factors will end up with the same position at the end of the long cycle

dapper python
#

Whew, okay, I can find the empty spots on the track now.

#

(slot, crashes predicted on naive cycling)

dapper python
#

The minute a pattern starts to form, it disappears again.

dapper python
#

Ah fuck and I just realized something I was doing that's critically wrong, about how I'm checking schedule slots. This is only for the first station, I didn't iterate stations. But I think I need to rethink this anyhow. There's a point where complexity starts spiraling and it isn't doing what it's supposed to, which is "fewer things in-game to avoid crashes."

#

I'm trying to stretch scheduling too far. It can be used as a part of this but trying to sync so many different schedule intervals isn't going to fly.

#

I can fit a quadratic to time/distance so at the least, I can do a little bit of distance calculation, but this approach is getting lost in the sauce. Scheduling can get 99% of the way there, pick the best schedule, then somehow stop conflicts. The gates are enough, I just wanted to remove them.

clear pivot
dapper python
#

Yea

#

It's doing the simple cycling, with a base clock that I'm doing multiple modulos on. So it's detecting that slot 48 on the modulo 490 schedule, crashes with 6, 12, 30, 36, etc., from mod330

#

Most of them are 1 crash

#

Even w/ primes, which I guarantee will eventually sync, it takes a while and it's just the one

#

W/ a shared base they never sync

clear pivot
#

Do you know if train schedules are done in parallel or on the same core?

dapper python
#

I'm not sure, but I think it doesn't matter for me? I've wholly mitigated pathfinding

#

And also station switching. When a station calls, it is assigned a train the next tick

clear pivot
#

If you are going with a timing approach, this methodology may be inherently flawed if its operating over a single core while the train scheduling isnt

dapper python
#

I must be misunderstanding something here. All of the work should be done ahead of time?

clear pivot
#

My understanding is this program is meant to help find optimal scheduling delays given an arbitrary number of trains

dapper python
#

The "Scheduler" is just a simple clock with a /130 to be 'schedule slot' signal. I send a train every 5 slots

dapper python
#

I'm trying to do the program in a generic fashion wherever I can, given the option to do it generically, I do

#

Cost me nothing to put those in

clear pivot
#

Ok, so regarding actual factorio for a moment, do you know if train schedules are processed on the same core or in parallel?

dapper python
#

I do not know

#

Probably single

#

This, yes?

clear pivot
#

Yeah

dapper python
#

This is asleep until 72s

clear pivot
#

Ok, but if you have two trains with a similar delay, are they processed in parallel or after the other processes?

#

If thats the case the concern was that schedules executed on a different cores will not be subject to the same perfect timing

dapper python
#

The odds of that being tiny aside, I would assume single core

clear pivot
#

Then yeah your program should sync fine

dapper python
#

My window to work in is like +-100 ticks

#

Yeah I'm not concerned anyhow, if I'm +-1 tick I should be fine.

#

A huge motivator here is UPS efficiency, so "time spent" would be very nice to keep

#

The thing is that these simple schedules, "This station gets a train when S%490==48", it's very few collisions. That's very little work in the game.

#

I could add circuit conditions to the train, but that's defeating the purpose. I could track every train with my FIFO system and decide if it's safe to send a train or not, but that's 300-500 combos, again defeating the purpose at least a bit

#

I know what the problem is, it's distance adding an extra layer of variability. I even know how to access that layer in-game already, so long as I stick to "farther stations get higher schedule slots" I can pretty easily gauge distance.

#

There's no pattern to the conflicts though. I'd end up having to effectively store multiple combinations of at least 2 and maybe more input slot modulos.

L(1) when S%490==49 and S%330 in 7,13,31,37,157,187,192```
#

That's very complicated in factorio. I don't want to pre-calculate to put that many things in. So I'm kinda stuck

clear pivot
#

different approach, why not use a station to synchronize timings? @dapper python

#

basically from what i recall from your particular problem, merging trains and them firing off causes issues. You could deliberately throttle that by having each train route to a special nearby station that doesnt release the train until the timing syncs

#

although i guess youd still be at the same problem of using walls to block things off

dapper python
#

Yeah that's a possibility. Actually it can be an acceleration loop

#

So when the train is released it's at full speed. But there's limits to that b/c you need a schedule that alternates AB enough times to cover all delays, so the train has to hit that on the way out

#

You can just spam clearing on the end, it's not really a problem, but 10 extra stops isn't ideal

#

Track timing with loops might be possible too but I don't see how

#

The problem isn't the entering train, the desync comes from the farther train

#

Waitaminit, the desync comes from the farther train?

#

This makes it worse?

dapper python
#

lmao I could normalize the distances. More track for each station closer. Then every train goes the same distance.

dapper python
clear pivot
#

lol nice

#

kinda reminds me of airports for some reason

dapper python
#

Hmm, airports? I haven't been to many but I suppose they're pretty tightly scheduled too aren't they

#

Ohh it's the baggage carousels

clear pivot
#

i didnt even consider those but i was thinking of the the runways

#

airplanes basically meander to a lane that allows to them to take off

dapper python
#

That too, yeah. I had done larger acceleration ramps but that wasn't working, I do still need at least one I think, but perhaps not more than one

#

I don't need to double back for map-build, either, so that it's one-directional will be fine on map

#

This is the general solution btw. I just had to look at the problem in the right way.

#

Left is problem, right is solution. The tracks need to head in the same direction, over a certain distance, so that distance always stays equal

#

I got away with it for RGB

#

Also dead speed merging trains at 600 tick intervals require effectively two slots to accel safely, so it's for sure one acceleration ramp

pale merlin
dapper python
#

lmaoooo

pale merlin
dapper python
#

ikr? So many crashes I reset to save

dapper python
#

Okay I have one last problem to solve I think, which is a little awkwarrd considering how I did everything up till this point. The coal trains have to get snaked in at bad times, and each section on the right is associated with a section on the left, to stop the weird overlaps from happening. I'm not sure how to snake the coal trains in b/c they're interspersed.

#

Maybe I should just try it and see what happens

#

I'll get the 5th part of the packet in b/c I have to do it that way, probably.

pale merlin
dapper python
#

Maybe not, now that I have basically an entire acceleration track for them.