聚丰项目 > 基于wifi通信控制的四旋翼控制系统

基于wifi通信控制的四旋翼控制系统

采用STM32F401RE做为四旋翼的控制器,EMW3080Wi-Fi模块作为四旋翼与外面设备的通信装置,执行器采用无刷电机,姿态传感器采用MPU6050模块,无线控制装置可用手机或电脑。控制算法暂定采用串级PID控制,外环控制角度,内环控制角速度。后期可做优化,滤波采用互补滤波。

h1654155952.9197 h1654155952.9197

分享
0 喜欢这个项目
团队介绍

h1654155952.9197 h1654155952.9197

团队成员

施超宇 总体设计

分享
项目简介
采用STM32F401RE做为四旋翼的控制器,EMW3080Wi-Fi模块作为四旋翼与外面设备的通信装置,执行器采用无刷电机,姿态传感器采用MPU6050模块,无线控制装置可用手机或电脑。控制算法暂定采用串级PID控制,外环控制角度,内环控制角速度。后期可做优化,滤波采用互补滤波。
硬件说明

硬件结构主要由5个部分组成,主控制器STM32f401-Nucleo是四旋翼飞行器的大脑控制整个系统,借助WiFiEMW3080模块进行通信,MPU6050作为获取四旋翼飞行器姿态信息的传感器,四个无刷电机作为四旋翼飞行器的执行器,四旋翼机架采用450机架,其结构图如下图所示:

结构图.png

1STM32F401RET6微控制器,基于ARM Cortex-M4处理器,带DSP,最高支持84MHz主频

2支持Arduino UNO R3 Shield扩展板,微控制器所有IO口引脚通过排针座引出ST-LINK/V2-1调试器,支持对外部微控制器调试3LED一个USB通讯LED、一个电源LED、一个用户LED;两个机械按键:复位、用户USB接口的3个不同功能:虚拟串口、容量存储、调试接口

33种不同供电方式:mini USB接口供电、IO引脚用电、通过Arduino UNO R3 Shield接口供电

4支持KeilIARembed在线IDE的设计工具

5STM32F401 Nucleo开发板包含了STM32F系列板卡惯有的机械按键、LED指示灯、mini USB调试接口,众多IO口外设通过排针座引出等功能,除此之外,也有与众不同之处,如兼容Arduino Shield接口,并且可以通过Arduino Shield扩展接口给板卡供电,板卡搭载了STM32F401RET6核心微控制器,基于32位的高性能ARM Cortex-M4处理器,带FPU单元,最高能支持84MHz主频,见下图。

 

stm32f401.png 

 

 

电调采用大唐宏运30A

电调.jpg 

 

无刷电机采用2212/920KV

 无刷电机.jpg

 

无线模块采用EMW3080

1EMW3080是单3.3V供电的、集成Wi-FiCortex-M4F MCU的嵌入式Wi-Fi模块,最高支持133M主频和256K RAM,强大的浮点运算EMW3080(B):无内部加密芯片,Memory、外设接口资源丰富,能满足大部分应用需求和多云的要求

无线.jpg 


软件说明


四旋翼飞行器控制系统是一个对耦合度要求高、欠驱动、需要较高的控制准确性与实时性的控制系统,四旋翼飞行器控制系统在姿态方面主要由横滚角(Roll)、俯仰角(Pitch)、偏航角(Yaw)、三轴角速度与油门(thrust)这几个控制量体现,四旋翼飞行器的整个控制系统采用串级PID控制系统,,如图所示,内环控制角速度,用于对飞行器的三个轴的角速度控制,外环控制角度,用于对飞行器的姿态控制。利用四旋翼四个电机各姿态角分量叠加关系得出PWM波输出值来控制每个电机转动速度。

 

下图为利用simulink对四旋翼飞行器做的仿真框图,采用的是串级PID控制。

simulink仿真.png 

利用MatlabGUI界面设计做的一个可视化仿真调试界面进行相应的仿真调试,如图所示,其中Ch1Ch2Ch3Ch4通道分别对应四旋翼rollpitchthrustyaw的设定。当设定四旋翼向右翻滚时,四旋翼绕x轴旋转的方向增大,如下图Gryroscope窗口下的蓝色曲线。加速度由突然增大到趋于平稳来进行自平稳校准,如Accelerometer窗口下的红色曲线和绿色曲线。

GUI.png

仿真曲线.png

 

Nucleo模块程序采用Mbed开发,数据采集计算以及PWM赋值主要在定时器中断中执行,main函数代码如下:

