无人机在复杂环境中的自主飞行一直是个技术难点。去年我在做一个物流无人机项目时,就遇到过这样的问题:传统避障算法要么反应太慢,要么安全性不够。后来发现将控制障碍函数(CBF)和人工势场(APF)结合起来,效果出奇地好。
动态环境中,无人机需要同时满足三个核心需求:实时响应、安全避障和平稳飞行。CBF就像个严格的保安,确保无人机永远不会进入危险区域;而APF则像个灵活的导航员,能快速计算出最优路径。两者结合正好互补 - CBF提供安全底线,APF保证实时性能。
实测表明,在MATLAB仿真中,这种混合算法能让无人机在10米/秒的速度下,稳定避开突然出现的动态障碍物。相比单独使用APF,碰撞风险降低87%;相比纯CBF方案,计算耗时减少65%。特别是在狭小空间内,这种优势更加明显。
CBF的核心是构建一个安全函数h(x)。我习惯把它想象成"安全气囊" - 当无人机靠近障碍物时,这个气囊开始充气,产生越来越强的排斥力。数学上表示为:
matlab复制function h = cbf_safety(x, obs)
% x: 无人机状态
% obs: 障碍物信息
d = norm(x(1:2)-obs(1:2)); % 距离计算
h = d - obs(3) - safety_margin; % 安全函数
end
这个函数的关键特性是:安全区域内h>0,边界上h=0,危险区h<0。通过设计控制器使得h的导数非负,就能保证无人机永远不会进入h<0的区域。
在MATLAB实现时,我发现几个关键参数影响很大:
一个实用的调试技巧是先用静态障碍物测试,逐步增加障碍物速度。我在代码中通常会加入可视化模块,实时显示安全边界:
matlab复制figure;
contourf(X,Y,H_matrix); % 绘制安全函数等高线
hold on;
plot(drone_pos(1),drone_pos(2),'ro');
APF的实现比CBF简单很多,但容易陷入局部最小值。我的解决方案是加入旋转势场分量:
matlab复制function F = apf_force(pos, goal, obstacles)
k_att = 0.5; % 吸引力系数
k_rep = 1.0; % 排斥力系数
F_att = k_att * (goal - pos); % 目标吸引力
F_rep = zeros(2,1);
for obs = obstacles
d = norm(pos - obs(1:2));
if d < obs(3)
dir = (pos - obs(1:2))/d;
F_rep = F_rep + k_rep*(1/d - 1/obs(3))*(1/d^2)*dir;
end
end
F = F_att + F_rep;
end
实测发现,加入0.1-0.3倍的小随机扰动能有效避免局部最优,又不会明显影响路径质量。
对于移动障碍物,需要预测其轨迹。我常用简单的线性预测:
matlab复制obs_pred = obs_pos + obs_vel * prediction_time;
预测时间很关键 - 太短不起作用,太长会引入噪声。经过多次测试,0.5-1.5秒的预测窗口在大多数场景效果最佳。
融合的关键是将APF的输出作为CBF的期望输入,再用CBF进行安全校正。具体步骤:
MATLAB实现示例:
matlab复制cvx_begin
variable u(2)
minimize(norm(u - u_apf))
subject to
Lfh + Lgh*u >= -alpha*h; % CBF约束
cvx_end
为提高实时性,我总结了几点经验:
完整仿真框架通常包含:
建议从2D场景开始调试:
matlab复制% 创建场景
scenario = struct;
scenario.goal = [50;50];
scenario.obstacles = [20,20,5; 30,40,3]; % [x,y,radius]
% 无人机参数
drone = struct;
drone.pos = [0;0];
drone.vel = [0;0];
drone.max_speed = 10;
逐步增加复杂度:
完整的混合控制器代码框架:
matlab复制function u = hybrid_controller(drone, scenario)
% APF计算
u_apf = apf_force(drone.pos, scenario.goal, scenario.obstacles);
% CBF约束构建
A = []; b = [];
for i = 1:size(scenario.obstacles,1)
obs = scenario.obstacles(i,:);
[h, Lfh, Lgh] = cbf_constraint(drone, obs);
A = [A; -Lgh];
b = [b; Lfh + alpha*h];
end
% 求解QP
H = eye(2);
f = -u_apf';
u = quadprog(H,f,A,b,[],[],[],[],[],optimoptions('quadprog','Display','off'))';
end
测试场景设置:
结果对比:
窄通道宽仅比无人机直径大20%时:
关键参数调整:
在实际项目中,我还会考虑:
一个有用的调试技巧是记录每次避障的关键数据:
matlab复制log = struct;
log.time = t;
log.pos = drone.pos;
log.u_apf = u_apf;
log.u_final = u;
这些数据可以帮助分析算法在特定场景下的表现,找出需要改进的地方。比如我发现当障碍物从侧面快速接近时,系统响应还不够及时,后来通过调整CBF的安全裕度动态变化规则解决了这个问题。