1. PX4位置控制器概述

大家好,我是你们的飞控讲师。今天咱们聊聊PX4多旋翼位置控制器的整体架构。说实话,这个模块是整个飞控系统里最贴近用户感知的部分——你推摇杆,飞机怎么动,全看它。

1.1 位置控制器在飞控系统中的位置

先看一张整体结构图,我习惯把PX4飞控系统分成三层:

PX4多旋翼飞控系统三层架构 位置控制器(Position Controller) 输入:期望位置/速度 → 输出:期望姿态角 + 推力 运行频率:50Hz ~ 100Hz 姿态控制器(Attitude Controller) 输入:期望姿态角 → 输出:期望角速度 运行频率:250Hz ~ 400Hz 角速度控制器(Rate Controller) 输入:期望角速度 → 输出:电机PWM值 运行频率:1kHz 外环 中环 内环 GPS/光流/视觉 IMU/磁力计 陀螺仪

你看,位置控制器在最外层。它接收期望位置(比如你要飞到N30° E120°那个点),然后算出飞机应该朝哪个方向倾斜、给多大油门。说白了,它就是个翻译官——把「去哪」翻译成「怎么飞」。

1.2 位置控制器的核心数据流

数据怎么流的?我画个简化的框图你就明白了:

期望位置 (x_des, y_des, z_des) 位置误差 e = x_des - x_cur P控制器 v_des = Kp * e 速度限幅 |v| ≤ v_max 当前位置反馈 (x_cur, y_cur, z_cur) 期望速度 传给速度环 简化版:位置环 → 速度限幅 → 输出期望速度

嗯,这里要注意:位置控制器内部其实还嵌套了一个速度控制器。位置环输出的是期望速度,速度环再算出期望加速度,最后映射到姿态角。我刚开始学的时候,老觉得位置环直接输出角度就行了,后来调试才发现——不加速度限幅,飞机起飞时能翻跟头!

1.3 位置控制器的输入输出

咱们把接口捋清楚:

信号类型 具体内容 数据来源 说明
输入 期望位置 (x, y, z) 遥控器 / 任务规划 / 机载计算机 单位:米,NED坐标系
输入 期望偏航角 (yaw) 遥控器 / 任务规划 单位:弧度
输入 当前位置/速度估计 EKF2估计器 融合GPS、IMU、视觉等
输出 期望姿态角 (roll, pitch) 传给姿态控制器 由加速度反算得到
输出 期望推力 (thrust) 传给姿态控制器 归一化值 0~1

💡 个人经验:我在做物流无人机项目时,发现位置控制器的输入频率很关键。如果GPS更新率只有5Hz,位置环跑50Hz其实意义不大——你想想看,输入数据都跟不上,算得再快也是白算。后来我改成根据传感器更新率动态调整位置环频率,效果好了不少。

1.4 位置控制器的代码结构

源码在 src/modules/mc_pos_control/ 目录下。核心文件就这几个:

  • PositionControl.cpp — 主逻辑,位置环+速度环计算
  • PositionControl.hpp — 头文件,定义类接口
  • takeoff.cpp — 起飞逻辑,单独抽出来了
  • land.cpp — 降落逻辑,同样独立

我习惯先看头文件,了解有哪些成员变量:

// PositionControl.hpp 核心接口
class PositionControl
{
public:
    // 设置期望值
    void setPositionSetpoint(const PositionSetpoint& sp);
    void setVehicleState(const VehicleState& state);
    
    // 核心计算函数
    void update(float dt);
    
    // 获取输出
    const VehicleAttitudeSetpoint& getAttitudeSetpoint() const;
    
private:
    // 位置环P增益
    matrix::Vector3f _pos_p;
    // 速度环PID增益
    matrix::Vector3f _vel_p, _vel_i, _vel_d;
    // 限幅参数
    float _vel_max;
    float _acc_max;
};

你看,接口很清晰。setPositionSetpoint喂期望,setVehicleState喂当前状态,update算一步,getAttitudeSetpoint拿结果。说白了就是个标准的「设置-计算-读取」模式。

⚠️ 避坑指南:我曾经在修改代码时,忘了调用setVehicleState,结果位置控制器拿到的全是零值。飞机一解锁就猛往前窜,差点撞墙。记住:update之前,一定要把状态喂进去!

1.5 位置控制器的运行频率

默认情况下,位置控制器跑在50Hz。为什么是这个值?

  • 传感器限制:GPS典型更新率就是5~10Hz,EKF2输出位置估计也就50Hz左右
  • 执行器限制:姿态控制器跑250~400Hz,位置环没必要更快
  • 计算资源:50Hz意味着20ms算一次,留给其他模块足够时间

当然,如果你用视觉定位(比如T265相机),位置更新率能到200Hz。这时候把位置环提到100Hz也是可以的。我有个项目就是这么干的,悬停精度从±30cm降到了±5cm。

1.6 小结

这一章咱们把位置控制器的位置、数据流、接口、代码结构都过了一遍。说白了,它就是飞控系统里承上启下的那个模块——上面接任务规划,下面接姿态控制。理解了这个框架,后面改代码你才知道动哪里、不动哪里。

嗯,内容就这些。下一章咱们会深入位置环的数学推导和参数整定,到时候拿实际飞行数据说话。


公众号:蓝海资料掘金营,微信deep3321