我有一个相当简单的传感器,它输出一个测量距离,有许多可调参数,决定了传感器如何进行测量.
我的问题是,用于将设置归零的编程效率最高的方法是什么,以便传感器的读数与已知的校准距离一致?每个设置都具有已知的最小,最大和(最小)步长.
这是我的第一次尝试:
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的Dofs
将目标移动到第二和第三距离,保存X值
通过平均A-> B的ΔX和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))