forked from nilsso/mips-myps
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
181 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
# Precision single-gas driven furnace controller | ||
# (nilsso) | ||
# | ||
# NOTE: To start operation, write a "value" greater than zero to the housing. This value is taken to | ||
# be a code for the target temperature and pressure with the format `PPPTTT`, where tT=TTT*10$ and | ||
# pT=PPP*100. | ||
# | ||
# e.g. 500050 -> tT = 050*10 = 500 K, pT = 500*100 = 50,000 kPa = 50 MPa | ||
# | ||
# IMPORTANT: Validation for this input is not done here, and the program will attempt to use | ||
# whatever it is given. If the target temperature is less-than the cold source temperature or | ||
# greater than the hot source temperature then wackiness will certainly occurr! | ||
# (I may change this point in the future) | ||
# | ||
# Things to consdier: | ||
# - If tF~=tT, tF~=tC or tF~=tH then algorithm is undefined | ||
# | ||
# For construction: | ||
# - The furnace, input pipe analyzer, waste digital valve and waste filtration | ||
# should be data isolated. | ||
furnace = d0 | ||
tankC = d1 | ||
tankH = d2 | ||
pumpC = d3 | ||
pumpH = d4 | ||
progressDest = d5 | ||
|
||
# Device hashes | ||
def AdvancedFurnace = 545937711 | ||
def PipeAnalyzer = 435685051 | ||
def DigitalValve = -1280984102 | ||
def Filtration = -348054045 | ||
|
||
# Constants | ||
def vF = 1000 # Furnace volume | ||
def R = 8.31446261815324 # Universal gas consant | ||
|
||
# Source volume-mole factor | ||
# (NOTE: ADJUST PER SETUP) | ||
# e.g. 6200 = 1 furnace (6000) + 2 pipes (200) L | ||
# (TODO: Need to implement defines calculated from other defines) | ||
def vC = 50100 | ||
def vH = 50100 | ||
def fC = (50100) / 50000 | ||
def fH = (50100) / 50000 | ||
|
||
# "P" term coefficients | ||
# (NOTE: Tweaking could increase result speed) | ||
def KPF = 0.3 # Furnace volume proportional term | ||
def KPC = 0.3 # Cold source proportional term | ||
def KPH = 0.5 # Hot source proportional term | ||
|
||
# Error bounds | ||
def ERRORT = 0.5 # Maximum temperature error | ||
def ERRORP = 0.5 # Maximum pressure error | ||
|
||
def ERRORF = 5 | ||
def ERRORC = 5 | ||
def ERRORH = 5 | ||
|
||
# Pump maximum bounds | ||
def rFmax = 1000 # Furnace output | ||
def rCmax = 1000 # Cold source pump | ||
def rHmax = 1000 # Hot source pump | ||
|
||
# Initialization | ||
db.Setting = -1 | ||
pumpC.On = 1 | ||
pumpC.Setting = 0 | ||
pumpH.On = 1 | ||
pumpH.Setting = 0 | ||
AdvancedFurnace.all.SettingInput = 0 | ||
AdvancedFurnace.all.SettingOutput = 0 | ||
Filtration.all.On = 0 | ||
DigitalValve.all.On = 0 | ||
|
||
loop: | ||
input = db.Setting # possibly trunc this | ||
tT = (input % 1000) * 10 | ||
pT = trunc(input / 1000) * 100 # pT | ||
pF = AdvancedFurnace.all.Pressure.Sum | ||
tF = AdvancedFurnace.all.Temperature.Sum | ||
|
||
ratioCO2 = AdvancedFurnace.all.RatioCarbonDioxide.Sum | ||
# TODO: Calculate error from having a ratio under some fixed value | ||
if (ratioCO2 > 0.9) and (input > 0) and ((abs(tT - tF) > ERRORT) or (abs(pT - pF) > ERRORP)): | ||
# Calculate moles removed bounds | ||
tH = tankH.Temperature # tH | ||
nRC = (tT - tH) / (tH - tF) | ||
tC = tankC.Temperature # tC | ||
nRH = (tC - tT) / (tF - tC) | ||
|
||
# Calculate moles to remove | ||
nT = (pT * vF) / (R * tT) # nT | ||
fix nF = AdvancedFurnace.all.TotalMoles.Sum | ||
fix nR = max(0, nT * max(nRC, nRH) + nF) # nR | ||
|
||
# Calculate C and H input moles | ||
nI = nT - nF + nR # nI | ||
tI = (tT * nT - tF * (nF - nR)) / nI # tI | ||
fix nCI = nI * (tI - tH) / (tC - tH) # nCI | ||
fix nHI = nI - nCI # nHI | ||
|
||
AdvancedFurnace.all.SettingInput = 1000 | ||
fix nC = fC * tankC.TotalMoles | ||
fix nH = fH * tankH.TotalMoles | ||
tag AddRemoveLoop: | ||
rF = KPF*(nR * vF / nF) | ||
rF = max(0, min(rFmax, rF)) | ||
AdvancedFurnace.all.SettingOutput = rF | ||
|
||
rC = KPC*(nCI * vC / nC) # rC | ||
rC = max(0, min(rCmax, rC)) | ||
pumpC.Setting = rC # set rC | ||
|
||
rH = KPH*(nHI * vH / nH) # rH | ||
rH = max(0, min(rHmax, rH)) | ||
pumpH.Setting = rH # set rH | ||
|
||
yield() | ||
nFp = nF | ||
nF = AdvancedFurnace.all.TotalMoles.Sum | ||
nR -= nFp - nF | ||
|
||
nCp = nC | ||
nC = fC * tankC.TotalMoles | ||
nCI -= nCp - nC | ||
|
||
nHp = nH | ||
nH = fH * tankH.TotalMoles | ||
nHI -= nHp - nH | ||
|
||
bgt(nR, ERRORF, AddRemoveLoop) | ||
bgt(nCI, ERRORC, AddRemoveLoop) | ||
bgt(nHI, ERRORH, AddRemoveLoop) | ||
|
||
AdvancedFurnace.all.SettingOutput = 0 | ||
AdvancedFurnace.all.SettingInput = 1000 | ||
pumpC.Setting = 0 | ||
pumpH.Setting = 0 | ||
#yield() | ||
while PipeAnalyzer.all.TotalMoles.Sum > 0: | ||
yield() | ||
|
||
elif ratioCO2 < 1.0: | ||
# Furnace gas filtration | ||
#pumpC.Setting = 0 | ||
#pumpH.Setting = 0 | ||
AdvancedFurnace.all.SettingInput = 0 | ||
Filtration.all.On = 1 | ||
DigitalValve.all.On = 1 | ||
yield() | ||
|
||
AdvancedFurnace.all.SettingOutput = 1000 | ||
while AdvancedFurnace.all.TotalMoles.Sum > 0: | ||
yield() | ||
|
||
AdvancedFurnace.all.SettingInput = 1000 | ||
AdvancedFurnace.all.SettingOutput = 0 | ||
while PipeAnalyzer.all.TotalMoles.Sum > 0: | ||
yield() | ||
|
||
AdvancedFurnace.all.SettingInput = 0 | ||
Filtration.all.On = 0 | ||
DigitalValve.all.On = 0 | ||
#else: | ||
# pumpC.Setting = 0 | ||
# pumpH.Setting = 0 | ||
# AdvancedFurnace.all.SettingOutput = 0 | ||
# AdvancedFurnace.all.SettingInput = 1000 | ||
# yield() | ||
|