Advanced Combinator

by zomis

Make combinators great again! One combinator to rule them all.

Content
3 years ago
0.16 - 1.1
1.36K
Circuit network

g [creation] measuring throughput

5 years ago
(updated 5 years ago)

I already had built the following with normal combinators in vanilla, and also had created a blueprint for it, but it takes some space (although i had it optimized down to 6 comparators and a few constant combinators) and most of all it had to be connected and checked each time. thus i decided to test this mod and learn about it by implementing the same functionality with one advanced combinator :-)

I wouldn't think too much about balancing it, since it is a cheat anyway and maybe should mostly be used for testing or in bigger setups that are partially built in cheat mode or with the creative mode mod anyway ...

how to measure throughput:
connect a wire from a belt (set that tile to "enable=false, read belt=true, and read mode=pulse") to an arithmetic combinator which is setup with either "<specific item> + 0" (for measuring a specific item only and ignore other items on that belt) or with "each + 0" (for measuring any items on the belt). in any case, output of that arithmetic combinator has to be "signal P" which is then connected with a red(!) wire to the advanced combinator. that's all, but if you want to see the results, you can connect a green wire from the advanced combinator to several nixie tubes or some other setup of your own.

this advanced combinator can also be used to measure the contents of a chest or some other storage system: setup is the same as above on the belt that leads to the storage, and an identical setup is done on the outgoing belt of that storage, but using N instead of P on that arithmetic combinator. P is for Positive Pulse (to add incoming items), N is for Negative Pulse (to subtract outgoing items, but no need to make the value negative yourself, just copy the same equation "xxx + 0" to both combinators and output P or N).

the measurement counts items for one interval and thus the results are only available at the end of the interval, but then they are exact, in contrast to other throughput measuring methods which give some results more quickly, but always lag behind the real values and never are exact. the length of the interval is 3600 ticks (1 minute) by default, but can be set to any value by connecting a constant combinator to the same redwire input and setting up the desired number of ticks on signal I (eg I=60 to measure throughput per second, or I=25000 to measure throughput per nauvis day). if you want to reset the system and clear it, add a signal R to that same combinator with any value except zero

finally, you might want to also see the results of measurements ...
on a green wire that comes from the advanced combinator, you can find these values:
X is the value that is input as P and N (X=P-N)
0 is the running measurement for the current interval
1-6 are the final results for the last 6 intervals
black is the timer which counts from 0 to the interval length
grey is the interval which was set by specifying I
white is a pulse that is generated when the interval resets
(can be used eg to trigger a speaker which beeps once per interval)
and if you don't want to calculate durations yourself, you can use the signals M and S which give the remaining time of the interval in minutes and seconds, or the percentage quota Q of the elapsed interval (100*black/grey)

hints for displaying belt throughput: for fully compressed yellow/red/blue belts, throughput should be 800/1600/2400 per minute (with I=3600, or as default when no i is given), but i also like to measure throughput for 15 seconds (I=900) since that results in 200/400/600 which is nicely shown on small nixie tubes as 2 00 / 4 00 / 6 00 (and i get results 4 times faster than with I=3600), and those numbers 2/4/6 are exactly the number of yellow lanes (half belts). when measuring throughput eg of a main belt and using this display, i easily can see how many belts really are needed, eg that i would need more than one yellow belt but less than half a blue belt for 2 55 (between 2 and 3 yellow lanes), or 8 00 would be 8 yellow lanes (8/2=4 yellow belts, 8/4=2 red belts, or 8=6+2 for one blue and one yellow belt).

and finally, here is the "program" to copy into the advanced combinator :


comment(measuring throughput - all inputs on red or green wires - all outputs on red and green wires);
comment(set interval to I ticks - 60=sec - default if no I given 3600=min - 25000=Nauvis day - 216000=hour);
comment(output - timer on black - interval on grey - pulse on white);
set_simple(20,virtual/signal-grey,add(red(this,virtual/signal-I),green(this,virtual/signal-I)));
if(compare(current(20),=,const(0)),set_simple(20,virtual/signal-grey,const(3600)));
if(compare(red(this,virtual/signal-R),≠,const(0)),set_simple(20,virtual/signal-grey,const(0)));
set_simple(19,virtual/signal-black,add(previous(19),const(1)));
comment(or as percentage quota Q = 100*black/grey);
set_simple(24,virtual/signal-Q,div(mult(const(100),current(19)),current(20)));
comment(or as M and S for remaining minutes and seconds);
set_simple(22,virtual/signal-M,div(sub(current(20),current(19)),const(60)));
set_simple(23,virtual/signal-S,mod(current(22),const(60)));
set_simple(22,virtual/signal-M,div(current(22),const(60)));
if(compare(current(19),>=,current(20)),set_simple(19,virtual/signal-black,const(0)));
if(compare(current(19),=,const(0)),set_simple(21,virtual/signal-white,const(1)));
comment(input positive pulse as P - negative pulse as N);
comment(show resulting value for current tick as X);
set_simple(13,virtual/signal-X,sub(add(red(this,virtual/signal-P),green(this,virtual/signal-P)),add(red(this,virtual/signal-N),green(this,virtual/signal-N))));
comment(output running total for this interval on 0);
set_simple(14,virtual/signal-0,add(previous(14),current(13)));
comment(output result for last 6 intervals on 1-6);
set_simple(6,virtual/signal-6,previous(6));
if(compare(current(19),=,const(0)),set_simple(6,virtual/signal-6,previous(5)));
set_simple(5,virtual/signal-5,previous(5));
if(compare(current(19),=,const(0)),set_simple(5,virtual/signal-5,previous(4)));
set_simple(4,virtual/signal-4,previous(4));
if(compare(current(19),=,const(0)),set_simple(4,virtual/signal-4,previous(3)));
set_simple(3,virtual/signal-3,previous(3));
if(compare(current(19),=,const(0)),set_simple(3,virtual/signal-3,previous(2)));
set_simple(2,virtual/signal-2,previous(2));
if(compare(current(19),=,const(0)),set_simple(2,virtual/signal-2,previous(1)));
set_simple(1,virtual/signal-1,previous(1));
if(compare(current(19),=,const(0)),set_simple(1,virtual/signal-1,current(14)));
comment(reset total running count if interval is done);
if(compare(current(19),=,const(0)),set_simple(14,virtual/signal-0,const(0)));



