|
本帖最后由 743836814 于 2015-6-21 03:15 编辑
多旋翼避障首先要确定避障系统的基本思路。
现如今市场充斥着各种飞控,原本想在开源飞控项目上进行二次开发,但感觉能力有限,又违背了通用的原则所以决定在接收机与飞控中间做一个中间层。
添加一个中间层后,所有飞控都能通用,从QQ飞控,到PX4,APM,都可以通吃。
这样就达到的通用的目的。
为什么可以达到通用的目的呢?
参考:(外部链接予以删除版主留)的帖子,航模中输出信号大多数为PWM信号,其1000为最低点,1500为中立点,2000为最高点。
开发过程中选用arduino进行开发,其语法简单,各种库丰富,是进行开发的不二之选。
- #include<Servo.h>;
- #define AIL1 22 //AIL fuyi
- #define ELE2 24 //ELE shengjiang
- #define THR3 26 //THR youmen
- #define RUD4 28 //RUD fangxiang
- unsigned long INAIL;
- unsigned long INELE;
- unsigned long INTHR;
- unsigned long INRUD;
- int OUTAIL;
- int OUTELE;
- int OUTTHR;
- int OUTRUD;
- Servo AIL;
- Servo ELE;
- Servo THR;
- Servo RUD;
- void setup()
- {
- pinMode(AIL1,0);
- pinMode(ELE2,0);
- pinMode(THR3,0);
- pinMode(RUD4,0);
- AIL.attach(4);
- ELE.attach(5);
- THR.attach(6);
- RUD.attach(7);
- Serial.begin(9600);
- }
- void loop()
- {
- INAIL = pulseIn(AIL1, 1);
- INELE = pulseIn(ELE2, 1);
- INTHR = pulseIn(THR3, 1);
- INRUD = pulseIn(RUD4, 1);
- OUTAIL = map(INAIL,1010,2007,47,144);
- OUTELE = map(INELE,1010,2007,47,144);
- OUTTHR = map(INTHR,1010,2007,47,144);
- OUTRUD = map(INRUD,1010,2007,47,144);
- AIL.write(OUTAIL);
- ELE.write(OUTELE);
- THR.write(OUTTHR);
- RUD.write(OUTRUD);
- Serial.print("AIL=");
- Serial.print(INAIL);
- Serial.print(" ELE=");
- Serial.print(INELE);
- Serial.print(" THR=");
- Serial.print(INTHR);
- Serial.print(" RUD=");
- Serial.print(INRUD);
- delay(5);
- }
复制代码这段代码主要用来读取接收机的PWM值,pluseIn()函数可以读取指定端口的电平脉冲时间。其还调用了arduino 的舵机库的舵机函数来控制,有人看出了,OUTTHR = map(INTHR,1010,2007,47,144); 这是个缩放函数,让1010-2007缩放为47-144,这里有人会问,为什么是1010-2007,为什么是47-144,我再来和同学们讲解,刚刚在取样的时候我们发现arduino读取的PWM宽度在1000-2000之间,但是有些值是大于2000的,那么我取了一个更大的区间,来“装”PWM的区间,所以是1000-2007,但是为什么要让舵机输出47-144度呢。这里要用点小技巧,羊毛出在羊身上,没错我们让arduino自己给自己测脉冲时间,我们可以写一个很简单的代码,还记得刚刚那个pluseIn()函数吗,我们让任意一个端口输出一个90度的舵机角度值,也就是xxxx.write(90); 然后把这个端口接在arduino其他任意一个数字端口上,用pluseIn()去测这个90度的脉宽是多少,比如90度测出来脉冲时间是1500,大了,我们要找的是1000-2000范围的那个舵机角度,我们再来一个30度,或者170度,就这样把范围越缩越小,最后,我找出了他们之间的关系,47度的舵机输出,用pluseIn()去测量刚好在1000左右,那么地、低位就找到了,同样高位在144度上 脉冲宽度时间是2000左右,那么接下来代码大家都看懂了吧?,这里的arduino就原封不动的把接收机的信号吃进去了,又吐出来给飞控,至此,arduino已经完全潜入飞机控制系统。
(如有疑问,请查阅连接帖子)
到目前为止,中间层已经初步的建立,开始选用相关避障所需要的传感器。
出于实用和成本方面的原因,通过本人的实际购买测试,最终选用了HC-SR04超声波,价格低廉,且测量范围与精度值复合要求。
1.使用电压:DC5V
2.静态电流:小于2mA
3:电平输出:高5V
4:电平输出:低0V
5:感应角度:不大于15度
6:探测距离:2cm-450cm
7:高精度:可达3mm
接线方式,VCC、trig(控制端)、 echo(接收端)、 GND地线
本产品使用方法:一个控制口发一个10US以上的高电平,就可以在接收口等待高电平输出.一有
输出就可以开定时器计时,当此口变为低电平时就可以读定时器的值,此时就为此次测距的时间,
方可算出距离.如此不断的周期测,就可以达到你移动测量的值了~~
模块工作原理:
(1)采用IO触发测距,给至少10us的高电平信号;
(2)模块自动发送8个40khz的方波,自动检测是否有信号返回;
(3)有信号返回,通过IO输出一高电平,高电平持续的时间就是
超声波从发射到返回的时间.测试距离=(高电平时间*声速(340M/S))/2
超声波测距程序:
- const int TrigPin = 6;
- const int EchoPin = 7;
- float cm;
- void setup()
- {
- Serial.begin(9600);
- pinMode(TrigPin, OUTPUT);
- pinMode(EchoPin, INPUT);
- }
- void loop()
- {
- //发一个10ms的高脉冲去触发TrigPin
- digitalWrite(TrigPin, LOW);
- delayMicroseconds(2);
- digitalWrite(TrigPin, HIGH);
- delayMicroseconds(10);
- digitalWrite(TrigPin, LOW);
- cm = pulseIn(EchoPin, HIGH) / 58.0; //算成厘米
- cm = (int(cm * 100.0)) / 100.0; //保留两位小数
- Serial.print(cm);
- Serial.print("cm");
- Serial.println();
- delay(1000);
- }
复制代码
传感器选定好后便可以进行相关的程序开发了。
(草图)
避障思路。
下面是我自己写的程序,刚学,不要见笑。。。(6.14晚上21点,未测试)
(此版本程序有缺陷,待我修改。。)
Hi_Bob兄帮我建立的,在这里表示感谢。
一般我写的会发布到群里,本人写的实在不堪入目,哈哈。(扣群:四五six丝丝124二)
版规真是奇怪。
|
欢迎继续阅读楼主其他信息
|