2. PX4概述与开发环境

各位同学,欢迎来到第二章。这一章我们聊聊坐标系。

说实话,我刚入行做飞控那会儿,觉得坐标系这东西太简单了——不就是三个轴嘛。结果第一次调试无人机偏航角的时候,飞机在天上转圈,我在地上抓狂。后来才发现,是坐标系定义搞反了。

嗯,坐标系搞错了,飞机就敢跟你玩漂移。所以这一章,咱们把坐标系这件事彻底讲清楚。

2.1 为什么需要多个坐标系?

你想想看,无人机在空中飞行,需要知道自己在哪里、往哪飞、姿态怎么样。但“位置”和“姿态”是相对的——你得先选一个参考系。

举个例子:

  • 你要告诉飞控“往北飞10米”,这个“北”是相对于地球的,不是相对于机头的。
  • 但你要控制电机转速让飞机抬头,这个“抬头”是相对于飞机本身的。

所以,飞控里至少需要两套坐标系:一套管位置(世界坐标系),一套管姿态(机体坐标系)。

核心概念:坐标系变换的本质,就是把同一个向量在不同参考系下“翻译”出来。飞控里90%的数学运算,都是在做这种翻译。

2.2 世界坐标系(World Frame)

世界坐标系,也叫地球固联坐标系。它的原点通常选在起飞点,或者某个已知的地理位置。

在PX4里,世界坐标系遵循 北-东-地(NED) 约定:

  • X轴:指向正北
  • Y轴:指向正东
  • Z轴:指向地心(向下)

为什么Z轴要向下?我记得第一次看到NED约定时也很疑惑。后来做了一次高度融合实验才明白:因为重力加速度是向下的,Z轴向下可以让重力分量直接取正,省去一个负号。说白了,就是为了计算方便。

坐标系 X轴 Y轴 Z轴 典型用途
世界坐标系(NED) 北 东 地 GPS位置、航点规划
世界坐标系(ENU) 东 北 天 ROS、仿真环境

注意:PX4使用NED,但ROS和很多仿真工具使用ENU(东-北-天)。做仿真时,一定要在数据接口层做转换。我曾经见过一个团队,仿真里飞得好好的,真机一飞就炸——就是因为坐标系没转。

2.3 机体坐标系(Body Frame)

机体坐标系固定在无人机上,跟着飞机一起动。原点在飞机的重心位置。

PX4的机体坐标系约定:

  • X轴:指向机头方向(前进方向)
  • Y轴:指向飞机右侧(右翼方向)
  • Z轴:指向飞机下方(符合右手定则)

这个坐标系有什么用?IMU(惯性测量单元)测量的加速度和角速度,就是基于机体坐标系的。你想啊,加速度计装在飞机上,它测到的“向前加速”是相对于机头的,不是相对于北的。

2.4 导航坐标系(Navigation Frame)

导航坐标系,其实可以理解为世界坐标系的一个“本地版本”。

在PX4里,导航坐标系和世界坐标系基本是同一个东西——都是NED。但严格来说,导航坐标系的原点可以随任务移动,而世界坐标系的原点是固定的。

我个人习惯这样理解:

  • 世界坐标系:起飞点就是原点,整个飞行过程中不变
  • 导航坐标系:用于解算导航方程,原点可以重新对齐(比如做零偏修正时)

实际工程中,你不需要太纠结这个区别。PX4的代码里,local_position 用的就是导航坐标系,原点在起飞点。

2.5 姿态表示:欧拉角与四元数

好了,现在有了两个坐标系,怎么描述飞机相对于世界的姿态?

两种主流方法:欧拉角和四元数。

2.5.1 欧拉角

欧拉角用三个角度来描述姿态:

  • 滚转角(Roll,φ):绕X轴旋转
  • 俯仰角(Pitch,θ):绕Y轴旋转
  • 偏航角(Yaw,ψ):绕Z轴旋转

PX4里,欧拉角的旋转顺序是 Z-Y-X(先偏航,再俯仰,最后滚转)。这个顺序很重要,换一个顺序,结果就完全不一样。

避坑指南:我曾经在写姿态解算时,用了不同的旋转顺序,结果飞机悬停时一直往一边偏。查了两天才发现,是旋转顺序和PX4的约定不一致。所以,做坐标变换前,先确认旋转顺序。

欧拉角有个著名的缺陷——万向锁(Gimbal Lock)。当俯仰角达到±90°时,滚转和偏航会失去一个自由度。对于固定翼飞机,这可能是致命的。

2.5.2 四元数

四元数用四个数来表示旋转,没有万向锁问题。形式是:

q = w + x*i + y*j + z*k

其中 w 是实部,x, y, z 是虚部。满足 w² + x² + y² + z² = 1。

PX4内部全部使用四元数。为什么?

  • 没有万向锁
  • 插值平滑(做姿态控制时很重要)
  • 计算效率高(只有乘法和加法,没有三角函数)

但四元数对人类不友好。你看到 [0.707, 0, 0.707, 0],能想象出飞机是什么姿态吗?反正我不能。所以调试时,我们会把四元数转成欧拉角来看。

2.6 坐标变换矩阵

坐标变换矩阵,就是把一个向量从一个坐标系“搬”到另一个坐标系。

从机体坐标系到世界坐标系的旋转矩阵(用欧拉角表示):

R = Rz(ψ) * Ry(θ) * Rx(φ)

其中:
Rz(ψ) = [cosψ  -sinψ  0]
         [sinψ   cosψ  0]
         [0      0     1]

Ry(θ) = [cosθ   0   sinθ]
         [0      1   0  ]
         [-sinθ  0   cosθ]

Rx(φ) = [1   0      0   ]
         [0   cosφ  -sinφ]
         [0   sinφ   cosφ]

用四元数表示旋转矩阵会更简洁。PX4里用的是这个公式:

R = [1-2(y²+z²)   2(xy-wz)     2(xz+wy)   ]
    [2(xy+wz)     1-2(x²+z²)   2(yz-wx)   ]
    [2(xz-wy)     2(yz+wx)     1-2(x²+y²) ]

嗯,公式看着复杂,但代码里就是几行乘加运算。你不需要背,知道怎么用就行。

2.7 PX4中的坐标系约定

最后,我们把PX4里的坐标系约定总结一下。这部分是硬规则,写代码时必须遵守:

模块 使用的坐标系 姿态表示 备注
位置估计(EKF2) NED(世界) 四元数 内部全部用四元数
姿态估计 机体→世界 四元数 输出给控制模块
控制模块 机体坐标系 四元数/欧拉角 调试时转欧拉角
GPS驱动 NED — 经纬度转本地坐标
MAVLink通信 NED 欧拉角 地面站显示用

关键点:PX4内部统一使用NED + 四元数。所有外部输入(如GPS、磁力计)都会被转换到这个统一框架下。你写自定义模块时,也要遵守这个约定。

2.8 知识体系总览

下面这张图,把本章的核心逻辑串起来了:

坐标系与变换知识体系 世界坐标系 NED(北-东-地) 机体坐标系 前-右-下 导航坐标系 本地NED,原点可移动 姿态表示 四元数 / 欧拉角 坐标变换矩阵 机体 → 世界 的旋转 PX4坐标系约定 统一NED + 四元数 核心逻辑:所有传感器数据最终统一到NED+四元数框架下,供EKF和控制模块使用

这张图你看懂了吗?从上往下看:世界坐标系和机体坐标系是基础,导航坐标系是世界坐标系的本地化版本,姿态表示描述两者的相对关系,坐标变换矩阵完成数学转换,最后全部统一到PX4的约定框架里。