Thorium-Sim / thorium

Platform for starship simulator controls
https://thoriumsim.com
Apache License 2.0
157 stars 69 forks source link

Software Panels Improvements #778

Open alexanderson1993 opened 6 years ago

alexanderson1993 commented 6 years ago

Detailed Description

Software Panels are cool, but are not true electronics simulators. It would be cool if they were.

0<x<1

AND
0*0=0
0*1=0
1*0=0
1*1=1
X*0=0
X*1=X
0*X=0
1*X=X
X*X=X

OR
0+0=0
0+1=1
1+0=1
1+1=1
X+0=X
X+1=1
0+X=X
1+X=1
X+X=X

NOT
0' = 1
1' = 0
X' = X
A|B||X
-|-||-
0|0||0
0|1||1
1|0||1
1|1||0
Emrix commented 6 years ago

This is an excerpt of a conversation I had with @alexanderson1993, and it explains the function and reasoning of these panels fairly well.

Ok, so I’ll be implementing this in the software panels soon, but this is basically how it goes: firstly, I'll be using the following vocabulary: Circuit = Logical Expression, TSP = Thorium Software Panels, wire/net = connection.... if I have more, I will add them(edited) So, when you implement a circuit in TSP, how you have it currently set up is mostly correct. It starts at the end of the circuit, and builds out towards the front. Then, when the front input is changed, then it follows the trail to the back output. However, this only works for Linear Circuits. ie: Circuits that have no loops in them. If a circuit has a loop, then it will require a little extra effort in order to get it to work properly. Firstly, you need to add values to the wires. These nets are essential that they have values, or else loops can't work. Especially for single loop logic gates. Secondly, when a circuit is initialized or instantiated, it sets all values (every single one of them) to x. Not 1 Not 0 But X. This means that the wire or gate doesn't have an assigned value yet. So how does it get this value? Through the inputs! (Obviously) So, when an input is set, then it will set the wire that it's connected to with the value, and then continue on down the path of circuitry, until it gets to the output.

This, however, is not done through a for loop or repeat, or something else like that. When it calculates the values on the nets and objects, it actually needs to schedule them. This scheduler (in C) is a linked list. Each node in the linked list contains the ID of the gate which needs to be calculated next. So when a value on a net changes, it adds the very next gate (or gates) that it's connected to to the end of the linked list. But, it first checks to make sure that there are no duplicate gates in the schedule. So, the scheduler takes the next thing on the linked list, evaluates it, and, if necessary, schedules the downstream gates. When a circuit is stable, then there will be no items in the linked list, and the circuit will be fully evaluated. However, like I said, what if it has a loop in it? ie, what if a nor gate looped back to itself? screen_shot_2018-05-11_at_12 34 11_pm

What happens? Well, in the real worlds, it starts out with a value, say 0. Well, then 0 gets fed into itself, so it changes to 1. But wait, now that it's 1, it goes back to 0. But we were just at zero, so we change 0 back into 1. And hey! we are at one again! So now we change it to zero. So this just keeps going..... However, in the logic simulation, all values are initialized to X first. So what happens here? Well, let me draw out a few truth tables for you... (See above "detailed description")

Yeah! So like I said, all values are initialized to X, so the looped not gate would just be X. "Well, what if it had a 1 on it?" Well, it can't because it can't initialize to another value. HOWEVER, the issue you are looking at is this one: screen_shot_2018-05-11_at_12 44 18_pm

So, as we can see, this is a NOR gate.

A|B||Output
-|-||-
0|0||0
0|1||1
1|0||1
1|1||0

That's the truth table for it. So, basically with this set up, the circuit is stable if and only if the input is hi. if the input is lo, then the circuit is unstable, and it flips out like our not gate. However, let us introduce the X!

A|B||Output
-|-||-
0|0||0
0|1||1
1|0||1
1|1||0
X|0||X
X|1||1
1|X||1
0|X||X
X|X||X

So when the gate is first initialized, then it initializes to X. "Ok," you say, "But if I bring the one input High, and then Low again, it is again unstable." True. So, in cases like that, then what you have to do is implement an escape clause. If a certain gate flips back and forth in a row 5 times or more, then you assign it's value to X

So, you'd have to implement a way for a circuit to be deemed as "unstable", or that it's in a non-stable state. I would probably do something where if it flips back and forth more than 20 times in one second, then it's likely unstable, and should be assigned a value of X.

Yeah. React limits to 50 stacks, or 50 loops within loops It throws an error once you get to that point, which would be caught with try That's how the current system blocks infinite loops if it hits a 'catch', it just sets the value to 0 In my system, it would set it to x

Though, because of typing, it would probably set it to -1 instead.

An ADC or Analog Digital Converter is needed also That's technically how my panels operate, so it might be nice to implement that in the software panels as well. But wholly not necessary. I can simply add in Division or Multiplication Gates instead.

The point of ADC is to get a floating point number (3.14) into binary (0011.01001) So that computer systems can process that information. Because like I said, the PI doesn't actually have any Analog inputs like the Arduino Does (Arduinos have the ADC built in), so you have to stick an ADC onto the GPIO of the pi for it to work.

And then there's the reverse, DAC (Digital to Analog Converter) which does just the opposite

So while the software panels can handle floating point numbers between components, the hardware panels cannot. But I don't want to restrict the software panels to just digital, because that would be stupid. But if HW and SW want to be linked, then you have to default to all digital.

But like I said, with multiplication and division gates (along with the floor and ceiling gates) then I can implement one manually without an issue. using binary to decimal conversion principles.

In order to connect an analog device to a digital system, you must put it through an ADC. This converts the analog system into bits which can be processed. The hardware panels do not care what the analog device is, as long as it receives binary from the ADC output. Therefore, when the analog devices are used in the software panels, then they must be converted to digital in order to be processed correctly. However, the hardware panels will not be able to detect where the digital input is, because an ADC gate will not be implemented in the software panels. Instead, I will need to create a special buffer which will "convert" between an "Analog" 1 and a "Digital" 1, so that the hardware panels know where to pick up the digital inputs.

Gates which should be included: Logic: NOT, AND, OR, NOR, NAND, XOR, XNOR Analog: Multiplication, Division, Addition, Subtraction, Modulus, Ceiling, Floor, Round Additional: ADC, Buffer

Inputs which should be included: Logic: Clock, IO Analog: Oscillator, Random Number Generator Additional: Thorium Vars

Outputs which should be included: Digital: LED, Buzzer Analog: RGB LED, Plasma Channel, Meters, Additional: DAC, Words (through LCD Screens)