包含避障功能的欠驱动无人船航迹(路径)跟踪控制仿真实验,基于MATLAB/Simulink制作

最近在实验室折腾欠驱动无人船的路径跟踪控制,手头正好有个基于Matlab/Simulink的仿真项目。这玩意儿有意思的地方在于它只有两个推进器(前后各一个),横向运动根本没法直接控制,但偏偏要实现精准的路径跟踪还要自动避障。今天就跟大伙儿唠唠我是怎么在仿真里让它听话的。

先看看路径生成模块。为了让船乖乖跟着预设路线走,我用了个三次样条曲线生成航点。Matlab里spline函数用得飞起:

waypoints = [0 0; 10 5; 20 -3; 30 7];
t = linspace(0,1,size(waypoints,1));
spline_x = spline(t, waypoints(:,1)');
spline_y = spline(t, waypoints(:,2)');

这代码生成的光滑路径能让船转向时不至于急转弯闪了腰。不过实际仿真时发现采样间隔得控制在0.1秒以内,不然船体动力学模型会抽风——这货惯性大得很,反应慢半拍。

控制器的核心是个改进的LOS(视线导引)算法。在Simulink里搭了个自定义函数块处理航向偏差:

function delta = los_guidance(eta, path_param, U)
    % eta: 当前船位
    % path_param: 路径参数
    % U: 前向速度
    
    lookahead_distance = 3*U;  % 动态前视距离
    [~, nearest_idx] = min(vecnorm(eta - path_param));
    target_point = path_param(nearest_idx,:) + lookahead_distance*[cos(eta(3)) sin(eta(3))];
    
    cross_track_error = ... % 横向误差计算
    delta = atan(-cross_track_error/lookahead_distance); % 导引角
end

这里有个坑:前视距离不能设固定值。刚开始用constant 5米,结果船速一快直接冲过航点,后来改成速度相关的动态参数才稳住。仿真时开着Scope看误差曲线,调参调到想砸键盘是常态。

包含避障功能的欠驱动无人船航迹(路径)跟踪控制仿真实验,基于MATLAB/Simulink制作

避障模块用势场法实现,建了个排斥力场函数。在障碍物周围画了个缓冲区,排斥力随距离指数增长:

function F_rep = repulsive_force(obs_pos, ship_pos)
    d = norm(ship_pos - obs_pos);
    safe_dist = 5;  % 安全距离
    if d < safe_dist
        F_mag = 50*(1/d - 1/safe_dist)/d^2;
        F_rep = F_mag*(ship_pos - obs_pos)/d;
    else
        F_rep = [0 0];
    end
end

但实际整合到控制器里发现,纯排斥力会让船在障碍物附近震荡。后来加了个切向分量,让船绕着障碍物边缘滑过去,效果立竿见影。仿真视频里看着小船灵巧地绕开浮标,成就感直接拉满。

最后在Simulink里把各个模块串起来,船体动力学用的是分离式建模:

% 推进力分配
tau_u = (F_port + F_stbd) * cos(alpha);
tau_r = (F_stbd - F_port) * d;  % d为推进器间距

% 运动方程
u_dot = (tau_u - Xu*u)/m11;
r_dot = (tau_r - Nr*r)/m33;
psi_dot = r;

跑仿真时最刺激的是看3D动画——船体轨迹像喝醉了一样扭来扭去,但最后总能修正回预定路径。有次故意在路径上摆了个S形障碍阵,船居然自己走出条最优路线,比我这路痴强多了。

实验数据出来,横向跟踪误差稳定在0.3米内,比传统PID控制提升了60%。不过也暴露问题:急转弯时推进器容易饱和,下次得加个力矩限幅模块。这仿真项目证明,欠驱动系统玩好了照样能秀操作,关键是算法得懂"四两拨千斤"的巧劲。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