How to pick a single signal from a wire and make it sticky?
Posted: Sat Mar 16, 2024 2:48 pm
by mrvn
When one places a decider combinator and sets it to "Anything > 0: Anything" it will output a single signal from the input. The problem is that it will always output the signal with the lowest ID or something. So the output constantly changes as signals appear and disappear.
What I need is a circuit that picks a single signal from a wire and then keeps that signal for as long as it exists on the wire.
So for example the wire has "50 iron plate, 20 copper plate" on it. The circuit then picks copper plates. The next ticks it's "50 iron plate, 20 steel, 10 copper plate" so the circuit should output 10 copper plate. It must not switch to iron plate or steel. The next tick again it's "50 iron plate, 20 steel" and now the circuit should switch to iron plate or steel. The circuit doesn't have to work in one tick from input to output but it must handle the input changing every tick.
Anyone have something like that?
Re: How to pick a single signal from a wire and make it sticky?
Posted: Sat Mar 16, 2024 2:57 pm
by mmmPI
Although i'm not sure it's exactly your request it reminded me of this viewtopic.php?f=18&t=89033
Maybe it's "something like that"
Re: How to pick a single signal from a wire and make it sticky?
Posted: Sat Mar 16, 2024 4:41 pm
by mrvn
Replying to myself but maybe other can use this too. It's not quite right yet as the output count doesn't change as the input count changes. Here we go:
sticky-pick-one.png (326.26 KiB) Viewed 2766 times
Left is with alt-view, right without so the wires are easier to see. Top is how I designed it and bottom is the same in compact with it's use case. All the filter inserter are just to show the wire signals.
So how does this work and what does it do?
At the input a decider combinator picks one signal out of the wire and feeds it to the memory cell. Initially the cell will store the value and after filtering out the "R" signal the value is output. Both the input and output are fed into the "Still present?" decider, which outputs R=1 as long as the stored signal is still present in the input. This lets the memory cell remember the current value. Once the signal disappears from the input R becomes 0 and the memory cell stores a new signal.
The use case for this is to program an assembler using a crafting combinator. It's important that the assembler keeps building the same thing till enough has been build so that A) the recipe isn't changed mid recipe and B) the requester chest keeps requesting the same items and they are used up.
What's still missing is for the value of the output to reflect the value of the input while remaining at the same signal. The requester chest should be programmed to request the ingredients for the number of items to be assembled. And as more and more items are build the requested amount should decrease accordingly. I can do that by adding a "red * green" circuit combining the input and output (and store with =1). Actually saves a combinator to store with =1.
Re: How to pick a single signal from a wire and make it sticky?
Posted: Sat Mar 16, 2024 6:02 pm
by mrvn
Final product: My on-demand assembler:
on-demand-assembler.png (1.11 MiB) Viewed 2745 times
The input should be generated from "wanted items - available items" using a roboport. I've used a constant combinator here for testing purposes. Each assmbler block builds something till no more of the item is needed and adds the required ingrediences (excluding raw materials) to the wanted items. Items larger than 10 are build in multiple [log_2(num / 10)] blocks as can be seen with the iron gear wheels.
The screenshot shows an example building 2 filter stack inserters. Everything else the circuit logic figures out itself.
Note: there must be enough building blocks that things break down to raw materials or available items. In the screenshot there are just enough blocks to build the copper wire in the last. Should have been 2 blocks building those.
Re: How to pick a single signal from a wire and make it sticky?
Posted: Sat Mar 16, 2024 7:01 pm
by Qon
This could be improved but I don't feel like doing that right now so I'll post this as it is right now:
Signal output of selected signal will update in value on the output. Non-selected signals changing on input has no effect. When selected signal is set to 0 (and stay that way for a few ticks) another non-zero signal will be selected.
If the selected signal is set to 0 and comes back very fast it may switch back or flicker back and forth between some signals for a few ticks, but it will quickly stabilize to correct some output. Other than that it's stable. Haven't tested with more input signals than 2 but should work fine.
Uses a pairwise multiplier that squares numbers for calculations. If you need larger numbers than the multiplier can handle (red wire signals are always 0 or 1) then you can just replace the multiplier with a more advanced one that handles full 32 bit numbers on green wire input.
Re: How to pick a single signal from a wire and make it sticky?
Note: The multiplicator doesn't need the topmost arithmetic combinator as the signals aren't in sync anyway and the memory cell can be set to store values of 1 or can be made 1 when you filter out the "1" signal. Saves 2 combinators right there. The "1" generator should maybe be a constant combinator.
The arithmetic combinator "each / 2 = each" at the top with it's output fed back into the input looks like a "20 cycle decay" operator, so the signal being fed back will hold for ~20 ticks.
Do you even need the memory cell with this? As long as the red*green multiplicator shows the item is still being build the decay will be reset and hold it's value, right? So all that needs then is the circuit to load the new selected value when empty.
So yeah, I think this can be simplified a lot. Thanks for doing this, always nice to get fresh ideas. I will try using just the decay part without the memory cell at all.
Re: How to pick a single signal from a wire and make it sticky?
Posted: Sat Mar 16, 2024 7:48 pm
by Qon
mrvn wrote: ↑Sat Mar 16, 2024 7:24 pm
Note: The multiplicator doesn't need the topmost arithmetic combinator as the signals aren't in sync anyway and the memory cell can be set to store values of 1 or can be made 1 when you filter out the "1" signal. Saves 2 combinators right there.
Feel free to modify it if you need it to be smaller
I just pasted the multiplier in without trying to update it, it is just selecting a signal so it's certainly overkill. Entire big sections of other parts of the design might be removable as well if we think a little bit more on this.
mrvn wrote: ↑Sat Mar 16, 2024 7:24 pm
The "1" generator should maybe be a constant combinator.
I'm not sure which part you are referring to here or how anything here could become a constant combinator.
mrvn wrote: ↑Sat Mar 16, 2024 7:24 pm
The arithmetic combinator "each / 2 = each" at the top with it's output fed back into the input looks like a "20 cycle decay" operator, so the signal being fed back will hold for ~20 ticks.
Yes, that is its purpose. I just selected number large enough that I would get a long enough delay for the rest of the circuit to stabilize, I did not even calculate how many ticks were needed or how many delay ticks it would give. Just added some 0s and checked that it would work. Reduce it if you want it to act a bit faster, should be possible.
It is there to keep the "selected" signal from switching if it disappears for just a few ticks. The point is to prevent the network from having a flickering signal that circulates forever because it exists temporarily for a few ticks and then disappears before its effects will propagate through the entire circuit.
mrvn wrote: ↑Sat Mar 16, 2024 7:24 pm
Do you even need the memory cell with this? As long as the red*green multiplicator shows the item is still being build the decay will be reset and hold it's value, right? So all that needs then is the circuit to load the new selected value when empty.
Try without to see. And consider what happens if the circuits selected signal disappears for just a couple of ticks so some parts of the multiplicator and signal source selector (where [signal-1] is used) has the signal while other parts don't.
mrvn wrote: ↑Sat Mar 16, 2024 7:24 pm
So yeah, I think this can be simplified a lot. Thanks for doing this, always nice to get fresh ideas. I will try using just the decay part without the memory cell at all.
I'm not sure what "decay part without memory cell" means. For something to decay there must be something that can decay, a value being updated that lives for a while without external input. Without the memory it's just a regular ephemeral signal that last a tick like any other.
Re: How to pick a single signal from a wire and make it sticky?
mrvn wrote: ↑Sat Mar 16, 2024 7:24 pm
The arithmetic combinator "each / 2 = each" at the top with it's output fed back into the input looks like a "20 cycle decay" operator, so the signal being fed back will hold for ~20 ticks.
Yes, that is its purpose. I just selected number large enough that I would get a long enough delay for the rest of the circuit to stabilize, I did not even calculate how many ticks were needed or how many delay ticks it would give. Just added some 0s and checked that it would work. Reduce it if you want it to act a bit faster, should be possible.
It is there to keep the "selected" signal from switching if it disappears for just a few ticks. The point is to prevent the network from having a flickering signal that circulates forever because it exists temporarily for a few ticks and then disappears before its effects will propagate through the entire circuit.
mrvn wrote: ↑Sat Mar 16, 2024 7:24 pm
Do you even need the memory cell with this? As long as the red*green multiplicator shows the item is still being build the decay will be reset and hold it's value, right? So all that needs then is the circuit to load the new selected value when empty.
Try without to see. And consider what happens if the circuits selected signal disappears for just a couple of ticks so some parts of the multiplicator and signal source selector (where [signal-1] is used) has the signal while other parts don't.
mrvn wrote: ↑Sat Mar 16, 2024 7:24 pm
So yeah, I think this can be simplified a lot. Thanks for doing this, always nice to get fresh ideas. I will try using just the decay part without the memory cell at all.
I'm not sure what "decay part without memory cell" means. For something to decay there must be something that can decay, a value being updated that lives for a while without external input. Without the memory it's just a regular ephemeral signal that last a tick like any other.
I'm talking about the "20 cycle decay" operator you used to avoid flickering signals. If I feed that (normalized to 1) back into the multiplicator that gives a loop that will constantly refresh the signal as long as the other input of the multiplicator gets the same signal. Once the signal is gone the value will fade away, and by gone I mean for around 20 ticks. Think of it as DRAM that needs to needs to be refreshed every <20 cycles or it looses it's value.
And when the output of the multiplcator is "Everything = 0" then I insert a new signal from the "Anything > 0: Anything" decider.
Re: How to pick a single signal from a wire and make it sticky?
Posted: Sat Mar 16, 2024 10:25 pm
by Tertius
mrvn wrote: ↑Sat Mar 16, 2024 2:48 pm
Anyone have something like that?
What do you want to achieve in the end? If we don't know the whole task, it may be we're trying to solve an XY-problem while the complete task could be solved with a different approach that doesn't require a sticky signal. There is no built in method to make a signal sticky, and it's a huge effort to code this explicitly with some memory cell, so I just don't approach problems this way.
I had the same problem (the ANYTHING operator changing the signal every tick) and i built the surrounding stuff either in a way that it implicitly does just work with this possible change every tick or I didn't use the ANYTHING operator at all and chose a different approach. I go great lengths for different approaches. The more complex an approach is, the more edge cases appear and the less reliable the whole thing becomes.
I don't see one circuit network setup as a sequential program made of of multiple operations where you code every operation with one or more combinators and you get the result after all operations processed the data one after another, and while it's running you have to fix the input in some memory cell and ignore the output due to intermediate (invalid) values.
Instead, I require one such building always have a correct output. It might have been delayed by some ticks tue to the latency of each combinator, but for every tick you have an input, some ticks later the valid output is created. There is no moment where there is an invalid output, and there is no need to keep the input constant for more than 1 tick. In such a world, you can use the ANYTHING combinator, and it doesn't matter if it changes its signal every tick.
As example, I have a supply loading station. There is a list of items to load defined in a constant combinator. The difference between train content and constant combinator is computed, so I know how many of which material to load. Then one random signal is picked with ANYTHING and fed into a stack filter inserter. The inserter swings, and if it swings back to grab the next item, ANYTHING might have been picked a different signal and changed the filter. This way it's possible the inserter picks up a different item each swing, depending on how the source chest is replenished at the same time, but in the end exactly the wanted items are transferred. While the inserter is swinging, there is a few ticks time for the output to adjust to a new input, so there isn't an exact 1:1 tick ratio for valid input/output, but such mandatory delays where signals would stabilize are everywhere if you search for them.
Re: How to pick a single signal from a wire and make it sticky?
mrvn wrote: ↑Sat Mar 16, 2024 2:48 pm
Anyone have something like that?
What do you want to achieve in the end? If we don't know the whole task, it may be we're trying to solve an XY-problem while the complete task could be solved with a different approach that doesn't require a sticky signal. There is no built in method to make a signal sticky, and it's a huge effort to code this explicitly with some memory cell, so I just don't approach problems this way.
I want my construction combinators and attached assemblers and requester chests to get a recipe and stick with it until the right number of items have been built. Switching recipes is awfully inefficient.
Re: How to pick a single signal from a wire and make it sticky?
Nice use of -2G to filter out the original signal count for the stored signal. Much better than the red*green multiplier. I hope I got the labels right in the screenshot below.
I tried your circuit and my own, based on the idea of using a decaying signal instead of a memory, with a really dirty signal. I added a clocked circuit that has 2 ticks iron gear wheel and one tick iron stick. Just to be mean.
pick-one.png (294.6 KiB) Viewed 2582 times
At first this looks really good. The output flickers between iron gear wheels and iron stick, matching the input. It only builds what's on the input signal. But when I turn off iron sticks I expected the circuits to pick the green circuit boards when iron gear wheels turn off and then stick with that.
Your circuit then flickers between gears and circuit boards. Mine has circuit boards and additionally flickers the gears. I blame the "filter existing" circuit. It takes inputs from different ticks so multiple signals get mixed together.
Anyway, that input was intentionally bad. I plan to use an crafting combinator to pick out the maximum from the input signals and that then only changes every 60 ticks. So I'm fine with an flickering input not working. Overall we've gone from 14 combinators to 9.
Re: How to pick a single signal from a wire and make it sticky?
Posted: Sun Mar 17, 2024 10:01 am
by mmmPI
Maybe with the blueprint it would be possible to help diagnose ?
Re: How to pick a single signal from a wire and make it sticky?
Hope this works at least as well as the previous one.
The top right combinator can be removed and you can take output from the green wire from the bottom right combinator instead, if you don't mind -2.1G output temporarily.
Re: How to pick a single signal from a wire and make it sticky?
Posted: Sun Mar 17, 2024 10:18 am
by mmmPI
Qon wrote: ↑Sun Mar 17, 2024 10:03 am
Hope this works at least as well as the previous one.
The top right combinator can be removed and you can take output from the green wire from the bottom right combinator instead, if you don't mind -2.1G output temporarily.
The previous one worked better, this one you need to disable the green signal after the initial pasting otherwise it initialize in a flickering state between green circuit and nothing. I haven't seen the -2.1G output thought, even temporarily, it's either nothing or the correct one. I had no magic lamp. And made sure to paste the blueprint in editor all in a electricity coverage. It does work though after that initial manipulation.
Re: How to pick a single signal from a wire and make it sticky?
Posted: Sun Mar 17, 2024 10:52 am
by Qon
mmmPI wrote: ↑Sun Mar 17, 2024 10:18 am
The previous one worked better, this one you need to disable the green signal after the initial pasting otherwise it initialize in a flickering state between green circuit and nothing. [...] I had no magic lamp. And made sure to paste the blueprint in editor all in a electricity coverage. It does work though after that initial manipulation.
I have another similar one that I tried earlier with slightly different wiring. I tried changing things around but it didn't seem to have much on an effect. I think it has been tested somewhat to be correct, but do it yourself also to be safe
It has the same combinators as the previous one, but this doesn't flicker when pasted.
Qon wrote: ↑Sun Mar 17, 2024 10:03 am
The top right combinator can be removed and you can take output from the green wire from the bottom right combinator instead, if you don't mind -2.1G output temporarily.
I haven't seen the -2.1G output thought, even temporarily,
It's only if you remove the output combinator and use the green wire from the combinator before it instead. Just to be clear, did you do that?
Re: How to pick a single signal from a wire and make it sticky?
Posted: Sun Mar 17, 2024 11:27 am
by mmmPI
Qon wrote: ↑Sun Mar 17, 2024 11:02 am
It's only if you remove the output combinator and use the green wire from the combinator before it instead. Just to be clear, did you do that?
No i did not, i only hovered over the output power pole expecting to see a large negative number, but instead there was none, and the blueprint was flickering at start so i thought maybe i was looking at another version than the one you wanted to post instead of looking further.
Qon wrote: ↑Sun Mar 17, 2024 10:52 am
I tried changing things around but it didn't seem to have much on an effect
Changing stuff randomly is they key, if you change things really randomly it's almost guaranteed to have a devastating effect ! On the other hand it's unlikely for the first random change to be that wire i see different in the newest blueprint. Pretty cool ! I think not using inserters to implement the logic may be uncessary difficulty added to the challenge of coming with a very generic and compact solution for such problem, i will keep it in library
Re: How to pick a single signal from a wire and make it sticky?
mmmPI wrote: ↑Sun Mar 17, 2024 10:18 am
The previous one worked better, this one you need to disable the green signal after the initial pasting otherwise it initialize in a flickering state between green circuit and nothing. [...] I had no magic lamp. And made sure to paste the blueprint in editor all in a electricity coverage. It does work though after that initial manipulation.
I have another similar one that I tried earlier with slightly different wiring. I tried changing things around but it didn't seem to have much on an effect. I think it has been tested somewhat to be correct, but do it yourself also to be safe
It has the same combinators as the previous one, but this doesn't flicker when pasted.
And here I was just done rearanging those 8+1 combinators with the assembler, crafting combinator, chests and recipe feedback logic
crafting-assembler.png (267.53 KiB) Viewed 2471 times
and then you go and safe 2 more combinators. Now I have to rearange everything vertical and make it 9x4. Or maybe I should combine the free space from 2 blocks and place a beacon there.
Re: How to pick a single signal from a wire and make it sticky?
Posted: Sun Mar 17, 2024 4:15 pm
by Qon
mrvn wrote: ↑Sun Mar 17, 2024 2:06 pm
and then you go and safe 2 more combinators. Now I have to rearange everything vertical and make it 9x4. Or maybe I should combine the free space from 2 blocks and place a beacon there.
Slight visual rewire (same connections so behaves exactly the same):
I think your use case would work with the second one just as well, since the weird output is just temporary negative signals that your assembler won't choose anyways? But it saves a combinator