这是一种方便简单且学习周期短的的无人机自动驾驶方案,

简单到只用配置串口输出就行

针对与无人机的自动化驾驶有两种方案,

第一种是从底层飞控开始,例如PIX飞控,但是从环境安装到最后的功能实现都非常的麻烦.

第二种方案是通过模拟遥控器输出信号进行的自动化控制,这种方法不需要对飞控底层进行研究.

不管哪一种从零开始都还是比较麻烦的.

但是我无意从同学那里发现了一个可以更快实现自动化方案,


在这里使用的是HC-SR04超声波以及STC15W408AS


目录

一丶原理图

二丶使用器材介绍 

三丶源码

主函数2.0

四丶实物图

五丶项目下载


一丶原理图

代码结构原理图

python怎么模拟swap_PD算法

python怎么模拟swap_STC15W408AS_02

 设备接线示意图

python怎么模拟swap_STC15W408AS_03

python怎么模拟swap_无人机自动驾驶_04


二丶使用器材介绍 

HC-SR04超声波

 

python怎么模拟swap_PD算法_05

大致原理就是发射40kHz的脉冲然后接收,然后我们只需要读取他T端口返回的高电平时间然后计算得到实际距离,不过这里要说一下我们在实际飞行的时候会发现数据返回错误试试了很多次最后发现是因为飞机的振动导致超声波模块返回数据的错误所以需要做一个减震处理,这里建议用泡沫粘上去就可以了.

15W80AS单片机

python怎么模拟swap_无人机自动驾驶_06

注意这款单片机和51有点不一样 他,没有串口1,所以在配置的时候需要查阅一下资料

YF-SMART外置平台

python怎么模拟swap_无人机自动驾驶_07

python怎么模拟swap_无人机自动驾驶_08

 使用方法就是利用串口给他发送指令然后他就会控制飞控进行全自动飞行了,有手动控制模式只需要切换遥控器的通道就可以了,我的这款是搞活动的试用款在手动飞行的时候还是能感觉到有一点的油门死区的.需要注意的就接线和他的供电,理论来说它可以适用于任何飞控但是有些飞控没有给他供电的地方所以需要自己购买一个降压模块.

旋翼机

我们这里用的是乐迪的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算法来保证无人机速度平稳且不会"左右摆动"

python怎么模拟swap_STC15W408AS_09

最后测试高度小于1M然后一直减少高度输出的指令速度会随着距离改变

现在条件满足我们开始做有避障版本的自动驾驶

python怎么模拟swap_PD算法_10

主函数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后退

测试效果 

python怎么模拟swap_STC15W408AS_11


 四丶实物图

注:以下操作比较硬核

降压模块

因为飞控给的电压不够这么多器件所以加了一个降压模块来保证模块的正常工作

没有合适的焊台所以丑了一点

python怎么模拟swap_python怎么模拟swap_12

接收机

这里我们用的接收机是富斯16x的接收机 ,注意不是每种遥控器和接收机都可以直接使用

需要配置模式,一般来说有 ibus,sbus,ppm,pwm模式 ,我们这里一定要选择成为ppm模式很重要!

python怎么模拟swap_STC15W408AS_13

python怎么模拟swap_STC15W408AS_14

python怎么模拟swap_超声波避障_15

YF-SMART&&PPM板

按照说明上给的指示直接接线就好了

PPM板就是吧 YF-smart输出的8通PWM转换成PPM然后输出给飞控

python怎么模拟swap_超声波避障_16

python怎么模拟swap_STC15W408AS_17

STC15W408AS&&HC-SR40

YF-SMART的TR串口接到STC15W408AS芯片的RT串口上,让他可以接收我们设置的指令

(飞行计划)

 HC-SR40超声波接入到我们设置芯片上的IO口就行

python怎么模拟swap_python怎么模拟swap_18

最后测试一下是否可以正常切换

python怎么模拟swap_python怎么模拟swap_19

 

python怎么模拟swap_STC15W408AS_20

最终的组装成品and演示效果

python怎么模拟swap_PD算法_21

python怎么模拟swap_python怎么模拟swap_22

python怎么模拟swap_PD算法_23

最后虽然实现了定点避障效果,但是本身用来自动驾驶的飞机稳定性不够,还是会晃动效果只能说一般般吧

建议在调试KD值的时候选择无风且保证飞机组装和稳定的情况下调试.