DIY编程器网

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1958|回复: 1
打印 上一主题 下一主题

[待整理] 四旋翼飞行器的设计

[复制链接]
跳转到指定楼层
楼主
发表于 2015-5-2 10:43:19 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
  近年来,随着航模爱好者的增加,越来越多的航模爱好者投向了四轴飞行器,也即四旋翼。四旋翼在设计时可分为十字模式和X 模式,通过改变螺旋桨的转速来使四旋翼进行俯仰、滚转、偏航三种基本的运动。十字模式较为简单,每次只改变一个轴上的两个桨的转速,而X 模式是通过改变四个桨的转速来改变四旋翼的运动姿态,所以X 模式的四旋翼可以进行更为精细的调节。四旋翼的发展不仅是因为它的价格达到了大众可以接受的范围,而且它的技术能被越来越多的人掌握。我们现在所设计的便是通过经典的PID 来控制四旋翼的飞行。
  此次设计四旋翼采用的是十字模式,用六通遥控器来进行控制,选用的机架是F450 的机架、十寸桨1045 和1000kv 的无刷电机。接下来就是进行飞控板的设计,我们选用的是瑞萨的R5F100LEA 芯片和串口6 轴加速度计/ 陀螺仪MPU6050 模块,在无线模块的选用中我们也使用了串口无线,这样降低了设计的难度,同时也使程序的编写更加简洁。
  首先添加头文件, 然后定义滚转俯仰偏航的PID 参数、积分定义,定义四个电机输出参数、运动控制量参数(如最小油门的预定义)、姿态角度参数、校验参数、串口协议参数( 主要定义输入输出的帧头帧尾和所需数组长度)、 主循环时间参数。
  以下是主要的程序源码:void main(void)
  
    {
     R_MAIN_UserInit();
     Delay_Ms(2000);
     while (1U)
     {
     Delay_Ms(5); //P13.0 =~P13.0;
     //------------ 校验位判断----------------//
     s u m _
  acc=0x55+0x51+imu_buff [0]+imu_buff
  [1]+imu_buff [2]+imu_buff [3]+imu_buff
  [4]+imu_buff [5]+imu_buff [6]+imu_buff [7];
     s u m _
  gry=0x55+0x52+imu_buff [9]+imu_buff[10]+imu_buff [11]+imu_buff [12]+imu_buff[13]+imu_buff [14]+imu_buff [15]+imu_buff [16];
     s u m _ang=0x55+0x53+imu_buff [18]+imu_buff
  [19]+imu_buff [20]+imu_buff [21]+imu_buff
  [22]+imu_buff [23]+imu_buff [24]+imu_buff [25];
     if((check_acc==sum_acc)&&(check_gry==sum_gry)&&(check_ang==sum_ang))
     {
     check_ok=1;
     }
     //-------- 以下为接收控制变量--------//
     if(uart0_receiveend == 1)
  // 如果控制数据接收已经完成
     {
     u a r t 0 _receiveend = 0; // 接收读取,接收完成清零
     i f ( ( u a r t 0 _control[0] == 0x55) && (uart0_control[14] ==0xEB))// 协议校验正确
     { time_s=0;
  //1s 中断循环次数
     rc_thr =
  uart0_control[1];rc_rol = uart0_control[2];   rc_pit = uart0_control[3];rc_yaw = uart0_control[4];
     pid_rol_p =pid_rol_p_begin+uart0_control[8];pid_rol_i =pid_rol_i_begin+uart0_control[6];pid_rol_d =pid_rol_d_begin+uart0_control[10];
     pid_pit_
  p=pid_pit_p_begin+uart0_control[8];pid_pit_i=pid_pit_i_begin+uart0_control[9];pid_pit_d =pid_pit_d_begin+uart0_control[10];
    pid_yaw_p = pid_yaw_p_begin+uart0_control[11];pid_yaw_d =pid_yaw_d_begin+uart0_control[12];
    Power=uart0_control[13];
     }
     }
  //-------- 以下为姿态数据换算--------//
    acc_x = (imu_buff[1] * 256) + (imu_buff[0]); // 从数组转换ACC 数据
    acc_x = acc_x / 32768.0 * 16;
  acc_y = (imu_buff[3] * 256) + (imu_buff[2]);
    acc_y = acc_y / 32768.0 * 16;
    acc_z = (imu_buff[5] * 256) + (imu_buff[4]);
    acc_z = acc_z / 32768.0 * 16;gryo_x = (imu_buff[10] * 256) + (imu_buff[9]); // 从数组转换GRYO 数据
    gryo_x = gryo_x / 32768.0 * 2000;
    gryo_y = (imu_buff[12] * 256) + (imu_buff[11]);
    gryo_y = gryo_y / 32768.0 * 2000;
    gryo_z = (imu_buff[14] * 256) + (imu_buff[13]);
    gryo_z = gryo_z / 32768.0 * 2000;
    angle_x = (imu_buff[19] * 256) +(imu_buff[18]); // 从数组转换ANGLE 数据  
  angle_x = angle_x / 32768.0 * 180;
    angle_y = (imu_buff[21] * 256) +(imu_buff[20]);
    angle_y = angle_y / 32768.0 * 180;
    angle_z = (imu_buff[23] * 256) +(imu_buff[22]);
    angle_z = angle_z / 32768.0 * 180;
     //--------I 的计算----------// 积分值i 限制在200 以内 且缩小2 倍
     integral_x+=angle_x;
     integral_y+=angle_y;
     integral_z+=angle_z;
  if(pid_rol_i*integral_x*0.1>50) integral_x_sum=50;
     else if (pid_rol_i*integral_x*0.1<-50) integral_x_sum=-50;   else integral_x_sum=pid_rol_i*integral_x*0.1;
     if(pid_pit_i*integral_y*0.1>50)integral_y_sum=50;
     else if(pid_pit_i*integral_y*0.1<-50) integral_y_sum=-50;   else integral_y_sum=pid_pit_i*integral_y*0.1 ;
     //-------- 以下为PID计算公式--------//
     p i d _ r o l = ( p i d _ r o l _p*0.08) * (angle_x + rc_rol - 100) +integral_x_sum+(pid_rol_d*0.08) * gryo_x; //PID 计算公式,X 方向GRYO 为反向输出。
  pid_pit = (pid_pit_p*0.08) * (angle_y + rc_pit -100) -integral_y_sum+(pid_pit_d*0.08) * gryo_y; //PID 计算公式,100 为姿态控制中立点.
     pid_yaw = 0;
    moto_x1 = (rc_thr * 15 + (+ pid_rol +pid_yaw));
    moto_x2 = (rc_thr * 15 + (- pid_rol +pid_yaw));
    moto_x3 = (rc_thr * 15 + (+ pid_pit +pid_yaw));
    moto_x4 = (rc_thr * 15 + (- pid_pit +pid_yaw));
    if(moto_x1 > 4000) moto_x1 = 4000;
  if(moto_x1 < 0) moto_x1 = 0;
  if(moto_x2 > 4000) moto_x2 = 4000;
  if(moto_x2 < 0) moto_x2 = 0;
  if(moto_x3 > 4000) moto_x3 = 4000;
  if(moto_x3 < 0) moto_x3 = 0;
  if(moto_x4 > 4000) moto_x4 = 4000;
  if(moto_x4 < 0) moto_x4 = 0;
  if(check_ok==1)
     {
     if((Power !
  =0x90)&&(time_s<2))// 是否按下停机或与遥控器失去联系
     {
     check_ok=0;
     TDR01 =4000 + (unsigned int)moto_x1; //油门基准输出1MS 为4000
    TDR02 = 4000 + (unsigned int)moto_x2; // 油门基准输出1MS 为4000
    TDR03 = 4000 + (unsigned int)moto_x3; // 油门基准输出1MS 为4000
    TDR04 = 4000 + (unsigned int)moto_x4; // 油门基准输出1MS 为4000
     }
     else// 油门小于1.18MS 关闭电机输出
     {
    moto_x1 = 0;moto_x2 = 0;
    moto_x3 = 0;moto_x4 = 0;
    TDR01 = min_thr; TDR02 = min_thr; // 最小输出油门
    TDR03 = min_thr; TDR04 = min_thr; // 最小输出油门
     }
     }
     void R_MAIN_UserInit(void)
    {
     EI();   R_TAU0_Channel0_Start(); // 打开电机PWM 输出计时器   R_TAU0_Channel7_Start(); // 打开ms 定时器中断,系统时间开始
     R_UART0_Start(); // 打开COM0 端口57600-N-8-1
     R_UART1_Start(); // 打开COM1 端口115200-N-8-1   TDR01 = min_thr; TDR02 = min_thr;// 最小输出油门
     TDR03 = min_thr; TDR04 = min_thr;
  // 最小输出油门
    }
  说明:在设计中出现了飞机在调节的过程中突然剧烈摇晃的情况,也即突然过调,于是加入了校验和来校验数据,摈弃错误数据。同时在调节的过程中由于使用的是十字模式,固定一轴的情况下来调节另一轴,必须使四旋翼能够克服它自身的重力,防止它的重力干扰调节出来的PID 参数不能用于飞行的需要。在用串口无线模块来调节的时候,由于通信的延时过于严重,建议用USB 延长线连接串口来进行调节。
  PCB 设计(图1):
  整机实物(图2):


  【参考文献】
  [1] 黄智伟. 全国大学生电子设计竞赛训练教程. 电子工业出版社,2010
  [2] 李晓林. 单片机原理与接口技术. 电子工业出版社,2010
  
  
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
收藏收藏 分享分享 支持支持 反对反对
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|文字版|手机版|DIY编程器网 ( 桂ICP备14005565号-1 )

GMT+8, 2024-4-26 23:36 , 耗时 0.096513 秒, 20 个查询请求 , Gzip 开启.

各位嘉宾言论仅代表个人观点,非属DIY编程器网立场。

桂公网安备 45031202000115号

DIY编程器群(超员):41210778 DIY编程器

DIY编程器群1(满员):3044634 DIY编程器1

diy编程器群2:551025008 diy编程器群2

QQ:28000622;Email:libyoufer@sina.com

本站由桂林市临桂区技兴电子商务经营部独家赞助。旨在技术交流,请自觉遵守国家法律法规,一旦发现将做封号删号处理。

快速回复 返回顶部 返回列表