基于STM32F4核心板的经典项目程序,远比网上搜索的开发板例程更有价值,历时2年时间打造。 ...
里面主要包括pid控制器,无迹卡尔曼滤波UKF,IMU+GPS组合导航,上位机通信,遥控器通信和解码,dma传输,手机蓝牙控制等。里面主要包括pid控制器,无迹卡尔曼滤波UKF,IMU+GPS组合导航,上位机通信,遥控器通信和解码,dma传输,手机蓝牙控制等。基于STM32F4核心板的经典项目程序,远比网上搜索的开发板例程更有价值,历时2年时间打造。基于STM32F4核心板的经典项目程序,远比网上
基于STM32F4核心板的经典项目程序,远比网上搜索的开发板例程更有价值,历时2年时间打造。 适合学生学习,工程师提高技术等等。 项目内容为:用stm32f407单片机核心板和gy-91模块做一个功能强大的四旋翼无人机飞控,程序从零开始做起,简洁而不简单。 里面主要包括pid控制器,无迹卡尔曼滤波UKF,IMU+GPS组合导航,上位机通信,遥控器通信和解码,dma传输,手机蓝牙控制等。 实现无人机垂直起降,定点,轨迹控制等。 商品包括原理图方案,单片机程序及固件,上位机程序及运行环境。

凌晨三点盯着示波器屏幕,突然发现UKF输出的姿态角曲线完美贴合真值那一刻,我抄起手边的冰可乐猛灌两口——这玩意儿终于成了。两年前从淘宝买来STM32F407核心板和GY-91模块时,绝对想不到会被这堆铁疙瘩折磨七百多天。

传感器底层驱动最能体现嵌入式开发的酸爽。看看这段MPU9250的DMA读取代码:
void IMU_DMA_Init() {
HAL_I2C_Mem_Read_DMA(&hi2c1, MPU9250_ADDR, ACCEL_XOUT_H, 1, imu_raw, 14);
HAL_Delay(100);
HAL_NVIC_SetPriority(I2C1_EV_IRQn, 0, 0);
}
表面是简单的I2C读取,实际调试时发现DMA传输完成中断总会比数据就绪晚3ms。最后在DMA回调里硬塞了个微秒级延时才解决,这骚操作教科书上可找不到。

组合导航才是重头戏。UKF的预测更新循环里藏着一堆魔鬼细节:
void UKF::update(Vector3d &acc, Vector3d &gps) {
// Sigma点生成
MatrixXd Xsig = sigma_points();
// 状态预测
predict_sigma(Xsig);
// 测量更新
measurement_update(acc, gps);
// 协方差裁剪
P_ = (P_ + P_.transpose())/2;
}
协方差矩阵不对称会导致数值发散这事,我是在无人机第23次炸机后才意识到的。加上最后那行对称化处理,定位精度直接从5米提升到0.3米。

基于STM32F4核心板的经典项目程序,远比网上搜索的开发板例程更有价值,历时2年时间打造。 适合学生学习,工程师提高技术等等。 项目内容为:用stm32f407单片机核心板和gy-91模块做一个功能强大的四旋翼无人机飞控,程序从零开始做起,简洁而不简单。 里面主要包括pid控制器,无迹卡尔曼滤波UKF,IMU+GPS组合导航,上位机通信,遥控器通信和解码,dma传输,手机蓝牙控制等。 实现无人机垂直起降,定点,轨迹控制等。 商品包括原理图方案,单片机程序及固件,上位机程序及运行环境。

PID调参堪称玄学艺术。飞控核心的PID结构体设计成这样:
typedef struct {
float kp, ki, kd;
float i_term;
float last_err;
uint32_t last_tick;
} FlightPID;
void pid_update(FlightPID* pid, float error) {
uint32_t now = HAL_GetTick();
float dt = (now - pid->last_tick) / 1000.0f;
pid->i_term += error * dt;
float d_term = (error - pid->last_err) / dt;
pid->last_err = error;
pid->last_tick = now;
return pid->kp * error + pid->ki * pid->i_term + pid->kd * d_term;
}
时间戳处理不当会让微分项爆炸,这个坑让我的四轴在实验室画了半个月的死亡圆圈。直到把HAL_GetTick()换成DWT时钟计数才解决。

上位机用PyQt搞了个实时三维姿态显示,数据协议设计才是精髓:
class Protocol:
HEADER = b'\xAA\x55'
def decode(self, data):
if len(data)<18: return
roll = struct.unpack('f', data[2:6])[0]
pitch = struct.unpack('f', data[6:10])[0]
yaw = struct.unpack('f', data[10:14])[0]
return (roll, pitch, yaw)
当发现蓝牙传输丢包导致姿态解算异常时,果断切到DMA双缓冲串口,数据传输率直接飙到921600bps,现在飞控能同时处理六组传感器数据流。

两年间烧过七块主控板,摔烂四副桨叶,最终搞定的这套飞控既能用PS2手柄操控,也能通过手机APP规划航点。看着自己写的代码在200米高空画着8字航线,突然觉得那些通宵改BUG的日子都值了——这大概就是硬核开发的终极浪漫吧。


更多推荐
所有评论(0)