中级

飞行工程师

从「玩」到「理解」的进阶之旅

适合初中/高中生,已完成初级飞行体验,想深入了解无人机工作原理并动手修改代码的同学。
学习周期:1-2 个月,每天 1-2 小时。需要 VS Code + ESP-IDF 开发环境。

教材理念

核心:任务驱动,边改边学,通过修改代码和调参,理解无人机的「大脑」如何工作。

结构:从「看懂代码」→「调参优化」→「传感器数据」→「功能扩展」,逐步解锁无人机的更多能力。

阶段项目名称核心技能难度
1我的无人机我定义代码修改、C语言基础⭐⭐
1PID 调参挑战闭环控制、参数优化⭐⭐⭐
2高度计解密传感器数据处理、滤波算法⭐⭐⭐
2姿态魔术师IMU 数据融合、互补滤波⭐⭐⭐
3避障大师传感器接口编程、实时控制⭐⭐⭐⭐
3无线绘图板Wi-Fi 通信、数据可视化⭐⭐⭐⭐

阶段 1:代码入门

项目 01:我的无人机我定义

任务:修改无人机的起飞音效、电机转速范围和 LED 灯效,理解代码结构。

1. 打开项目

解压 starter_code.zip,用 VS Code 打开文件夹。代码结构如下:

  • main.c — 主函数,控制飞行流程
  • buzzer.c — 蜂鸣器控制,负责音效
  • led.c — LED 控制,负责灯效
  • motors.c — 电机控制,负责转速

2. 修改起飞音效

打开 buzzer.c,找到 tone 数组并修改为《欢乐颂》前两句:

// 原始代码:起飞音效 uint16_t tone[] = {440, 880, 440, 0}; // A4, A5, A4, 静音 // 修改为《欢乐颂》前两句 uint16_t tone[] = {330, 330, 392, 392, 440, 440, 392, 0}; // E4, E4, G4, G4, A4, A4, G4

3. 修改电机转速

打开 motors.c,找到并修改 MOTORS_TEST_RATIO 宏:

// 原始:20% 转速 #define MOTORS_TEST_RATIO (uint16_t)(0.2*(1<<16)) // 修改为 30% 转速 #define MOTORS_TEST_RATIO (uint16_t)(0.3*(1<<16))

4. 编译烧录

F1,输入 ESP-IDF: Build 编译项目,然后 ESP-IDF: Flash 烧录到无人机。

知识点

C语言数组、宏定义、ESP-IDF 项目结构。

项目 02:PID 调参挑战

任务:通过调整 PID 参数,让无人机在有风的环境下也能稳定悬停。

PID 控制器代码

打开 controller_pid.c,核心的 PID 更新函数:

typedef struct { float kp; // 比例系数,控制反应速度 float ki; // 积分系数,消除静态误差 float kd; // 微分系数,防止过冲 } PID_t; float pid_update(PID_t* pid, float setpoint, float feedback) { float error = setpoint - feedback; pid->integral += error * dt; float derivative = (error - pid->last_error) / dt; pid->last_error = error; return pid->kp * error + pid->ki * pid->integral + pid->kd * derivative; }

调参指南

默认参数:kp=0.5, ki=0.1, kd=0.2,根据飞行表现调整:

  • 晃动厉害 → 减小 kp
  • 飞不起来 → 增大 kp
  • 有漂移 → 增大 ki
  • 反应迟钝 → 增大 kd
知识点

PID 控制器原理、闭环控制、参数调优方法。

阶段 2:传感器与数据

项目 03:高度计解密

任务:读取气压计数据,计算真实高度,并实现更精准的定高功能。

额外硬件:BMP280 气压计模块(I2C 连接到 GPIO21/22)。

// 修改气压校准 - sensors_bmp280.c void bmp280_init(void) { // 用手机天气 APP 查询当地当前气压 p0 = 100800; // 修改为当地当前气压 (Pa) } // 优化定高 - altitude_hold.c if (fabs(current_altitude - target_altitude) < 0.1) { // 高度差小于 0.1 米,不调整(死区控制) return; }
知识点

气压计原理、高度计算、数据滤波、死区控制。

项目 04:姿态魔术师

任务:读取 IMU 数据,用互补滤波算法计算无人机姿态。

// sensfusion6.c - 互补滤波 void sensfusion6UpdateQ(float gx, gy, gz, ax, ay, az, dt) { // 1. 陀螺仪积分更新姿态(快速但有漂移) // 2. 加速度计校准姿态(准确但易受震动影响) // 3. 互补滤波:融合两者数据 beta = 0.02; // 滤波系数,0-1 之间 }

调整 beta 参数体会效果:beta=0.1(信任加速度计)vs beta=0.01(信任陀螺仪)。

阶段 3:功能扩展

项目 05:避障大师

任务:用超声波传感器实现前方避障功能。额外硬件:HC-SR04 超声波模块(Trig → GPIO18, Echo → GPIO19)。

float ultrasonic_get_distance(void) { // 1. 发送 10us 触发信号 gpio_set_level(TRIG_PIN, 1); ets_delay_us(10); gpio_set_level(TRIG_PIN, 0); // 2. 测量 Echo 高电平持续时间 uint32_t start = 0, end = 0; while (!gpio_get_level(ECHO_PIN)) start = esp_timer_get_time(); while (gpio_get_level(ECHO_PIN)) end = esp_timer_get_time(); // 3. 距离 = 时间 x 声速 / 2 return (end - start) * 0.034 / 2; }

项目 06:无线绘图板

任务:通过 Wi-Fi 将飞行数据回传到电脑,用 Python + Matplotlib 实时绘制曲线。

// wifilink.c - 通过 UDP 发送飞行数据 void wifilink_send_data(float altitude, roll, pitch, yaw) { char buffer[256]; sprintf(buffer, "{\"alt\":%.2f,\"roll\":%.2f,\"pitch\":%.2f,\"yaw\":%.2f}", altitude, roll, pitch, yaw); sendto(sock, buffer, strlen(buffer), 0, (struct sockaddr*)&dest_addr, sizeof(dest_addr)); }

电脑端运行 python plotter.py 即可看到实时飞行数据曲线。

学习建议

  1. 边做边查:遇到不理解的代码,用 VS Code 的「转到定义」功能查看函数实现,或查 ESP-IDF 官方文档。
  2. 记录问题:准备一个笔记本,记录调参过程中的现象和解决方案,形成自己的「调参手册」。
  3. 组队学习:和同学一起做项目,互相讨论问题,分享调参经验。
  4. 挑战升级:每完成一个项目,尝试添加一个小功能。
← 初级教程 高级教程 →