FA_规划和控制(PC)-人工势场法(APF)

📅 发布时间:2026/7/16 2:25:26 👁️ 浏览次数:
FA_规划和控制(PC)-人工势场法(APF)
FAformulas and algorithm,PCplanning and controlAPFartificial potential field一、人工势场法APF核心概念人工势场法Artificial Potential Field, APF是一种模拟物理中 “势场” 概念的路径规划算法核心思想是目标点对机器人产生引力Attractive Potential拉着机器人向目标移动 障碍物对机器人产生斥力Repulsive Potential推着机器人远离障碍物 机器人的运动方向由引力和斥力的合力决定最终沿着 “势场梯度下降” 的方向找到一条无碰撞的路径。可以类比成你机器人在一个山谷里目标点是山谷的最低点引力障碍物是山谷里的石头斥力你会沿着 “往最低点走、同时避开石头” 的方向移动。1. 核心数学模型1引力场与引力引力场通常采用二次函数目标点附近平滑距离越远引力越大Uatt​(q)21​ξ⋅∥q−qgoal​∥2引力是引力场的负梯度梯度方向是势场上升方向负梯度是下降方向Fatt​(q)−∇Uatt​(q)ξ⋅(qgoal​−q)其中ξ引力增益系数控制引力大小 q(x,y)机器人当前位置 qgoal​(xgoal​,ygoal​)目标点位置 ∥⋅∥欧几里得距离。2斥力场与斥力斥力场采用分段函数仅在障碍物一定范围内生效避免全局影响$Urep​(q){21​η⋅(∥q−qobs​∥1​−ρ0​1​)2,0,​∥q−qobs​∥≤ρ0​∥q−qobs​∥ρ0​​斥力是斥力场的负梯度Frep​(q)−∇Urep​(q){η⋅(∥q−qobs​∥1​−ρ0​1​)⋅∥q−qobs​∥21​⋅∥q−qobs​∥q−qobs​​,0,​∥q−qobs​∥≤ρ0​∥q−qobs​∥ρ0​​其中η斥力增益系数 qobs​(xobs​,yobs​)障碍物位置 ρ0​障碍物影响半径超出则无斥力。3总势场与总受力总势场 引力场 斥力场Utotal​(q)Uatt​(q)∑i1n​Urep,i​(q)总受力 引力 所有障碍物的斥力Ftotal​(q)Fatt​(q)∑i1n​Frep,i​(q)二、APF的应用场景APF算法因实现简单、实时性好广泛应用于移动机器人路径规划如AGV自动导引车、无人机、扫地机器人的局部路径规划自动驾驶低速场景下的避障如园区无人车、泊车辅助机械臂运动规划关节空间/笛卡尔空间的避障路径生成游戏AI游戏角色的避障移动如NPC避开障碍物到达目标点。局限性易陷入局部最小值机器人被引力和斥力平衡“卡住”无法到达目标需额外策略优化如添加随机扰动、动态调整势场参数。三、APF的操作步骤以二维平面机器人路径规划为例核心步骤如下1、初始化参数机器人起始位置q s t a r t q_{start}qstart​​、目标位置q g o a l q_{goal}qgoal​​障碍物位置列表Q o b s ​ [ q o b s 1 ​ , q o b s 2 ​ , . . . ] Q_{obs}​[q_{obs1}​,q_{obs2}​,...]Qobs​​[qobs1​​,qobs2​​,...]引力系数ξ ξξ、斥力系数η ηη、障碍物影响半径ρ 0 ρ_0ρ0​​步长δ δδ机器人每次移动的距离、目标阈值ϵ ϵϵ距离目标小于ϵ ϵϵ则停止。2、迭代计算路径计算当前位置的引力F a t t F_{att}Fatt​​计算所有障碍物的斥力F r e p , i F_{rep,i}Frep,i​​求和得到总斥力计算总受力F t o t a l F_{total}Ftotal​​归一化后作为移动方向机器人沿总受力方向移动一步q n e w ​ q c u r r e n t ​ δ ⋅ F t o t a l ∥ F t o t a l ​∥ q_{new}​q_{current}​δ⋅\frac{F_{total}}{∥F_{total}​∥}qnew​​qcurrent​​δ⋅∥Ftotal​​∥Ftotal​​​​记录新位置到路径列表检查是否到达目标∥ q c u r r e n t ​ − q g o a l ​∥ ϵ ∥q_{current}​−q_{goal}​∥ϵ∥qcurrent​​−qgoal​​∥ϵ若到达则停止否则重复迭代。输出路径将迭代过程中记录的位置列表作为最终路径。四、APF代码实现Python以下是完整的二维APF路径规划代码包含可视化功能可直接运行importnumpy as npimportmatplotlib.pyplot as plt# 定义人工势场法类class APFPlanner: def __init__(self):# 核心参数可根据场景调整self.xi0.8# 引力增益系数self.eta50.0# 斥力增益系数self.rho01.0# 障碍物影响半径self.delta0.05# 移动步长self.epsilon0.1# 目标阈值距离小于该值则到达self.max_iter1000# 最大迭代次数防止死循环# 计算引力def attractive_force(self, current_pos, goal_pos):# current_pos: 机器人当前位置 (x,y)# goal_pos: 目标位置 (x,y)directiongoal_pos - current_pos distancenp.linalg.norm(direction)# 引力 xi * (目标位置 - 当前位置)forceself.xi * directionreturnforce# 计算单个障碍物的斥力def repulsive_force(self, current_pos, obs_pos):# current_pos: 机器人当前位置 (x,y)# obs_pos: 单个障碍物位置 (x,y)directioncurrent_pos - obs_pos# 斥力方向远离障碍物distancenp.linalg.norm(direction)ifdistanceself.rho0:# 超出影响半径斥力为0returnnp.array([0.0,0.0])else:# 斥力计算公式rep_forceself.eta *(1/distance -1/self.rho0)*(1/distance**2)*(direction / distance)returnrep_force# 规划路径def plan(self, start_pos, goal_pos, obs_list):# start_pos: 起始位置 (x,y)# goal_pos: 目标位置 (x,y)# obs_list: 障碍物列表 [[x1,y1], [x2,y2], ...]current_posnp.array(start_pos,dtypenp.float64)path[current_pos.copy()]# 记录路径for_inrange(self.max_iter):# 1. 计算引力f_attself.attractive_force(current_pos, goal_pos)# 2. 计算总斥力遍历所有障碍物f_rep_totalnp.array([0.0,0.0])forobsinobs_list: obs_posnp.array(obs)f_repself.repulsive_force(current_pos, obs_pos)f_rep_totalf_rep# 3. 总受力f_totalf_att f_rep_total f_total_normnp.linalg.norm(f_total)# 防止受力为0陷入局部最小值iff_total_norm1e-6: print(警告受力为0可能陷入局部最小值)# 添加微小随机扰动跳出局部最小值f_totalnp.array([np.random.uniform(-0.1,0.1), np.random.uniform(-0.1,0.1)])f_total_normnp.linalg.norm(f_total)# 4. 移动一步归一化方向 步长current_posself.delta *(f_total / f_total_norm)# 5. 记录路径path.append(current_pos.copy())# 6. 检查是否到达目标ifnp.linalg.norm(current_pos - goal_pos)self.epsilon: print(到达目标)breakreturnnp.array(path)# -------------------------- 测试代码 --------------------------if__name____main__:# 1. 初始化规划器apfAPFPlanner()# 2. 设置起始点、目标点、障碍物start(0.0,0.0)# 起始位置goal(5.0,5.0)# 目标位置obstacles[# 障碍物列表(2.0,2.0),(3.0,4.0),(1.0,3.5)]# 3. 规划路径pathapf.plan(start, goal, obstacles)# 4. 可视化结果plt.figure(figsize(8,8))# 绘制障碍物forobsinobstacles: circleplt.Circle(obs, apf.rho0,colorr,alpha0.3,labelObstacleifobsobstacles[0]else)plt.gca().add_patch(circle)# 绘制路径plt.plot(path[:,0], path[:,1],b-,linewidth2,labelAPF Path)# 绘制起始点和目标点plt.scatter(start[0], start[1],colorgreen,s100,labelStart)plt.scatter(goal[0], goal[1],colorred,s100,labelGoal)# 图表设置plt.xlabel(X (m))plt.ylabel(Y (m))plt.title(Artificial Potential Field (APF) Path Planning)plt.legend()plt.grid(True)plt.axis(equal)plt.show()代码关键部分解释参数初始化xi引力和eta斥力是核心可调参数——xi过小会导致机器人向目标移动慢eta过大会导致斥力过强机器人远离障碍物过远需根据场景调试引力计算直接按公式实现方向始终指向目标点斥力计算判断机器人与障碍物的距离超出rho0则斥力为0否则按公式计算路径迭代每次计算总受力后归一化方向移动固定步长直到到达目标或达到最大迭代次数局部最小值处理添加随机扰动避免机器人因引力和斥力平衡“卡住”可视化用matplotlib绘制路径、障碍物、起始/目标点直观展示规划结果。运行前置条件安装依赖库pipinstallnumpy matplotlib直接运行代码会弹出可视化窗口显示规划的路径。五、结束语核心原理APF通过引力拉向目标和斥力推离障碍物的合力引导机器人移动本质是势场梯度下降关键步骤初始化参数→迭代计算引力/斥力→沿合力移动→到达目标停止使用要点需调试xi引力、eta斥力、rho0障碍物影响半径等参数同时注意处理局部最小值问题适用场景实时性要求高、环境简单的局部路径规划如AGV、无人机避障。