3. 航点数据结构:把飞行指令翻译成机器能懂的语言
做航点规划,说白了就是给无人机写一份「飞行剧本」。但无人机不像人,它听不懂「飞到那个山头拍张照」这种话。你得把每个动作拆成结构化的数据——这就是航点数据结构存在的意义。
我个人习惯把航点比作「路书上的一个站点」。每个站点不光有位置,还有到了之后要干什么、怎么干。今天我们就来拆开这个结构,看看里面到底装了些什么。
3.1 航点结构体定义:最基本的积木块
不管用哪个厂商的SDK,航点结构体的骨架都差不多。我拿一个典型的定义来举例:
typedef struct {
double latitude; // 纬度,单位度
double longitude; // 经度,单位度
float altitude; // 海拔高度,单位米
float heading; // 航向角,单位度,0=正北
uint16_t stay_time; // 停留时间,单位秒
uint8_t action_count; // 动作数量
Action actions[8]; // 动作列表,最多8个
uint8_t speed; // 到达该点的速度百分比
uint8_t 转弯模式; // 0=直线,1=曲线
} Waypoint;
嗯,这里要注意:转弯模式这个字段,不同厂家叫法不一样。大疆叫「转弯模式」,Pixhawk系统里叫「转弯半径」。但本质都一样——控制飞机怎么从一个点过渡到下一个点。
核心要点:航点结构体是「位置 + 行为 + 控制参数」的三元组。缺了任何一个,任务执行都可能出问题。
3.2 航点属性:经纬度、海拔、航向角、停留时间
这四个属性是航点的「身份证」。咱们一个一个说。
3.2.1 经纬度(Latitude / Longitude)
这个不用多解释,地球上的坐标。但有个坑——精度问题。我曾经在项目里用float存经纬度,结果飞到几百米外才发现位置偏了。为什么?float只有7位有效数字,经纬度的小数点后第6位代表约0.1米的误差。你想想看,累积几个点之后,航线就歪了。
我的建议:经纬度一律用double,别省那4个字节。
3.2.2 海拔高度(Altitude)
这里有个容易混淆的概念:相对高度 vs 绝对高度。
| 类型 | 参考基准 | 典型场景 | 注意事项 |
|---|---|---|---|
| 相对高度 | 起飞点 | 低空巡检、贴近拍摄 | 起飞点变化,航线就废了 |
| 绝对高度 | 海平面(MSL) | 测绘、跨区域飞行 | 需要高精度DEM数据 |
| 气压高度 | 标准气压面 | 应急备份 | 受天气影响大,误差可达几十米 |
我个人习惯在航点结构体里加一个altitude_type字段,明确告诉飞控用哪个基准。不然你在地面站看到的高度和飞机实际飞的高度,可能根本不是一回事。
3.2.3 航向角(Heading)
航向角决定了飞机机头指向哪里。0度是正北,顺时针增加。但这里有个细节——航向角 ≠ 飞行方向。
举个例子:飞机从A点飞向B点,飞行方向是90度(正东)。但如果你想让相机始终对准北边的目标,航向角就得设成0度。说白了,航向角控制的是「脸朝哪」,不是「往哪走」。
小技巧:在测绘任务中,我通常把航向角设成与航线方向垂直。这样相机扫过的覆盖范围最大,重叠率也最均匀。
3.2.4 停留时间(Stay Time)
这个字段看似简单,但用不好会出大问题。我曾经见过一个新手,把每个航点的停留时间都设成10秒。结果一条50个点的航线,光悬停就花了8分钟,电池全耗在等待上了。
什么时候该设停留时间?
- 拍照任务:等飞机稳定后再拍,一般2-3秒足够
- 变焦或对焦:相机需要时间调整,5-8秒比较稳妥
- 云台调整:如果云台要转大角度,留3-5秒
- 纯过点:停留时间设为0,飞机直接飞过不停留
3.3 航点动作:让无人机不只是飞过去
光有位置属性,飞机只能做「空中公交车」。真正让航点任务有价值的,是动作系统。
3.3.1 拍照动作
最常见的动作,没有之一。但拍照也分好几种:
typedef enum {
ACTION_SINGLE_SHOT, // 单拍
ACTION_BURST_SHOT, // 连拍(3/5/7张)
ACTION_AEB, // 包围曝光
ACTION_INTERVAL, // 定时拍(配合航线速度)
ACTION_HDR, // HDR合成
} PhotoAction;
我个人最常用的是单拍 + 定时拍的组合。单拍用于关键点位(比如塔顶),定时拍用于航线中间的连续覆盖。你想想看,如果每个点都单拍,航线速度会被频繁打断,效率很低。
3.3.2 变焦动作
变焦是巡检任务的刚需。但变焦动作有个坑——变焦速度。我曾经在项目里直接设了一个目标焦距,结果相机「唰」一下变过去,画面剧烈抖动,拍出来的照片全是糊的。
正确的做法:把变焦拆成多个步骤,每个步骤只变一点点。比如从24mm变到120mm,可以拆成24→35→50→70→120,每步之间留1秒稳定时间。
警告:变焦过程中不要同时触发拍照。相机的ISP(图像信号处理器)在变焦时负载很高,这时候拍照容易丢帧或出现坏点。先变焦,等稳定了再拍。
3.3.3 云台控制
云台控制是航点动作里最灵活,也最容易出错的。控制参数通常包括:
| 参数 | 范围 | 说明 |
|---|---|---|
| pitch(俯仰) | -90° ~ +30° | 负值向下,正值向上 |
| yaw(偏航) | -180° ~ +180° | 相对机头或绝对角度 |
| roll(横滚) | -45° ~ +45° | 大部分任务用不到 |
| speed(速度) | 1 ~ 100 | 云台转动速度百分比 |
| mode(模式) | 0/1 | 0=绝对角度,1=相对角度 |
这里有个容易忽略的点:云台偏航和飞机航向角的关系。如果你设了云台偏航为绝对角度30度,但飞机航向角也在变,云台会一直「追」那个绝对方向。结果就是云台电机一直在微调,画面反而晃来晃去。
我的经验:除非有特殊需求,否则云台偏航用相对模式,跟着机头走。这样飞机转弯时,云台和机身的相对关系不变,画面最稳定。
3.4 航点数据结构总览图
下面这张图把整个航点数据结构的层次关系画清楚了。你可以把它当作「航点任务的数据字典」来用。
3.5 实战中的避坑指南
最后,分享几个我在项目中踩过的坑,希望能帮你少走弯路。
坑1:经纬度精度丢失
我曾经用float存经纬度,结果在1000米外的航点偏差了2米。排查了一天才发现是数据类型的问题。从此以后,所有经纬度一律用double。
坑2:海拔基准不统一
有一次在山区做测绘,地面站显示高度50米,但飞机实际离地只有30米。后来发现地面站用的是相对高度(以起飞点为基准),而飞控用的是绝对高度(以海平面为基准)。两者差了20米,因为起飞点本身海拔就有20米。
坑3:动作执行顺序
航点动作是按顺序执行的。如果你先变焦再拍照,没问题。但如果你先拍照再变焦,拍到的照片就是变焦前的画面。这个逻辑看起来简单,但我在项目里见过有人把顺序搞反,结果拍了一堆模糊的照片。
嗯,航点数据结构就讲到这里。说白了,它就是一份「飞行 + 拍摄」的详细说明书。把每个字段理解透,你的航点任务就成功了一半。