Page 1 of 1

Train Counter

Posted: Thu Mar 31, 2016 9:45 am
by jameinel
This is my first post to the forums, so please forgive if I get some of the syntax wrong.

I've been enjoying Factorio, and I particularly enjoy all the mini optimization problems it presents. One of the issues I was trying to answer was whether roundabouts or cross intersections really are noticeably different for throughput. Thanks to viewtopic.php?f=18&t=18621 I managed to actually build them correctly. But one of the things I actually needed was a way to tell how many trains were passing through the intersection. I had tried to do the counting manually, but the raw throughput of a simple intersection is really hard to count, and even harder if you want to track directions separately.
train-counter.jpg (149.37 KiB) Viewed 5560 times

Code: Select all

There are a couple of semi-complex pieces going on here, which I'll try to explain. First there is the core counting circuit, and second there is the "refill/reset" bits to make it easier to reset. I was getting frustrated setting all of these up when I had 27 different stations I was managing. And as always, automate what you can :).
counter.jpg (43.86 KiB) Viewed 5560 times
The key part of the "counting" is being able to insert only a single stack onto the train at a time. So every station gets an item of copper/iron/steel plate, and when a train stops we load 1 stack of whatever item is available at this station.
  1. Is the reservoir of whatever material this station is going to be delivering.It is a smart chest limited to 1000 items.
  2. Is set up to load into the staging box only when there is nothing in the box already, and a token is waiting.
  3. Is the staging box. There should only ever be 1 stack of items in this box.
  4. Is the inserter. Set to only transfer items if there is a token in the token box.
  5. Is the token box. I chose a laser turret because of the icon.
  6. only takes the token out when it notices box 3 become empty.
  7. just returns the token once it has taken its time to get back.
  8. will be described later
  9. to be described later.
  10. A timing belt. I set my trains to stop for 5s, so this makes the token take slightly longer than 5s to arrive back at 7
2, 3, 4, 6, 8, 9 are on one circuit network. 4 has the logic "turrets > 0" to only insert when a token is at 5. 2 and 6 have the logic "turrets > plates". Which when 3 is empty, but 5 is full, is true, which will cause the token to be taken, 3 to be loaded. What's nice is that since stack size > 1, it stays false even when the turret returns. The next trigger is only when 4 empties the box at 3.

8 & 9 are present just to allow me to use exactly the same pattern at all train stations. They count copper-plates + iron-plates => signal 1, steel-plates + signal 1 => signal 0. That way I can fill 1 with copper, iron or steel plates and everything just keeps working.

There is one other nice feature here, which is that all of these are set up with the Logistic parameter "number of Storage Drums > 0". It doesn't really matter what the token is, but it means that I can start (and stop) all of the counters at exactly the same time. I don't happen to be storing Storage Drums normally.
accumulator.jpg (31.27 KiB) Viewed 5560 times
This is what actually counts where the trains came from. Only tricks here are that 2-4 all use the "number of Storage Drums" so that they stop accumulating at the same time. They also are on a green circuit network which says "don't accumulate whatever is in the storage pool". That way the station that delivers iron-plate won't count iron-plate.
reset.jpg (49.67 KiB) Viewed 5560 times
This is the "initialize" / "reset" logic. I got really tired of putting 1 token into the token box all the time, and when you finish doing some counting, the trains will still have some items in them. Also, you need to fill the storage pool before you start doing anything.
1 is a simple requester box initialized to empty in the blueprint, so I don't end up filling the wrong item. But once I lay it down I can set it to request 100 of the right plate, and leave it. The inserter at 2 will fill the pool at 3 (which is capped at 1000 items).
4,5,6,7 is all my trick to get a single item initialized into the token box. With upgrades, inserters can move 5 items at once between boxes, but only 1 item to/from belts. So I use a requester (which requests a single token, but logistic bots carry at least 2), 5 loads it onto the belt 6, and 7 has circuit connection to only load onto 8 if it is empty. 2 & 7 also have a Logical connection that only when a "Raw Fish" > 0 do they do any work. This gives me a "when do I reset" phase.
9 is also watching for Raw Fish and just pulls whatever is left on the train off again, 10 is just a Logical Storage chest to allow the bots to take any waste.