final remarks:
with the advanced combinator and this "program", it is much easier and faster to setup the throughput measuring, and also easier to show the last 6 intervals (my vanilla setup only showed the last interval), but it is more difficult or even impossible to build this "throughput meter" for ANY number of different items at the same time since i have no idea how to implement "each" in such a program. my vanilla setup was able to simply store "each" signal and on the output you were able to select which items to show by setting up one nixie display for each item type (on one output wire for the current interval and on another output wire for the last interval)
I also failed at first by using one signal "grey" which was then immediately sent on the red output and read back on the red input, and similar applied to X vs N/P, etc. by using only red wires for input and green for output, i could partially avoid this effect, and by using different signals for input and output there might even be no such problems any longer, thus being able to extend the program a bit and allow inputs on red or green wires (output goes to red and green wires anyway; it would be nice if i could specify that some output value goes only to red or only to green wires).

edit1 : formatting and final remarks
edit2 : hints for belt throughput display
edit3 : extended program to use red OR green for input, and also calculate Q

4 months ago
(updated 4 months ago)

I have updated the "code" a little bit for myself:

default interval set to 10 seconds,
if you input blue belt, then it will output rates relative to the blue belt throughput: 100 = 45/s = 1 belts, 150 = 67.5/s = 1.5 belts, etc.
otherwide it will output per 10 second: 450 = 45/s = 1 belts, 675 = 67.5/s = 1.5 belts etc.

comment(measuring throughput - all inputs on red or green wires - all outputs on red and green wires);
comment(input: I - interval of measuring, default I=600=10 seconds, R>0 = reset, "blue belt" - output rates recalculated as blue belt);
comment(output - timer on black - interval on grey - pulse on white);

set_simple(20,virtual/signal-grey,add(red(this,virtual/signal-I),green(this,virtual/signal-I)));
set_simple(10,virtual/signal-Z,const(0));
set_simple(10,virtual/signal-Z,add(red(this,item/express-transport-belt),green(this,item/express-transport-belt)));

if(compare(current(20),=,const(0)),set_simple(20,virtual/signal-grey,const(600)));
if(compare(red(this,virtual/signal-R),≠,const(0)),set_simple(20,virtual/signal-grey,const(0)));

comment(timer increment);
set_simple(19,virtual/signal-black,add(previous(19),const(1)));

comment(or as percentage info = 100*black/grey);
set_simple(24,virtual/signal-info,div(mult(const(100),current(19)),current(20)));

if(compare(current(19),>=,current(20)),set_simple(19,virtual/signal-black,const(0)));
if(compare(current(19),=,const(0)),set_simple(21,virtual/signal-white,const(1)));

comment(input positive pulse as P - negative pulse as N);
comment(show resulting value for current tick as X);
set_simple(13,virtual/signal-X,sub(add(red(this,virtual/signal-P),green(this,virtual/signal-P)),add(red(this,virtual/signal-N),green(this,virtual/signal-N))));

comment(output running total for this interval on 0);
set_simple(14,virtual/signal-0,add(previous(14),current(13)));

comment(output result for last 6 intervals on 1-6);
set_simple(6,virtual/signal-6,previous(6));
if(compare(current(19),=,const(0)),set_simple(6,virtual/signal-6,previous(5)));
set_simple(5,virtual/signal-5,previous(5));
if(compare(current(19),=,const(0)),set_simple(5,virtual/signal-5,previous(4)));
set_simple(4,virtual/signal-4,previous(4));
if(compare(current(19),=,const(0)),set_simple(4,virtual/signal-4,previous(3)));
set_simple(3,virtual/signal-3,previous(3));
if(compare(current(19),=,const(0)),set_simple(3,virtual/signal-3,previous(2)));
set_simple(2,virtual/signal-2,previous(2));
if(compare(current(19),=,const(0)),set_simple(2,virtual/signal-2,previous(1)));
set_simple(1,virtual/signal-1,previous(1));

comment(convert section - blue belts * 100, "100" is 45/s);
if(compare(current(10),>,const(0)),set_simple(15,virtual/signal-B,div(div(mult(current(14),const(400)),current(20)),const(3))));
if(compare(current(10),>,const(0)),if(compare(current(19),=,const(0)),set_simple(1,virtual/signal-1,current(15))));
if(compare(current(10),=,const(0)),if(compare(current(19),=,const(0)),set_simple(1,virtual/signal-1,current(14))));

comment(reset total running count if interval is done);
if(compare(current(19),=,const(0)),set_simple(14,virtual/signal-0,const(0)));

New response