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]
|
||||
N = int(settings.numTemps)
|
||||
|
||||
# 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.
|
||||
samples = optimizeTempTable(thrm, N, hiadc)
|
||||
|
||||
# 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) < 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()):
|
||||
for i in samples:
|
||||
t = int(thrm.temp(i))
|
||||
if t is None:
|
||||
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
|
||||
ptherm = vTherm * vTherm / r
|
||||
if i == max(lookup):
|
||||
if i == max(samples):
|
||||
c = " "
|
||||
else:
|
||||
c = ","
|
||||
|
|
@ -179,9 +142,10 @@ def SteinhartHartTable(ofp, params, names, settings, finalTable):
|
|||
|
||||
hiadc = thrm.setting(0)[0]
|
||||
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))
|
||||
if t is None:
|
||||
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))
|
||||
|
||||
if i + step >= int(hiadc):
|
||||
if i == max(samples):
|
||||
c = " "
|
||||
else:
|
||||
c = ","
|
||||
|
|
@ -201,6 +165,49 @@ def SteinhartHartTable(ofp, params, names, settings, finalTable):
|
|||
else:
|
||||
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):
|
||||
return min([x for x in lookup.keys() if x > value])
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue