You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派Pico油门踏板:零点两侧绝对值转0-100%线性值方案

树莓派Pico油门踏板模拟器传感器数据转换问题优化

问题描述

  • 模拟传感器返回值为65535→0→65535的绝对值形式,而非预期的-65535→0→65535,常规范围映射函数因首尾取值相同无法生效
  • 尝试通过死区(值≤20)标记及踏板运动方向跟踪,将数据转换为0-100%线性值,再映射至-127至127范围用于模拟游戏手柄扳机,但在方向与死区标记的逻辑处理上存在困惑

当前代码

def getScaledAcceleratorPosition():
    # Establish a few basic values we need to evaluate
    acceleratorValue = analog_activePins[0].value
    posDifference = (last_AcceleratorVal - acceleratorValue)
    
    if (digital_activePins[9].value == False) and (digital_activePins[10].value == False): #If neither butterfly switch is enabled, then return 127 for the position of the accelerator
        global last_AcceleratorVal = 65535
        global sawAccelDeadBand = False     # Reset memory on seeing the deadband in the middle of accelerator pedal travel
        global pedalMovingDown = False
        global pedalMovingUp = True
        return -127 # Send fully retracted position for analog Right Trigger
    elif (digital_activePins[9].value == True or digital_activePins[10].value == True):
        # Take care of a condition where the accelerator pedal rests at Maximum value
        if acceleratorValue > 65520 and acceleratorValue <= 65535:
            global last_AcceleratorVal = 65535
            global sawAccelDeadBand = False     # Reset memory on seeing the deadband in the middle of accelerator pedal travel
            global pedalMovingDown = False
            global pedalMovingUp = True
            return -127
            
        # Create small dead zones at the ends of travel
        if acceleratorValue >= 65520: acceleratorValue = 65530
        if acceleratorValue <= 500: acceleratorValue = 0
        if acceleratorValue > 0 and acceleratorValue <= 20: sawAccelDeadBand = True     # Set a flag when we pass the accelerator deadband in the middle of travel.
        
        # Compensate for the analog feedback device value map that looks like 65535->0->65535, rather than -65535->0->65535
        if (posDifference > 0 and sawAccelDeadBand == False) or (posDifference < 0 and sawAccelDeadBand == True):
            global pedalMovingDown = True
            global pedalMovingUp = False
            print("Accel Pedal Moving Down. Value: %s"%acceleratorValue)
        elif (posDifference > 0 and sawAccelDeadBand == True) or (posDifference < 0 and sawAccelDeadBand == False):
            global pedalMovingDown = False
            global pedalMovingUp = True
            print("Accel Pedal Moving Up.   Value: %s"%acceleratorValue)
        
        # Values if Pedal is moving Down:
        if pedalMovingDown == True and sawAccelDeadBand == True:
            retVal = range_map(acceleratorValue, 0, 65535, 0, 127)
            # sawDeadBandAndPedalMovingDown = True  # Need some memory for when I pass by the dead band and the pedal is moving down?
        elif pedalMovingDown == True and sawAccelDeadBand == False:
            retVal = range_map(acceleratorValue, 65535, 0, -127, 0)
        # Values if Pedal is moving Up:
        if pedalMovingUp == True and sawAccelDeadBand == True:
            retVal = range_map(acceleratorValue, 65535, 0, 0, 127)
            # sawDeadBandAndPedalMovingUp = True  # Need some memory for when I pass by the dead band and the pedal is moving up?
        elif pedalMovingUp == True and sawAccelDeadBand == False:
            retVal = range_map(acceleratorValue, 0, 65535, -127, 0)
        
        global last_AcceleratorVal = acceleratorValue
        return round(retVal)
    else:
        print("Something wrong in getScaledAcceleratorPosition Routine")
        return 0

优化建议

1. 全局变量管理优化

  • 把全局变量移到函数外部初始化,避免在分支内重复赋值,同时用类或闭包封装状态,减少global关键字的滥用,提升代码可维护性:
    # 全局状态初始化
    last_AcceleratorVal = 65535
    sawAccelDeadBand = False
    pedalMovingDown = False
    pedalMovingUp = True
    

2. 死区与方向判断逻辑简化

  • 补充死区离开的判断逻辑,避免仅触发进入死区的标记;同时简化方向判断条件,直接通过差值正负结合死区状态推导运动方向:
    # 死区状态更新
    if 0 < acceleratorValue <= 20:
        sawAccelDeadBand = True
    elif acceleratorValue > 20 and sawAccelDeadBand:
        # 仅当离开死区时保留状态,避免误重置
        pass
    
    # 简化方向判断
    if posDifference != 0:
        moving_trend_down = posDifference > 0
        if sawAccelDeadBand:
            pedalMovingDown = moving_trend_down
            pedalMovingUp = not moving_trend_down
        else:
            pedalMovingDown = not moving_trend_down
            pedalMovingUp = moving_trend_down
    

3. 范围映射逻辑合并

  • 取消多分支的range_map调用,根据死区和方向状态直接计算目标值,减少冗余:
    # 直接计算映射值,替代range_map
    if sawAccelDeadBand:
        # 过死区后:0→65535对应0→127(踩下),65535→0对应127→0(抬起)
        if pedalMovingDown:
            retVal = (acceleratorValue / 65535) * 127
        else:
            retVal = (1 - acceleratorValue / 65535) * 127
    else:
        # 未过死区:65535→0对应-127→0(踩下),0→65535对应0→-127(抬起)
        if pedalMovingDown:
            retVal = -127 + (acceleratorValue / 65535) * 127
        else:
            retVal = (acceleratorValue / 65535) * (-127)
    

4. 边界值处理优化

  • 统一边界修正逻辑,避免原代码中>=65520设为65530的不一致问题:
    # 两端死区修正
    if acceleratorValue >= 65520:
        acceleratorValue = 65535
    elif acceleratorValue <= 500:
        acceleratorValue = 0
    

5. 代码结构优化

  • 将开关判断、边界处理、方向判断、映射计算拆分为独立代码块,提升可读性;增加默认返回值,避免分支遗漏导致的未定义变量问题。

内容的提问来源于stack exchange,提问作者Brennan Thomason

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 08:02:02