最近几个月一直在帮客户调一台 50 kg 载重级别的六轴植保机。平台用的是魔改的 ArduCopter 固件(底层挂载 RTK 与避障雷达),动力套件是 10015 电机配 36 寸碳纤桨。
很多做植保算法的朋友容易把变量喷洒当成一个单纯的「地速-流量」映射问题,觉得只要写个线性插值、用 PWM 控水泵就完事了。实际上,大载重平台一旦起飞,强烈的旋翼下洗气流(Downwash)和水箱液体晃动会对雾滴沉降、作业幅宽产生决定性影响。今天把我们外场实飞的数据和代码逻辑整理出来,给做农林植保和飞控二次开发的朋友参考。
1. 硬件配置与测绘基线
测试平台的关键参数如下:
- 轴距:1750 mm,对称六轴
- 整机空重:28 kg,最大起飞重量(MTOW):78 kg(额定载药 50 L)
- 喷洒系统:双无刷隔膜泵 + 4 组离心雾化喷头(带霍尔流量计反馈)
- 导航定位:双天线 RTK(用于偏航与厘米级定位)
- 巡航参数:对地作业高度 2.5 - 3.5 m,作业航速 4.0 - 7.5 m/s
在开展变量喷洒测试前,我们先在跑道上布置了水敏纸矩阵,测定纯下洗风场对雾滴穿透率的影响。
2. 下洗气流分布与喷头布局调优
在大载重多旋翼下,旋翼尖端涡流会导致雾滴向外侧和上方卷吸(即漂移),而旋翼正下方的垂直风速最高。
实飞测得的下洗气流垂直分量分布如下(桨盘下方 1.2 m 处):
- 旋翼中心(电机轴):垂直风速约 3.5 - 4.2 m/s。
- 0.7R - 0.8R(桨叶 75% 半径处):垂直风速达到峰值,约 11.8 - 13.5 m/s。
- 桨尖以外区域:出现向上的反向涡流卷吸,速度约 -1.5 m/s。
桨盘平面
[====电机====0.75R====桨尖]
| | ^
| 4m/s | 13m/s | 向上卷吸 (-1.5m/s)
v v |
--------------------------------- 地面
喷头位置调整复盘: 最初方案是将喷头安装在机臂最外侧,以为可以扩大喷幅。实测发现,在航速超过 5 m/s 时,最外侧喷头产生的微米级雾滴直接被桨尖涡卷入机身背风区,水敏纸上几乎看不到有效沉积,药液漂移率高达 35%。
最终优化方案:将 4 个离心喷头全部内缩至旋翼下方 0.7R 的最大下洗风速区域,距桨盘垂直距离保持在 450 mm。利用下洗风场的强垂直动量压制细雾滴,穿透水稻冠层的比例直接从 48% 提升至 76%,有效喷幅稳定在 6.5 m。
3. 基于航速与处方图的变量控制算法
变量喷洒控制的核心逻辑是:根据飞控当前的水平地速 $V_{ground}$、设定的单亩施药量 $D_{target}$(L/亩)以及有效喷幅 $W$,实时计算目标容积流量 $Q_{target}$(L/min)。
计算公式: $$Q_{target} = \frac{D_{target} \times W \times V_{ground}}{666.7} \times 60$$
在实际工程中,不能单纯依靠前馈,因为管路压力变化、水泵磨损及药液粘度会导致稳态误差,必须加入流量计的闭环 PID 控制。
以下是在机载计算单元(或外挂控制板)上运行的 C++ 核心控制片段:
#include <algorithm>
#include <cmath>
struct SprayConfig {
float spray_width = 6.5f; // 有效喷幅,单位: 米
float min_pump_pwm = 1100.0f; // 水泵死区阈值
float max_pump_pwm = 1950.0f;
float kp = 120.0f; // 闭环比例项
float ki = 25.0f; // 闭环积分项
};
class SprayController {
public:
SprayController(const SprayConfig& cfg) : config_(cfg) {}
// 计算水泵控制输出 (PWM 1000-2000)
float update(float ground_speed_m_s, float target_dose_L_per_mu,
float actual_flow_L_min, float dt)
{
// 航速过低或悬停时自动切断喷洒,防止单点药害烧苗
if (ground_speed_m_s < 0.8f) {
integral_ = 0.0f;
return 1000.0f;
}
// 计算目标流量: L/min
// 1 亩 ≈ 666.67 平方米
float target_flow = (target_dose_L_per_mu * config_.spray_width * ground_speed_m_s * 60.0f) / 666.67f;
// 流量闭环 PID 控制 (PI 即可满足要求)
float error = target_flow - actual_flow_L_min;
integral_ += error * dt;
// 积分抗饱和处理
integral_ = std::clamp(integral_, -5.0f, 5.0f);
// 前馈项:基于标定曲线的经验线性映射
float feed_forward = 1000.0f + (target_flow / 8.0f) * 900.0f;
// 控制量合成
float output_pwm = feed_forward + (config_.kp * error) + (config_.ki * integral_);
return std::clamp(output_pwm, config_.min_pump_pwm, config_.max_pump_pwm);
}
private:
SprayConfig config_;
float integral_ = 0.0f;
};
4. 炸机复盘与边缘工况踩坑
在做植保飞控调试时,环境往往非常恶劣,以下是两起真实故障复盘:
事故一:水箱破浪板缺失引发俯仰轴共振坠机
- 现象:满载 50 kg 水起飞,以 6 m/s 航速做「弓」字形掉头。在减速刹车阶段,飞机俯仰轴(Pitch)出现发散性剧烈晃动,姿态角在 1.5 秒内失控超过 45 度,飞控触发低空倾翻保护锁桨炸机。
- 排查:读取 Dataflash 日志,发现刹车时内部液体向前涌动,质心瞬时前移超过 12 cm,导致前三轴电机瞬间达到最大转速饱和,控制分配(Mixer)失去力矩裕度。
- 解决:药箱内必须加装纵横交错的物理防浪隔板;同时在飞控参数中限制加速度限制参数
WPNAV_ACCEL,由原来的 2.5 m/s² 降为 1.2 m/s²,避免急刹带来的强冲击。
事故二:流量计气泡干扰导致水泵超频烧毁
- 现象:在作业到药液末期时,水管吸入空气。霍尔式叶轮流量计在通过气泡时瞬时转速畸变,向飞控反馈了一个虚假的超大流量值(>15 L/min)。
- 后果:控制器检测到流量「超标」,瞬间将积分项下拉,随后空气排空,流量读数暴跌至 0,控制器又暴力拉满水泵 PWM,高频反复振荡导致电调击穿。
- 解决:在流量计底层驱动中加入移动中值滤波(Median Filter)与斜率保护,若 $dQ/dt$ 异常超出物理极限,直接降级至纯前馈开环控制,并向地面站上报
SPRAY_FLOW_SENSOR_INVALID警报。
5. 总结
在大载重植保作业中,飞控算法不能脱离空气动力学和流体物理特性:
- 下洗利用优先:离心喷头务必布置在高风速下洗区,避开桨尖反向气流,压制雾滴飘移。
- 控制解耦:变量喷洒必须做速度死区切断与平滑加减速,避免航线转弯掉头时的药害重叠。
- 传感器容错:农药起泡、泥沙杂质是常态,流量计读数必须做异常剔除,开环前馈保底比激进的积分闭环更安全。
下一步我们准备在 Gazebo 里结合风场插件做多旋翼与液滴流动的耦合仿真,尽量把边界问题在实验室里规避掉。
许可协议:CC BY-NC 4.0
更新于 3 小时前
觉得文章有帮助?点个赞吧!
0 条评论


