1. 无人船轨迹跟踪与自动靠泊系统概述
无人水面车辆(USV)作为智能海洋装备的核心组成部分,正在深刻改变着传统海上作业模式。在海洋测绘、环境监测、港口巡检等应用场景中,精确的轨迹跟踪和可靠的自动靠泊能力直接决定了USV的作业效能。我们团队基于PX4开源飞控框架和C++开发环境,构建了一套完整的模型预测控制(MPC)解决方案,经过实际水域测试验证,在3级海况下仍能保持0.5米以内的轨迹跟踪精度。
这套系统的技术核心在于将复杂的运动控制问题分解为三个层次:最上层采用改进的视线制导(LOS)算法进行路径规划,中间层通过MPC控制器处理动力学约束下的优化问题,底层则利用PX4的原生混控器实现执行机构控制。特别在自动靠泊场景中,我们创新性地采用了双阶段路径生成策略,先通过全局路径规划将USV引导至泊位附近的安全区域,再切换为基于五次样条的局部精细调整,有效解决了传统方法在最终靠泊阶段容易出现的振荡问题。
2. 无人船动力学建模关键技术
2.1 坐标系定义与转换原理
在无人船运动控制中,正确处理坐标系关系是建模的基础。我们采用右手坐标系规则定义了两个关键参考系:
-
东北天坐标系(NED):固定于地面的惯性参考系
- X轴指向正北
- Y轴指向正东
- Z轴垂直向下指向地心
-
船体坐标系(Body Frame):固连在船体的动参考系
- X轴沿船体纵轴指向前方
- Y轴指向右舷
- Z轴垂直甲板向下
两坐标系间的转换通过旋转矩阵实现,其中最关键的是艏摇角(ψ)的转换。当仅考虑水平面运动时,转换关系可简化为:
code复制[x_body] [cosψ sinψ][x_ned]
[y_body] = [-sinψ cosψ][y_ned]
实际编程实现时需要注意:PX4内部使用四元数表示姿态,需要特别处理姿态转换时的奇点问题。我们建议使用Eigen库的Quaternion类进行相关运算。
2.2 三自由度运动学模型构建
针对水面船舶的主要运动特性,我们建立了包含纵荡、横荡和艏摇的三自由度模型。该模型充分考虑了以下因素:
- 流体动力导数:包括线性阻尼系数和非线性交叉耦合项
- 螺旋桨推力特性:左右推进器的推力不对称性
- 环境扰动:通过等效力和力矩项表示风浪影响
具体的状态空间方程表示为:
code复制Mν̇ + C(ν)ν + D(ν)ν = τ + τ_env
η̇ = J(η)ν
其中:
- M为惯性矩阵(包含附加质量)
- C(ν)为科里奥利力矩阵
- D(ν)为阻尼矩阵
- τ为控制输入
- τ_env为环境干扰
- J(η)为转换矩阵
3. 分层控制架构设计与实现
3.1 制导层:改进型LOS算法
传统LOS算法在路径跟踪中存在曲率不连续的缺陷,我们通过引入自适应前视距离和曲率平滑模块进行了优化:
-
前视距离动态调整:
cpp复制double L = L_min + k*(v - v_min); // v为当前速度,k为调节系数 -
路径曲率补偿:
- 实时计算路径曲率半径R
- 在期望艏向中增加补偿角Δψ = atan(L/(2R))
实测表明,这种改进使USV在转弯时的轨迹偏差减少了40%以上。
3.2 控制层:MPC核心实现
3.2.1 预测模型离散化
我们采用Tustin双线性变换将连续模型离散化,采样周期选择100ms(与PX4的主控周期一致)。离散化后的状态方程:
code复制x(k+1) = A_d x(k) + B_d u(k)
y(k) = C_d x(k)
在C++实现中,使用Eigen库进行矩阵运算:
cpp复制MatrixXd Ad = (MatrixXd::Identity(n,n) - 0.5*Ts*A).inverse()
* (MatrixXd::Identity(n,n) + 0.5*Ts*A);
3.2.2 优化问题构建
MPC的核心是求解如下优化问题:
code复制min Σ(||x(k+i)-x_ref||_Q + ||u(k+i)||_R)
s.t. x(k+i+1) = A_d x(k+i) + B_d u(k+i)
u_min ≤ u(k+i) ≤ u_max
我们采用qpOASES求解器处理这个二次规划问题,关键配置参数包括:
- 预测时域N=10(对应1秒)
- 状态权重Q=diag([10,10,5,1,1,0.5])
- 控制权重R=diag([0.1,0.1])
注意:权重选择需要根据船舶动力学特性调整,过大的Q值可能导致执行器饱和。
4. 自动靠泊系统实现细节
4.1 双阶段路径规划策略
4.1.1 全局粗规划阶段
采用改进A*算法考虑:
- 静态障碍物安全距离
- 水流方向影响
- 船舶最小转弯半径约束
生成的关键航路点通过三次样条插值平滑处理。
4.1.2 局部精调整阶段
在距泊位5米范围内切换为五次样条规划:
cpp复制VectorXd coeff = spline.solve(
start_pose, end_pose,
start_vel, end_vel,
start_acc, end_acc);
这保证了靠泊末端的位置、速度和加速度连续性。
4.2 PX4集成关键点
- 混控器配置(mixer文件):
code复制R: 4x 10000 10000 0 -10000 0 1
# 左右电机+舵机混控
- MAVLink消息处理:
cpp复制mavlink_msg_attitude_pack(
sysid, compid,
&msg,
roll, pitch, yaw,
rollspeed, pitchspeed, yawspeed);
- 参数同步机制:
- 通过param_set保存MPC参数
- 使用param_get在启动时读取
5. 实际调试经验与问题排查
5.1 常见问题速查表
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 轨迹振荡 | Q矩阵权重过大 | 降低位置相关权重 |
| 响应迟缓 | 预测时域过长 | 减小N至5-10步 |
| 执行器饱和 | 控制量约束过松 | 检查u_max参数 |
| 偏航不稳定 | 阻尼系数不准 | 重新辨识Yv,Nr参数 |
5.2 参数整定心得
- 先调姿态环再调位置环
- 从静止工况开始测试
- 海试时逐步增加浪高等级
- 记录ROS bag数据离线分析
我们总结的最佳实践是:先用PID让船舶基本可控,再切换MPC进行精细调节。在3米级USV上,典型MPC参数范围为:
- 采样周期:50-200ms
- 预测时域:5-15步
- 求解器容差:1e-4
6. 系统性能优化方向
- 在线模型辨识:通过递归最小二乘法实时更新水动力参数
- 事件触发机制:在状态变化小时降低控制频率
- 异构计算:将QP求解卸载到FPGA加速
- 多船协同:引入冲突检测算法
在现有代码框架下,最值得优先实现的是模型参数的自适应更新。可以扩展状态估计器,同时估计船舶状态和水动力参数。我们验证过的方法是在EKF中增加参数状态:
cpp复制state_vector << x, y, ψ, u, v, r, Xu, Yv, Nr;
这种实现需要注意参数的可观测性问题,需要通过持续激励保证辨识效果。