Refactor temp table optimization for any algorithm
This should be squashed but is separated here for comparison.
This commit is contained in:
parent
b7a2d58b31
commit
090be579d1
|
|
@ -100,46 +100,9 @@ def BetaTable(ofp, params, names, settings, finalTable):
|
||||||
hiadc = thrm.setting(0)[0]
|
hiadc = thrm.setting(0)[0]
|
||||||
N = int(settings.numTemps)
|
N = int(settings.numTemps)
|
||||||
|
|
||||||
# This is a variation of the Ramer-Douglas-Peucker algorithm, see
|
samples = optimizeTempTable(thrm, N, hiadc)
|
||||||
# https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm
|
|
||||||
#
|
|
||||||
# It works like this:
|
|
||||||
#
|
|
||||||
# - Calculate all (1024) ideal values.
|
|
||||||
# - Keep only the ones in the interesting range (0..500C).
|
|
||||||
# - Insert the two extremes into our sample list.
|
|
||||||
# - Calculate the linear approximation of the remaining values.
|
|
||||||
# - Insert the correct value for the "most-wrong" estimation into our
|
|
||||||
# sample list.
|
|
||||||
# - Repeat until "N" values are chosen as requested.
|
|
||||||
|
|
||||||
# Calculate actual temps for all ADC values.
|
for i in samples:
|
||||||
actual = dict([(x, thrm.temp(1.0 * x)) for x in range(1, int(hiadc + 1))])
|
|
||||||
|
|
||||||
# Limit ADC range to 0C to 500C.
|
|
||||||
MIN_TEMP = 0
|
|
||||||
MAX_TEMP = 500
|
|
||||||
actual = dict([(adc, actual[adc]) for adc in actual
|
|
||||||
if actual[adc] <= MAX_TEMP and actual[adc] >= MIN_TEMP])
|
|
||||||
|
|
||||||
# Build a lookup table starting with the extremes.
|
|
||||||
A = min(actual)
|
|
||||||
B = max(actual)
|
|
||||||
lookup = dict([(x, actual[x]) for x in [A,B]])
|
|
||||||
error = dict({})
|
|
||||||
while len(lookup) < N:
|
|
||||||
error.update(dict([(x, abs(actual[x] - LinearTableEstimate(lookup, x)))
|
|
||||||
for x in range(A + 1, B)]))
|
|
||||||
|
|
||||||
# Correct the most-wrong lookup value.
|
|
||||||
next = max(error, key = error.get)
|
|
||||||
lookup[next] = actual[next]
|
|
||||||
|
|
||||||
# Prepare to update the error range.
|
|
||||||
A = before(lookup, next)
|
|
||||||
B = after(lookup, next)
|
|
||||||
|
|
||||||
for i in sorted(lookup.keys()):
|
|
||||||
t = int(thrm.temp(i))
|
t = int(thrm.temp(i))
|
||||||
if t is None:
|
if t is None:
|
||||||
ofp.output("// ERROR CALCULATING THERMISTOR VALUES AT ADC %d" % i)
|
ofp.output("// ERROR CALCULATING THERMISTOR VALUES AT ADC %d" % i)
|
||||||
|
|
@ -150,7 +113,7 @@ def BetaTable(ofp, params, names, settings, finalTable):
|
||||||
|
|
||||||
vTherm = i * vadc / 1024
|
vTherm = i * vadc / 1024
|
||||||
ptherm = vTherm * vTherm / r
|
ptherm = vTherm * vTherm / r
|
||||||
if i == max(lookup):
|
if i == max(samples):
|
||||||
c = " "
|
c = " "
|
||||||
else:
|
else:
|
||||||
c = ","
|
c = ","
|
||||||
|
|
@ -179,9 +142,10 @@ def SteinhartHartTable(ofp, params, names, settings, finalTable):
|
||||||
|
|
||||||
hiadc = thrm.setting(0)[0]
|
hiadc = thrm.setting(0)[0]
|
||||||
N = int(settings.numTemps)
|
N = int(settings.numTemps)
|
||||||
step = int(hiadc / (N - 1))
|
|
||||||
|
|
||||||
for i in range(1, int(hiadc), step):
|
samples = optimizeTempTable(thrm, N, hiadc)
|
||||||
|
|
||||||
|
for i in samples:
|
||||||
t = int(thrm.temp(i))
|
t = int(thrm.temp(i))
|
||||||
if t is None:
|
if t is None:
|
||||||
ofp.output("// ERROR CALCULATING THERMISTOR VALUES AT ADC %d" % i)
|
ofp.output("// ERROR CALCULATING THERMISTOR VALUES AT ADC %d" % i)
|
||||||
|
|
@ -189,7 +153,7 @@ def SteinhartHartTable(ofp, params, names, settings, finalTable):
|
||||||
|
|
||||||
r = int(thrm.adcInv(i))
|
r = int(thrm.adcInv(i))
|
||||||
|
|
||||||
if i + step >= int(hiadc):
|
if i == max(samples):
|
||||||
c = " "
|
c = " "
|
||||||
else:
|
else:
|
||||||
c = ","
|
c = ","
|
||||||
|
|
@ -201,6 +165,49 @@ def SteinhartHartTable(ofp, params, names, settings, finalTable):
|
||||||
else:
|
else:
|
||||||
ofp.output(" },")
|
ofp.output(" },")
|
||||||
|
|
||||||
|
def optimizeTempTable(thrm, length, hiadc):
|
||||||
|
|
||||||
|
# This is a variation of the Ramer-Douglas-Peucker algorithm, see
|
||||||
|
# https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm
|
||||||
|
#
|
||||||
|
# It works like this:
|
||||||
|
#
|
||||||
|
# - Calculate all (1024) ideal values.
|
||||||
|
# - Keep only the ones in the interesting range (0..500C).
|
||||||
|
# - Insert the two extremes into our sample list.
|
||||||
|
# - Calculate the linear approximation of the remaining values.
|
||||||
|
# - Insert the correct value for the "most-wrong" estimation into our
|
||||||
|
# sample list.
|
||||||
|
# - Repeat until "N" values are chosen as requested.
|
||||||
|
|
||||||
|
# Calculate actual temps for all ADC values.
|
||||||
|
actual = dict([(x, thrm.temp(1.0 * x)) for x in range(1, int(hiadc + 1))])
|
||||||
|
|
||||||
|
# Limit ADC range to 0C to 500C.
|
||||||
|
MIN_TEMP = 0
|
||||||
|
MAX_TEMP = 500
|
||||||
|
actual = dict([(adc, actual[adc]) for adc in actual
|
||||||
|
if actual[adc] <= MAX_TEMP and actual[adc] >= MIN_TEMP])
|
||||||
|
|
||||||
|
# Build a lookup table starting with the extremes.
|
||||||
|
A = min(actual)
|
||||||
|
B = max(actual)
|
||||||
|
lookup = dict([(x, actual[x]) for x in [A, B]])
|
||||||
|
error = dict({})
|
||||||
|
while len(lookup) < length:
|
||||||
|
error.update(dict([(x, abs(actual[x] - LinearTableEstimate(lookup, x)))
|
||||||
|
for x in range(A + 1, B)]))
|
||||||
|
|
||||||
|
# Correct the most-wrong lookup value.
|
||||||
|
next = max(error, key = error.get)
|
||||||
|
lookup[next] = actual[next]
|
||||||
|
|
||||||
|
# Prepare to update the error range.
|
||||||
|
A = before(lookup, next)
|
||||||
|
B = after(lookup, next)
|
||||||
|
|
||||||
|
return sorted(lookup)
|
||||||
|
|
||||||
def after(lookup, value):
|
def after(lookup, value):
|
||||||
return min([x for x in lookup.keys() if x > value])
|
return min([x for x in lookup.keys() if x > value])
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue