python – 调整传感器设置的最有效方法是什么,以便提供最佳读数?

我有一个相当简单的传感器,它输出一个测量距离,有许多可调参数,决定了传感器如何进行测量.

我的问题是,用于将设置归零的编程效率最高的方法是什么,以便传感器的读数与已知的校准距离一致?每个设置都具有已知的最小,最大和(最小)步长.

这是我的第一次尝试:

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))
上一篇:android – 通过Bluemix将TI SensorTag连接到IBM IoT Foundation时无效的userID()


下一篇:python – 实时绘图中的多个数据系列