这是一种方便简单且学习周期短的的无人机自动驾驶方案,
简单到只用配置串口输出就行
针对与无人机的自动化驾驶有两种方案,
第一种是从底层飞控开始,例如PIX飞控,但是从环境安装到最后的功能实现都非常的麻烦.
第二种方案是通过模拟遥控器输出信号进行的自动化控制,这种方法不需要对飞控底层进行研究.
不管哪一种从零开始都还是比较麻烦的.
但是我无意从同学那里发现了一个可以更快实现自动化方案,
在这里使用的是HC-SR04超声波以及STC15W408AS
目录
一丶原理图
二丶使用器材介绍
三丶源码
主函数2.0
四丶实物图
五丶项目下载
一丶原理图
代码结构原理图
设备接线示意图
二丶使用器材介绍
HC-SR04超声波
大致原理就是发射40kHz的脉冲然后接收,然后我们只需要读取他T端口返回的高电平时间然后计算得到实际距离,不过这里要说一下我们在实际飞行的时候会发现数据返回错误试试了很多次最后发现是因为飞机的振动导致超声波模块返回数据的错误所以需要做一个减震处理,这里建议用泡沫粘上去就可以了.
15W80AS单片机
注意这款单片机和51有点不一样 他,没有串口1,所以在配置的时候需要查阅一下资料
YF-SMART外置平台
使用方法就是利用串口给他发送指令然后他就会控制飞控进行全自动飞行了,有手动控制模式只需要切换遥控器的通道就可以了,我的这款是搞活动的试用款在手动飞行的时候还是能感觉到有一点的油门死区的.需要注意的就接线和他的供电,理论来说它可以适用于任何飞控但是有些飞控没有给他供电的地方所以需要自己购买一个降压模块.
旋翼机
我们这里用的是乐迪的miniPIX飞控 用的固件是APM的
对飞控没有限制,其他的都和其他四旋翼没有什么区别基本
三丶源码
串口和定时器的初始化配置
先看代码
/*
开发者邮箱
@m.t-chen@foxmail.com
串口定时器配置
*/
#include "stc15.h"
#include "set.h"
bit busy;
uint Time_flag =0; //定时器溢出标志位
void UartInit(void) //9600bps@11.0592MHz
{
IE |= 0x90; // 总中断开关 和串口中断开关
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x01; //串口1选择定时器2为波特率发生器
AUXR &= 0xFB; //定时器2时钟为Fosc/12,即12T
T2L = 0xE8; //设定定时初值
T2H = 0xFF; //设定定时初值
AUXR |= 0x10; //启动定时器2
}
void Timer0Init(void)
{
TMOD |= 0x01;
ET0 = 1;
TH0 = 0;
TL0 = 0;
TF0 = 0;
TR0 = 0;
ET0=1; //打开定时器0中断允许
}
void timer0_isr() interrupt 1 //定时器中断
{
TH0 = 0;
TL0 = 0;
Time_flag++;
}
void Uart() interrupt 4
{
if(RI) //接收数据,手动将RI清0
{
RI=0;
}
if(TI)
{
TI=0;
busy=0;
}
}
void UartSend(char dat)
{
SBUF = dat;
while (busy);
busy = 1;
}
void UartSendStr(char *p)
{
while (*p)
{
UartSend(*p++);
}
}
因为我这里使用的芯片是STC15W408AS
注意:15W408AS没有定时器1,且这款芯片同时是有内部晶振并且可调频率 这里是11.0592
所以我用定时器2作为的串口波特率发生器,定时器0用来计时超声波
超声波启动和距离计算
先看代码
/*
开发者邮箱
@m.t-chen@foxmail.com
超声波算法
*/
#include "stc15.h"
#include "set.h"
#include "intrins.h"
sbit Trig=P5^4; //超声波发送端
sbit Echo=P5^5; //超声波接收端
///
uint time=0; //超声波返回高电平时间
int distance=0; //距离
//
extern uint Time_flag;
unsigned char hcsr04_cm[8]="0000\r\n";
void Start_hcsr04(void) //初始化超声波
{
Trig=0;
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
Trig=1;
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
Trig=0;
}
void Data_Handler(void) //计算距离
{
time=(TH0*256+TL0)+(Time_flag*65536); //获取返回来的高电平时间
Time_flag=0;
TH0=0;
TL0=0;
distance=(time*1.7)/100; //计算距离 单位CM
}
int date_hcsr04(void) //读取超声波数据并返回距离
{
distance=0;
Start_hcsr04(); //启动超声波
while(!Echo); //判断是否反馈数据
TR0=1;
while(Echo); //判断舒服结束
TR0=0;
Data_Handler(); //处理数据
串口输出距离
// hcsr04_cm[0] = distance / 1000 +0x30; /
// hcsr04_cm[1] = distance / 100%10 +0x30; /
// hcsr04_cm[2] = distance % 100/10 +0x30; /
// hcsr04_cm[3] = distance % 10 +0x30; /
// UartSendStr(hcsr04_cm); /
/
return distance;
}
注意:我们的晶振设置的是11.0592所以我们的一个机器周期并不是1us所以会存在一定的误差.不影响使用,较真的同学可以设置成12M
distance=(time*1.7)/100; 这一段代码1.7是因为声速340M/S 超声波从发射到接收就会X2
所以 340/2 =170 转换单位到CM 所以1.7
延时函数
/*
开发者邮箱
@m.t-chen@foxmail.com
延时函数 控制输出频率
*/
#include "stc15.h"
#include "set.h"
#include "intrins.h"
void Delay500ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 22;
j = 3;
k = 227;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
主函数
先看代码
/*
开发者邮箱
@m.t-chen@foxmail.com
此文件为主函数
需求控制无人机定高1M
低了上升,高了下降.
*/
#include "stc15.h"
#include "intrins.h"
#include "set.h"
#include "math.h"
unsigned char order[12]="$VU,00*\r\n"; //控制指令
long Kp = 160; //比例
long Kd = 50; //微分
int sr04cm = 0;
int sr04cm2 = 0;
int sr04cm3 = 0;
void uart_out() //最终结果输出
{
uint speed = 0;
int date = 0;
sr04cm3 = sr04cm2;
sr04cm2 = sr04cm;
sr04cm = date_hcsr04()-100; //接收超声波数据
控制方向指令///
if(sr04cm>0) order[2] = 'D'; //大于等于1M
else if(sr04cm<=0) order[2] = 'U'; //小于1M
PD算法
date = ((Kp*sr04cm)/1000)+((Kd*(sr04cm3-sr04cm))/1000);
///速度最大限幅//
if(date>9) date = 9;
else if(date<-9) date = 9;
//控制速度///
order[5] = abs(date)+0x30;
指令输出/
UartSendStr(order);
}
void main()
{
UartInit();
Timer0Init();
while(1)
{
uart_out();
Delay500ms(); //控制输出间隔
}
}
这里简单的使用了PD算法来保证无人机速度平稳且不会"左右摆动"
最后测试高度小于1M然后一直减少高度输出的指令速度会随着距离改变
现在条件满足我们开始做有避障版本的自动驾驶
主函数2.0
先看代码
/*
开发者邮箱
@m.t-chen@foxmail.com
此文件为主函数
需求控制无人机定高1.5M
低了上升,高了下降.
*/
#include "stc15.h"
#include "intrins.h"
#include "set.h"
#include "math.h"
unsigned char order[12]="$VA,00*\r\n"; //控制指令
long Kp = 100; //比例
long Kd = 50; //微分
int sr04cm = 0;
int sr04cm2 = 0;
int sr04cm3 = 0;
void uart_out() //最终结果输出
{
uint speed = 0;
int date = 0;
sr04cm3 = sr04cm2;
sr04cm2 = sr04cm;
sr04cm = date_hcsr04()-150; //接收超声波数据
控制方向指令///
if(sr04cm>0) order[2] = 'A'; //大于等于1M
else if(sr04cm<=0) order[2] = 'B'; //小于1M
PD算法
date = ((Kp*sr04cm)/1000)+((Kd*(sr04cm3-sr04cm))/1000);
///速度最大限幅//
if(date>9) date = 9;
else if(date<-9) date = 9;
//控制速度///
order[5] = abs(date)+0x30;
//指令输出/
// UartSendStr(order);
if(order[2] == 'A')
{
order[5] = 6+0x30; //默认前进速度
UartSendStr(order);
}
else if(order[2] == 'B')
{
UartSendStr(order);
}
}
void main()
{
UartInit();
Timer0Init();
while(1)
{
uart_out();
Delay500ms(); //控制输出间隔
}
}
这个版本主要是修改了默认方向,其次是增加了一个判断 如果是大于1.5M无人机前进速度始终为6
因为这款超声波最大测距4M 所以大于4M的值是不可靠的 所以我们吧前进速度改为常量6.遇见障碍后退依然保留原来的PD算法
从 UD(上下) 改为AB(前后) 前方1.5M有障碍停止 障碍小于1.5M后退
测试效果
四丶实物图
注:以下操作比较硬核
降压模块
因为飞控给的电压不够这么多器件所以加了一个降压模块来保证模块的正常工作
没有合适的焊台所以丑了一点
接收机
这里我们用的接收机是富斯16x的接收机 ,注意不是每种遥控器和接收机都可以直接使用
需要配置模式,一般来说有 ibus,sbus,ppm,pwm模式 ,我们这里一定要选择成为ppm模式很重要!
YF-SMART&&PPM板
按照说明上给的指示直接接线就好了
PPM板就是吧 YF-smart输出的8通PWM转换成PPM然后输出给飞控
STC15W408AS&&HC-SR40
吧YF-SMART的TR串口接到STC15W408AS芯片的RT串口上,让他可以接收我们设置的指令
(飞行计划)
HC-SR40超声波接入到我们设置芯片上的IO口就行
最后测试一下是否可以正常切换
最终的组装成品and演示效果
最后虽然实现了定点避障效果,但是本身用来自动驾驶的飞机稳定性不够,还是会晃动效果只能说一般般吧
建议在调试KD值的时候选择无风且保证飞机组装和稳定的情况下调试.
五丶项目下载
注意事项
做自动驾驶的飞机本身必须要足够稳定
最后结果和飞机本身的稳定性有很大的关联,其次超声波这种传感元件需要给他做减震处理
室内测试请不要上桨!!!!室内测试请不要上桨!!!室内测试请不要上桨!!! 安全第一
此项目所有源码,包括元器件的文档参数.
点击下载