Overall, it works pretty well. A few tweaks I might make if I play with it more:
  • Don't use Iron/Copper/Steel plates. Changing to some other item would let you integrate it into a real system and have it running alongside for you to do debugging of your real network throughput.
  • Accumulators could go to the same box. Slightly easier to count 1 box than 3. It would also allow for a "Reset" phase that automatically removed everything from the accumulator box into a Logical Storage chest. As it stands, I have to manually go around to read the final counts, so it isn't that hard to just shift-right-click the items away when I'm done counting.
  • shrink it if possible. As it stands it *just* fits in a 4-wide train spacing, which sometimes means having to move other things out of the way.
  • add a 4th item being tracked to allow for N, S, E, W tracking. Its really nice to measure something like a T junction, but if you wanted an 4-way it wouldn't quite work. Its a bit hard to get both horizontal and vertical tracking with too many more inserters, and I don't know a way to do a logical "don't pull out X if X is in that box over there" without manually tweaking the filters. As is, there is only 1 box you need to set up per location (the requester chest), and the rest is all handled by Fish vs Storage Drum, and manually emptying the accumulators.
As it stands, I've discovered some great tweaks to my rail network with this. Things like signals in the wrong place, causing trains in one of the side stations to block trains going into another side station.

I guess what I'd rather have is a crossing counter. Something that looked a bit like a Rail Chain Signal, that just had a counter for how many trains passed by it. This is slightly more flexible, as it lets you track where trains came from and where they went to (how many copper plates from South got to North, etc).

Re: Train Counter

Posted: Thu Mar 31, 2016 5:16 pm
by vanatteveldt
Great setup, thanks for the detailed explanation!
jameinel wrote: One of the issues I was trying to answer was whether roundabouts or cross intersections really are noticeably different for throughput.
So... are they? :)

Edit, never mind, I guess you placed the answer in a different post: viewtopic.php?f=18&t=22794

Re: Train Counter

Posted: Thu Mar 31, 2016 9:28 pm
by Berjiz
Hmm wouldn't it be easier to take fuel from the train? Take one stack from each train

Re: Train Counter

Posted: Sat Apr 02, 2016 5:47 am
by jameinel
You could take fuel from the trains, which has the nice property that you can have single engine (1-0-0) trains. However, that would give you total number of trains through your system, but wouldn't be able to tell you where from/to they went. (Am I getting bottlenecked coming from N=>S vs N=>W, etc.)

Re: Train Counter

Posted: Mon May 24, 2021 11:53 am
by ppoublan
Hi all,
I'm looking for a way to count trains passing a signal, and if possible get an average per minute.
I built something like explained in this thread, using belt and inserter, but i'm pretty sure this could be done with combinators only. But after many tests was not able to build it with only combinators.
Any idea ?

Re: Train Counter

Posted: Mon May 24, 2021 2:00 pm
by spiral_power
How's this.
I made it at 0.17.79.
C increases each time when rail signal turns red.
Very simple one.

1.png (2.78 MiB) Viewed 2538 times

Re: Train Counter

Posted: Mon May 24, 2021 3:06 pm
by disentius
Interesting! This one will do what you want, I believe.
How this works:, left to right:
- Read the yellow signal (block reserved by train), convert it to a pulse signal and count these.
- Counter T counts up to X ticks, and then sends a R(eset) signal to reset decider
- Next combinator sends the max Yellows through on R to memory cell.
- the memory cell is cleared by R one tick before it receives its next max yellows from the previous combinator

Re: Train Counter

Posted: Mon May 24, 2021 3:11 pm
by ppoublan
Really nice and does exactly what I was looking for.
Thanks a lot.
I'm definitely not good at using combinators ;)

Re: Train Counter

Posted: Mon May 24, 2021 4:38 pm
by disentius
And the same principle to calculate the average trains per minute.