自动驾驶技术近年来取得了显著进展,其中避障算法作为核心功能模块,直接关系到行车安全。在众多避障算法中,人工势力场(Artificial Potential Field, APF)因其直观的物理模型和计算高效性,成为工程实践中广泛采用的基础方案。
我第一次接触APF算法是在2018年参与园区无人车项目时。当时团队尝试了多种路径规划方案,最终发现APF在实时性和实现复杂度之间取得了很好的平衡。这种算法将车辆的运动抽象为物理场中的质点运动,通过力场的构建实现避障逻辑,非常符合工程师的思维习惯。
APF算法的核心是将车辆环境建模为势场空间,主要包含两种力:
这两种力场叠加形成的合力场,决定了车辆的运动方向和速度。从数学角度看,势函数U(q)定义为:
U(q) = U_att(q) + U_rep(q)
其中q表示车辆位置坐标,U_att和U_rep分别代表吸引和排斥势函数。
最常用的吸引力场采用二次函数形式:
U_att(q) = 0.5 * k_att * ρ^2(q,q_goal)
其中:
对应的吸引力计算为势函数的负梯度:
F_att(q) = -∇U_att(q) = k_att * (q_goal - q)
这个模型的特点是距离目标越远,吸引力越大,类似于弹簧的胡克定律。
排斥力场通常采用反比例函数形式:
U_rep(q) = {
0.5 * k_rep * (1/ρ(q,q_obs) - 1/ρ_0)^2, if ρ(q,q_obs) ≤ ρ_0
0, if ρ(q,q_obs) > ρ_0
}
其中:
对应的排斥力计算为:
F_rep(q) = -∇U_rep(q) = {
k_rep * (1/ρ - 1/ρ_0) * (1/ρ^2) * ∇ρ, if ρ ≤ ρ_0
0, if ρ > ρ_0
}
matlab复制% 车辆初始位置 (m)
vehicle_pos = [0, 0];
% 目标位置 (m)
goal_pos = [10, 10];
% 障碍物参数 [x,y,radius] (m)
obstacles = [3,4,1; 6,7,1];
% 控制参数
k_att = 1.0; % 吸引力增益
k_rep = 10.0; % 排斥力增益
step_size = 0.1; % 运动步长 (m/step)
max_iter = 1000; % 最大迭代次数
参数设置经验:
matlab复制function F_att = calculateAttraction(vehicle, goal, k_att)
% 计算位置差向量
delta = goal - vehicle;
% 计算欧式距离
dist = norm(delta);
% 归一化方向向量
if dist > 0
dir = delta / dist;
else
dir = [0, 0];
end
% 计算吸引力
F_att = k_att * dist * dir;
end
改进说明:
matlab复制function F_rep = calculateRepulsion(vehicle, obstacles, k_rep)
F_rep = [0, 0];
for i = 1:size(obstacles,1)
obs_pos = obstacles(i,1:2);
obs_radius = obstacles(i,3);
% 计算相对位置
delta = vehicle - obs_pos;
dist = norm(delta);
% 检查是否在影响范围内
if dist <= obs_radius
% 计算排斥力大小
if dist > 0.01 % 避免奇异值
magnitude = k_rep * (1/dist - 1/obs_radius) * (1/dist^2);
F_rep = F_rep + magnitude * (delta/dist);
else
% 极近距离时的处理
F_rep = F_rep + [1e5, 1e5];
end
end
end
end
关键改进点:
matlab复制% 初始化轨迹记录
trajectory = zeros(max_iter, 2);
trajectory(1,:) = vehicle_pos;
% 主循环
for iter = 2:max_iter
% 计算受力
F_att = calculateAttraction(vehicle_pos, goal_pos, k_att);
F_rep = calculateRepulsion(vehicle_pos, obstacles, k_rep);
F_total = F_att + F_rep;
% 更新位置
vehicle_pos = vehicle_pos + step_size * F_total/norm(F_total);
trajectory(iter,:) = vehicle_pos;
% 终止条件检查
if norm(vehicle_pos - goal_pos) < 0.1
trajectory = trajectory(1:iter,:);
break;
end
end
% 可视化
figure;
hold on;
% 绘制障碍物
for i = 1:size(obstacles,1)
rectangle('Position',[obstacles(i,1)-obstacles(i,3),...
obstacles(i,2)-obstacles(i,3),...
2*obstacles(i,3),2*obstacles(i,3)],...
'Curvature',[1,1],'FaceColor','r');
end
% 绘制轨迹
plot(trajectory(:,1), trajectory(:,2), 'b-', 'LineWidth',1.5);
% 绘制起点和终点
plot(trajectory(1,1),trajectory(1,2),'go','MarkerSize',8,'LineWidth',2);
plot(goal_pos(1),goal_pos(2),'mx','MarkerSize',8,'LineWidth',2);
axis equal; grid on;
xlabel('X Position (m)'); ylabel('Y Position (m)');
title('APF避障轨迹仿真');
legend('障碍物','行驶轨迹','起点','终点');
可视化技巧:
现象:车辆在特定位置受力平衡,陷入停滞
解决方案:
matlab复制% 随机扰动实现示例
if norm(F_total) < 0.01 && iter > 50
F_total = F_total + 0.1*randn(1,2);
end
现象:车辆在障碍物附近来回摆动
解决方案:
matlab复制% 动态步长调整
adaptive_step = min(step_size, 0.1*norm(F_total));
vehicle_pos = vehicle_pos + adaptive_step * F_total/norm(F_total);
吸引力系数k_att:
排斥力系数k_rep:
障碍物影响半径ρ0:
matlab复制% 预测障碍物位置
obs_velocity = [0.2, 0]; % 障碍物速度
predicted_pos = obs_pos + obs_velocity * prediction_time;
matlab复制% 椭圆障碍物距离计算
a = 2; b = 1; % 长短轴
theta = atan2(delta(2), delta(1));
closest_point = obs_pos + [a*cos(theta), b*sin(theta)];
dist = norm(vehicle_pos - closest_point);
matlab复制% 3D距离计算
dist = sqrt(dx^2 + dy^2 + dz^2);
简单避障场景:
复杂迷宫场景:
动态场景:
| 特性 | APF | A* | RRT |
|---|---|---|---|
| 实时性 | 优秀 | 一般 | 中等 |
| 路径最优性 | 局部最优 | 全局最优 | 随机近似 |
| 内存消耗 | 低 | 高 | 中等 |
| 实现复杂度 | 简单 | 中等 | 复杂 |
APF最适合实时性要求高、计算资源有限的场景,如嵌入式系统上的实时避障。
matlab复制% 使用网格分区
grid_size = 2.0;
obs_grid = floor(obstacles(:,1:2)/grid_size);
matlab复制% 离线计算力场图
[xx,yy] = meshgrid(0:0.5:10);
potential_map = zeros(size(xx));
matlab复制% 使用parfor并行计算多个障碍物
parfor i = 1:num_obs
rep_forces(i,:) = calc_rep_force(vehicle, obs(i));
end
在多车系统中,需要考虑车车之间的相互作用力:
matlab复制function F_inter = vehicleInteraction(ego_pos, other_vehicles)
F_inter = [0, 0];
for i = 1:size(other_vehicles,1)
dist = norm(ego_pos - other_vehicles(i,:));
if dist < safe_distance
F_inter = F_inter + k_inter * (safe_distance-dist) * ...
(ego_pos-other_vehicles(i,:))/dist;
end
end
end
对于实际车辆,需要考虑运动学约束:
matlab复制% 车辆运动学模型
max_steer = pi/4; % 最大转向角
wheelbase = 2.5; % 轴距
% 计算可行转向
desired_angle = atan2(F_total(2), F_total(1));
steer_angle = max(-max_steer, min(max_steer, desired_angle - current_yaw));
使用神经网络优化势场参数:
matlab复制% 神经网络预测参数
input = [vehicle_pos, goal_pos, obstacles(:)'];
k_att = net_att(input);
k_rep = net_rep(input);
在实际项目中,我们发现结合简单的模糊逻辑控制可以显著提升APF在复杂场景下的表现。例如根据距离动态调整参数:
matlab复制% 模糊参数调整
if min_obs_dist < 2.0
k_rep = base_k_rep * (3.0/min_obs_dist);
else
k_rep = base_k_rep;
end
这种基于APF的混合方法既保持了算法的简洁性,又提高了在真实环境中的可靠性。