基于simplex算法的二维光纤对准光功率最优位置求解咨询
二维光轴对准寻优实现代码
前置说明
你提到的simplex光对准寻优是指Nelder-Mead可变单纯形算法,和scipy.optimize.linprog内置的线性规划单纯形不是同一实现,二维寻优直接使用scipy.optimize.minimize的Nelder-Mead方法即可,无需手动实现算法逻辑。
实现逻辑
分两步完成寻优,适配大范围搜索场景:
- 粗搜阶段:按预设步长网格化遍历搜索范围,检测到光功率高于阈值立即停止粗搜,进入精搜阶段
- 精搜阶段:调用Nelder-Mead单纯形算法在有效点附近寻优,自动收敛到最大功率点
完整代码
import time import numpy as np from scipy.optimize import minimize from labFunctions import PowerMeter, MotorAxis # 初始化硬件 pm = PowerMeter('pm_address') yaxis = MotorAxis('y_address') zaxis = MotorAxis('z_address') # -------------------------- 可调参数 -------------------------- limits = [ystart, zstart, yend, zend] # 搜索范围:[y最小值, z最小值, y最大值, z最大值] coarse_step = 0.1 # 粗搜步长,建议设为光斑直径的70%~80%,单位和电机位置单位一致 power_threshold = 1e-6 # 粗搜功率阈值,建议设为噪声功率的3~5倍,单位和功率计输出一致 motor_wait = 0.1 # 电机到位后等待时间,单位秒,根据电机实际速度调整 conv_tol = 1e-8 # 精搜收敛阈值,功率变化小于该值时停止寻优 # ------------------------------------------------------------- # 目标函数:输入[y,z]位置,返回负光功率(因为minimize找最小值,负功率最小对应原功率最大) def objective(pos): y, z = pos # 边界限制,避免电机超出行程 y = np.clip(y, limits[0], limits[2]) z = np.clip(z, limits[1], limits[3]) # 控制电机移动 yaxis.move_to(y) zaxis.move_to(z) time.sleep(motor_wait) # 读取功率 power = pm.meas_power() return -power # 粗搜:网格化遍历找第一个高于阈值的点 coarse_points_y = np.arange(limits[0], limits[2], coarse_step) coarse_points_z = np.arange(limits[1], limits[3], coarse_step) init_pos = None for y in coarse_points_y: for z in coarse_points_z: yaxis.move_to(y) zaxis.move_to(z) time.sleep(motor_wait) current_power = pm.meas_power() if current_power > power_threshold: init_pos = [y, z] print(f"粗搜找到有效点:Y={y}, Z={z}, 功率={current_power}") break if init_pos is not None: break if init_pos is None: raise RuntimeError("粗搜未找到高于阈值的光信号,请调整搜索范围或阈值") # 精搜:调用Nelder-Mead单纯形算法寻优 result = minimize( objective, x0=init_pos, method='Nelder-Mead', tol=conv_tol, bounds=[(limits[0], limits[2]), (limits[1], limits[3])] ) # 输出最优结果 best_y, best_z = result.x best_power = -result.fun print(f"寻优完成:最优位置Y={best_y:.4f}, Z={best_z:.4f}, 最大功率={best_power:.8f}") # 最后移动到最优位置 yaxis.move_to(best_y) zaxis.move_to(best_z)
参数调整建议
- 如果粗搜速度太慢,可以适当调大
coarse_step,但不能超过光斑直径,否则可能漏过光斑 - 如果精搜出现抖动不收敛的情况,可以适当调大
conv_tol或者motor_wait,保证功率读数稳定 - 功率阈值需要根据实际噪声水平调整,避免把噪声误判为有效信号
内容的提问来源于stack exchange,提问作者Enzo
相关产品推荐
相关产品推荐