int main(void)

{

  SystemInit();        //系统初始化

delay_ms(50);

InitMPU6050();   //MPU6050初始化

delay_ms(50);

Get_offsets();  //机体坐标矫正

   for(pre_cnt=0;pre_cnt<FILTER_NUM;pre_cnt++)

   {

     Prepare_Data();

   }

while(1)

{

  

}  

 }

姿态传感器进行的滤波处理算法采用互补滤波,代码如下:

void imuUpdate(Axis3f acc, Axis3f gyro, state_t *state , float dt) /*数据融合 互补滤波*/

{

float normalise;

float ex, ey, ez;

float q0s, q1s, q2s, q3s; /*四元数的平方*/

static float R11,R21;  /*矩阵(1,1),(2,1)*/

static float vecxZ, vecyZ, veczZ; /*机体坐标系下的Z方向向量*/

float halfT =0.5f * dt;

Axis3f tempacc =acc;

 

gyro.x = gyro.x * DEG2RAD; /* 度转弧度 */

gyro.y = gyro.y * DEG2RAD;

gyro.z = gyro.z * DEG2RAD;

 

/* 某一个方向加速度不为0 */

if((acc.x != 0.0f) || (acc.y != 0.0f) || (acc.z != 0.0f))

{

/*单位化加速计测量值*/

normalise = invSqrt(acc.x * acc.x + acc.y * acc.y + acc.z * acc.z);

acc.x *= normalise;

acc.y *= normalise;

acc.z *= normalise;

 

/*加速计读取的方向与重力加速计方向的差值,用向量叉乘计算*/

ex = (acc.y * veczZ - acc.z * vecyZ);

ey = (acc.z * vecxZ - acc.x * veczZ);

ez = (acc.x * vecyZ - acc.y * vecxZ);


/*误差累计,与积分常数相乘*/

exInt += Ki * ex * dt ;  

eyInt += Ki * ey * dt ;

ezInt += Ki * ez * dt ;


/*用叉积误差来做PI修正陀螺零偏,即抵消陀螺读数中的偏移量*/

gyro.x += Kp * ex + exInt;

gyro.y += Kp * ey + eyInt;

gyro.z += Kp * ez + ezInt;

}

/* 一阶近似算法,四元数运动学方程的离散化形式和积分 */

q0 += (-q1 * gyro.x - q2 * gyro.y - q3 * gyro.z) * halfT;

q1 += (q0 * gyro.x + q2 * gyro.z - q3 * gyro.y) * halfT;

q2 += (q0 * gyro.y - q1 * gyro.z + q3 * gyro.x) * halfT;

q3 += (q0 * gyro.z + q1 * gyro.y - q2 * gyro.x) * halfT;


/*单位化四元数*/

normalise = invSqrt(q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3);

q0 *= normalise;

q1 *= normalise;

q2 *= normalise;

q3 *= normalise;

/*四元数的平方*/

q0s = q0 * q0;

q1s = q1 * q1;

q2s = q2 * q2;

q3s = q3 * q3;


R11 = q0s + q1s - q2s - q3s; /*矩阵(1,1)*/

R21 = 2 * (q1 * q2 + q0 * q3); /*矩阵(2,1)*/

 

/*机体坐标系下的Z方向向量*/

vecxZ = 2 * (q1 * q3 - q0 * q2);/*矩阵(3,1)*/

vecyZ = 2 * (q0 * q1 + q2 * q3);/*矩阵(3,2)*/

veczZ = q0s - q1s - q2s + q3s; /*矩阵(3,3)*/


if (vecxZ>1) vecxZ=1;

if (vecxZ<-1) vecxZ=-1;


/*计算roll pitch yaw 欧拉角*/

state->attitude.pitch = -asinf(vecxZ) * RAD2DEG;

state->attitude.roll = atan2f(vecyZ, veczZ) * RAD2DEG;

state->attitude.yaw = atan2f(R21, R11) * RAD2DEG;


if (!isCalibrated) /*校准*/

{

baseZacc = tempacc.x* vecxZ + tempacc.y * vecyZ + tempacc.z * veczZ;

isCalibrated = true;

}

state->acc.z= tempacc.x* vecxZ + tempacc.y * vecyZ + tempacc.z * veczZ - baseZacc; /*Z轴加速度(去除重力加速度)*/

}

Andorid控制界面:

摇杆.png

 

 


演示效果


评论区(0 )