调整传感器设置以提供最佳读数的最有效方法是什么?
What is the most efficient way to tune the settings of a sensor, such that it gives optimal readings?
我有一个相当简单的传感器,它输出测量的距离,有许多可调参数决定传感器如何进行所述测量。
我的问题是,将设置调零以使传感器的读数与已知的校准距离对齐的最有效的编程方法是什么?每个设置都有一个已知的最小、最大和(最小)步长。
这是我的第一次尝试:
def setParameters(nl, nd, v1, v2, v3, ln, lto, sr, vo, a, do):
nLightBox.SetText(nl)
nDataBox.SetText(nd)
vtx1Box.SetText(v1)
vtx2Box.SetText(v2)
vtx3Box.SetText(v3)
ledNumBox.SetText(ln)
ltOffsetBox.SetText(lto)
srBox.SetText(sr)
vofsBox.SetText(vo)
aBox.SetText(a)
dofsBox.SetText(do)
setButton.Click()
closestMeasure = math.inf
closestSettings = {
'nLight': NLIGHT_DEFAULT,
'nData': NDATA_DEFAULT,
'vtx1': VTX1_DEFAULT,
'vtx2': VTX2_DEFAULT,
'vtx3': VTX3_DEFAULT,
'ledNum': LED_NUM_DEFAULT,
'ltOffset': LT_OFFSET_DEFAULT,
'sr': SR_DEFAULT,
'vofs': VOFS_DEFAULT,
'alpha': ALPHA_DEFAULT,
'dofs': DOFS_DEFAULT
}
try:
print("Adjusting parameters...")
for i in [1000, 100, 10, 1]:
for do in arange(DOFS_MIN, DOFS_MAX+0.01, DOFS_STEP*i):
for vo in range(VOFS_MIN, VOFS_MAX+1, VOFS_STEP*i):
for lto in range(LT_OFFSET_MIN, LT_OFFSET_MAX+1, LT_OFFSET_STEP*i):
for sr in arange(SR_MIN, SR_MAX+0.01, SR_STEP*i):
for a in arange(ALPHA_MIN, ALPHA_MAX+0.01, ALPHA_STEP*i):
for nl in range(NLIGHT_MIN, NLIGHT_MAX+1, NLIGHT_STEP*i):
for nd in range(NDATA_MIN, NDATA_MAX+1, NDATA_STEP*i):
for v1 in range(VTX1_MIN, VTX1_MAX+1, VTX1_STEP*i):
for v2 in range(VTX2_MIN, VTX2_MAX+1, VTX2_STEP*i):
for v3 in range(VTX3_MIN, VTX3_MAX+1, VTX3_STEP*i):
for ln in range(LED_NUM_MIN, LED_NUM_MAX+1, LED_NUM_STEP*i):
setParameters(nl, nd, v1, v2, v3, ln, lto, sr, vo, a, do)
time.sleep(0.1)
sumMeasure = 0.00
samples = 0
for i in range(1,3):
if len(avgDistanceBox.TextBlock()) != 0:
sumMeasure += float(avgDistanceBox.TextBlock().replace(',','').replace('∞','inf'))
samples += 1
time.sleep(0.05)
if samples > 0:
measured = (sumMeasure/samples)*0.001
if (abs(measured - distance)) < abs((closestMeasure - distance)):
closestMeasure = measured
print("Reading at {} meters, target is {} meters".format(closestMeasure, distance))
closestSettings = {
'nLight': nl,
'nData': nd,
'vtx1': v1,
'vtx2': v2,
'vtx3': v3,
'ledNum': ln,
'ltOffset': lto,
'sr': sr,
'vofs': vo,
'alpha': a,
'dofs': do
}
except:
print("Error during parameter adjustment: ", sys.exc_info()[0])
raise
print(closestMeasure)
print(closestSettings)
正如您可能看到的那样,这是解决此问题的一种极其低效的方法。任何建议将不胜感激!
编辑:添加了更多相关代码
编辑 2:这是距离的计算方式
其中Vout1和Vout2为传感器输出,C为光速,T0等于ledNum
以下是这些值,以及最小值、最大值和最小步长值
# Amount of sample frames to capture
NUMFRAMES_DEFAULT = 10
NUMFRAMES_MIN = 1
NUMFRAMES_MAX = 10000
NUMFRAMES_STEP = 1
# Number of times to emit light in a frame
NLIGHT_DEFAULT = 100
NLIGHT_MIN = 0
NLIGHT_MAX = 65535
NLIGHT_STEP = 1
# Number of times to read data in a frame
NDATA_DEFAULT = 100
NDATA_MIN = 5
NDATA_MAX = 250
NDATA_STEP = 1
# VTX1 Pulse Width (Should equal LED_NUM)
VTX1_DEFAULT = 40
VTX1_MIN = 20
VTX1_MAX = 5100
VTX1_STEP = 20
# VTX2 Pulse Width (Should equal LED_NUM)
VTX2_DEFAULT = 40
VTX2_MIN = 20
VTX2_MAX = 5100
VTX2_STEP = 20
# VTX3 High Period
VTX3_DEFAULT = 920
VTX3_MIN = 20
VTX3_MAX = 1310700
VTX3_STEP = 20
# LED Emission Pulse Width
LED_NUM_DEFAULT = 40
LED_NUM_MIN = 20
LED_NUM_MAX = 5100
LED_NUM_STEP = 20
# LED Emission Delay
LT_OFFSET_DEFAULT = 20
LT_OFFSET_MIN = 0
LT_OFFSET_MAX = 300
LT_OFFSET_STEP = 20
# Sensitivity Ratio
SR_DEFAULT = 1.00
SR_MIN = 0.00
SR_MAX = 2.00
SR_STEP = 0.01
# Voltage Offset
VOFS_DEFAULT = 0
VOFS_MIN = 0
VOFS_MAX = 1000
VOFS_STEP = 1
# Slope
ALPHA_DEFAULT = 1.00
ALPHA_MIN = 0.00
ALPHA_MAX = 5.00
ALPHA_STEP = 0.01
# Distancce Offset
DOFS_DEFAULT = 0.00
DOFS_MIN = -100.00
DOFS_MAX = 100.00
DOFS_STEP = 0.01
# End definition
我最终解决这个问题的方法(使用这个特定的传感器)非常简单。
传感器数据可以想象为对应于每个实际距离Y的任意值X,因此可以表示为图表。然后可以将 Dofs 设置视为测量点的 Y 偏移,将(最佳)Alpha 设置视为通过可能点的最佳拟合线的斜率。关于这个初始传感器校准,其他设置不需要修改。
为了正确校准传感器,选择三个(递减的)距离并遵循以下步骤:
将目标放在第一个距离处,先保存 X,在 X=Y 处找到自由度
将目标移动到第二和第三距离,保存X值
将A->B和B->C的ΔX取平均值计算ΔX,对ΔY做同样的事情
将 Alpha 设置为 ΔY/ΔX
相关代码:
# Shift the y-offset (Dofs) up or down until the sensor reading equals the actual first distance (x=y)
input("Ensure target ({}) is at the first distance ({}m), then press [Enter] to continue...".format(target, distance1))
print("Measuring sensor reading...")
firstX = takeMeasurement()
optimalDofs = math.inf
print("Adjusting distance offset...")
while True:
reading = takeMeasurement()
print("Reading: {:.3f}m, Dofs: {}m, Target: {}m".format(reading, getOutput(settings['dofs'][0]), distance1))
if (reading > distance1-margin) and (reading < distance1+margin):
optimalDofs = getOutput(settings['dofs'][0])
print("Optimal Distance Offset: {}m, Initial Sensor Reading: {}m".format(optimalDofs, firstX))
break
diff = abs(reading - distance1)
jump = getJump(diff)
if reading < distance1+margin:
adjustDown(settings['dofs'][0], jump)
elif reading > distance1-margin:
adjustUp(settings['dofs'][0], jump)
# Reset dofs to default
print("Resetting distance offset...")
adjust(settings['dofs'][0], DOFS_DEFAULT)
# Finds the sensor reading (x) at the second distance
input("Move target ({}) to the second distance ({}m), then press [Enter] to continue...".format(target, distance2))
print("Measuring sensor reading...")
secondX = takeMeasurement()
print("Sensor Reading: {}m".format(secondX))
# Finds the sensor reading (x) at the third distance
input("Move target ({}) to the third distance ({}m), then press [Enter] to continue...".format(target, distance3))
print("Measuring sensor reading...")
thirdX = takeMeasurement()
print("Sensor Reading: {}m".format(thirdX))
# Calculate the optimal alpha value by averaging delta X and delta Y
# Set dofs back to the optimal setting
print("Calculating optimal alpha...")
deltaX = (abs(firstX-secondX)+abs(secondX-thirdX))/2
print("Delta X: {}m".format(deltaX))
deltaY = (abs(distance1-distance2)+abs(distance2-distance3))/2
print("Delta Y: {}m".format(deltaY))
newAlpha = np.around(deltaY/deltaX, decimals=2)
print("Calculated optimal alpha: {:.2f}".format(newAlpha))
print("Setting alpha...")
adjust(settings['alpha'][0], newAlpha)
print("Readjusting distance offset...")
adjust(settings['dofs'][0], optimalDofs)
print("Optimal Alpha: {}, Optimal Distance Offset: {}".format(newAlpha, optimalDofs))
我有一个相当简单的传感器,它输出测量的距离,有许多可调参数决定传感器如何进行所述测量。
我的问题是,将设置调零以使传感器的读数与已知的校准距离对齐的最有效的编程方法是什么?每个设置都有一个已知的最小、最大和(最小)步长。
这是我的第一次尝试:
def setParameters(nl, nd, v1, v2, v3, ln, lto, sr, vo, a, do):
nLightBox.SetText(nl)
nDataBox.SetText(nd)
vtx1Box.SetText(v1)
vtx2Box.SetText(v2)
vtx3Box.SetText(v3)
ledNumBox.SetText(ln)
ltOffsetBox.SetText(lto)
srBox.SetText(sr)
vofsBox.SetText(vo)
aBox.SetText(a)
dofsBox.SetText(do)
setButton.Click()
closestMeasure = math.inf
closestSettings = {
'nLight': NLIGHT_DEFAULT,
'nData': NDATA_DEFAULT,
'vtx1': VTX1_DEFAULT,
'vtx2': VTX2_DEFAULT,
'vtx3': VTX3_DEFAULT,
'ledNum': LED_NUM_DEFAULT,
'ltOffset': LT_OFFSET_DEFAULT,
'sr': SR_DEFAULT,
'vofs': VOFS_DEFAULT,
'alpha': ALPHA_DEFAULT,
'dofs': DOFS_DEFAULT
}
try:
print("Adjusting parameters...")
for i in [1000, 100, 10, 1]:
for do in arange(DOFS_MIN, DOFS_MAX+0.01, DOFS_STEP*i):
for vo in range(VOFS_MIN, VOFS_MAX+1, VOFS_STEP*i):
for lto in range(LT_OFFSET_MIN, LT_OFFSET_MAX+1, LT_OFFSET_STEP*i):
for sr in arange(SR_MIN, SR_MAX+0.01, SR_STEP*i):
for a in arange(ALPHA_MIN, ALPHA_MAX+0.01, ALPHA_STEP*i):
for nl in range(NLIGHT_MIN, NLIGHT_MAX+1, NLIGHT_STEP*i):
for nd in range(NDATA_MIN, NDATA_MAX+1, NDATA_STEP*i):
for v1 in range(VTX1_MIN, VTX1_MAX+1, VTX1_STEP*i):
for v2 in range(VTX2_MIN, VTX2_MAX+1, VTX2_STEP*i):
for v3 in range(VTX3_MIN, VTX3_MAX+1, VTX3_STEP*i):
for ln in range(LED_NUM_MIN, LED_NUM_MAX+1, LED_NUM_STEP*i):
setParameters(nl, nd, v1, v2, v3, ln, lto, sr, vo, a, do)
time.sleep(0.1)
sumMeasure = 0.00
samples = 0
for i in range(1,3):
if len(avgDistanceBox.TextBlock()) != 0:
sumMeasure += float(avgDistanceBox.TextBlock().replace(',','').replace('∞','inf'))
samples += 1
time.sleep(0.05)
if samples > 0:
measured = (sumMeasure/samples)*0.001
if (abs(measured - distance)) < abs((closestMeasure - distance)):
closestMeasure = measured
print("Reading at {} meters, target is {} meters".format(closestMeasure, distance))
closestSettings = {
'nLight': nl,
'nData': nd,
'vtx1': v1,
'vtx2': v2,
'vtx3': v3,
'ledNum': ln,
'ltOffset': lto,
'sr': sr,
'vofs': vo,
'alpha': a,
'dofs': do
}
except:
print("Error during parameter adjustment: ", sys.exc_info()[0])
raise
print(closestMeasure)
print(closestSettings)
正如您可能看到的那样,这是解决此问题的一种极其低效的方法。任何建议将不胜感激!
编辑:添加了更多相关代码
编辑 2:这是距离的计算方式
其中Vout1和Vout2为传感器输出,C为光速,T0等于ledNum
以下是这些值,以及最小值、最大值和最小步长值
# Amount of sample frames to capture
NUMFRAMES_DEFAULT = 10
NUMFRAMES_MIN = 1
NUMFRAMES_MAX = 10000
NUMFRAMES_STEP = 1
# Number of times to emit light in a frame
NLIGHT_DEFAULT = 100
NLIGHT_MIN = 0
NLIGHT_MAX = 65535
NLIGHT_STEP = 1
# Number of times to read data in a frame
NDATA_DEFAULT = 100
NDATA_MIN = 5
NDATA_MAX = 250
NDATA_STEP = 1
# VTX1 Pulse Width (Should equal LED_NUM)
VTX1_DEFAULT = 40
VTX1_MIN = 20
VTX1_MAX = 5100
VTX1_STEP = 20
# VTX2 Pulse Width (Should equal LED_NUM)
VTX2_DEFAULT = 40
VTX2_MIN = 20
VTX2_MAX = 5100
VTX2_STEP = 20
# VTX3 High Period
VTX3_DEFAULT = 920
VTX3_MIN = 20
VTX3_MAX = 1310700
VTX3_STEP = 20
# LED Emission Pulse Width
LED_NUM_DEFAULT = 40
LED_NUM_MIN = 20
LED_NUM_MAX = 5100
LED_NUM_STEP = 20
# LED Emission Delay
LT_OFFSET_DEFAULT = 20
LT_OFFSET_MIN = 0
LT_OFFSET_MAX = 300
LT_OFFSET_STEP = 20
# Sensitivity Ratio
SR_DEFAULT = 1.00
SR_MIN = 0.00
SR_MAX = 2.00
SR_STEP = 0.01
# Voltage Offset
VOFS_DEFAULT = 0
VOFS_MIN = 0
VOFS_MAX = 1000
VOFS_STEP = 1
# Slope
ALPHA_DEFAULT = 1.00
ALPHA_MIN = 0.00
ALPHA_MAX = 5.00
ALPHA_STEP = 0.01
# Distancce Offset
DOFS_DEFAULT = 0.00
DOFS_MIN = -100.00
DOFS_MAX = 100.00
DOFS_STEP = 0.01
# End definition
我最终解决这个问题的方法(使用这个特定的传感器)非常简单。
传感器数据可以想象为对应于每个实际距离Y的任意值X,因此可以表示为图表。然后可以将 Dofs 设置视为测量点的 Y 偏移,将(最佳)Alpha 设置视为通过可能点的最佳拟合线的斜率。关于这个初始传感器校准,其他设置不需要修改。
为了正确校准传感器,选择三个(递减的)距离并遵循以下步骤:
将目标放在第一个距离处,先保存 X,在 X=Y 处找到自由度
将目标移动到第二和第三距离,保存X值
将A->B和B->C的ΔX取平均值计算ΔX,对ΔY做同样的事情
将 Alpha 设置为 ΔY/ΔX
相关代码:
# Shift the y-offset (Dofs) up or down until the sensor reading equals the actual first distance (x=y)
input("Ensure target ({}) is at the first distance ({}m), then press [Enter] to continue...".format(target, distance1))
print("Measuring sensor reading...")
firstX = takeMeasurement()
optimalDofs = math.inf
print("Adjusting distance offset...")
while True:
reading = takeMeasurement()
print("Reading: {:.3f}m, Dofs: {}m, Target: {}m".format(reading, getOutput(settings['dofs'][0]), distance1))
if (reading > distance1-margin) and (reading < distance1+margin):
optimalDofs = getOutput(settings['dofs'][0])
print("Optimal Distance Offset: {}m, Initial Sensor Reading: {}m".format(optimalDofs, firstX))
break
diff = abs(reading - distance1)
jump = getJump(diff)
if reading < distance1+margin:
adjustDown(settings['dofs'][0], jump)
elif reading > distance1-margin:
adjustUp(settings['dofs'][0], jump)
# Reset dofs to default
print("Resetting distance offset...")
adjust(settings['dofs'][0], DOFS_DEFAULT)
# Finds the sensor reading (x) at the second distance
input("Move target ({}) to the second distance ({}m), then press [Enter] to continue...".format(target, distance2))
print("Measuring sensor reading...")
secondX = takeMeasurement()
print("Sensor Reading: {}m".format(secondX))
# Finds the sensor reading (x) at the third distance
input("Move target ({}) to the third distance ({}m), then press [Enter] to continue...".format(target, distance3))
print("Measuring sensor reading...")
thirdX = takeMeasurement()
print("Sensor Reading: {}m".format(thirdX))
# Calculate the optimal alpha value by averaging delta X and delta Y
# Set dofs back to the optimal setting
print("Calculating optimal alpha...")
deltaX = (abs(firstX-secondX)+abs(secondX-thirdX))/2
print("Delta X: {}m".format(deltaX))
deltaY = (abs(distance1-distance2)+abs(distance2-distance3))/2
print("Delta Y: {}m".format(deltaY))
newAlpha = np.around(deltaY/deltaX, decimals=2)
print("Calculated optimal alpha: {:.2f}".format(newAlpha))
print("Setting alpha...")
adjust(settings['alpha'][0], newAlpha)
print("Readjusting distance offset...")
adjust(settings['dofs'][0], optimalDofs)
print("Optimal Alpha: {}, Optimal Distance Offset: {}".format(newAlpha, optimalDofs))