之前在网上搜无人机避障在发现了“PlayUAV汇聚开源力量”上看到“多旋翼通用避障开源项目”(http://www.playuav.com/article/242),这个作者是湖南工业大学的20岁小伙子,昵称叫“七烟”,现在是“多旋翼避障系统开发”QQ群的群主。
在这个帖子里看到他所引用的由魏宇科提出的“用Arduino扩展无人飞行器”的新思路,魏宇科在百度上就能搜到,是第九届全国高职高专“发明杯”大学生创新创业大赛一等奖的获得者,他这篇帖子是在“ARDUINO中文社区”,题为“用Arduino扩展无人飞行器+普及无人机知识,不会算法的人必看”(http://www.arduino.cn/thread-11353-1-1.html),魏宇科的QQ群是“Arduino扩展无人机”。
我这里之所以写这个帖子,主要是看到很多人对此也感兴趣,但在应用和参考上,很多都是照搬照抄,囫囵吞枣式的进行,存在的一些问题也是继续在使用。为此,从我的角度对两位的工作做一些锦上添花的补充和进一步的优化等工作。此外,他们的工作是在Atmega2560上做的,我这里简化了,在Atmega328p上做了一些工作,很多东西我并没有做完整,只是为了说明问题,做了局部的工作。
他们两位的一些作品和工作,你们可参考相关的帖子,或到这两个群里看看相关的群文件。
首先来对两位之前的工作谈谈自己的一些看法:
1. 魏宇科的“Arduino扩展无人机”
1.1 优点
在接收机和飞控之间插入的方式很好,这使得避障与飞控程序无关,从而降低了开发难度,门槛比较低,在这里不仅可以实现避障,只要有想法就可在这里实现你想要的其他一些功能,大家可以自由设想,并努力实现。
1.2 不足
(1)遥控信号解码
魏宇科的遥控信号解码采用下述方式
INAIL = pulseIn(AIL1, 1);
INELE = pulseIn(ELE2, 1);
INTHR = pulseIn(THR3, 1);
INRUD = pulseIn(RUD4, 1);
程序效率比较低,实时性不是很好,这一点,“七烟”做了改进,采用了中断方式。
(2)遥控信号输出的校准与修正比较繁琐,输出精度比较低,这个问题,我做了一些改进。
2. “七烟”的避障工作
2.1 优点
提出了一个实用、具体的工作;用中断获取接收机的AIL和ELE信号,提高了解读遥控信号的实时性。
2.2 不足
(1)AIL.write(OUTAIL)与ELE.write(OUTELE)这两个输出,在 loop() 内,而且是在超声波函数与避障函数之后,那么前面所用的中断方式获取的AIL和ELE信号其实时性的优势就大打折扣了;
(2)HC-SR04正常的、比较好的、合格的模块,说明书中要求超声测量的重复周期要大于60ms,超声测量程序使用的是 pulseIn 函数,而且四个超声测距是顺序执行的,理想情况下,所用的时间需要 240ms 以上,而遥控信号的周期略大于 20ms,这样就严重的影响了避障的响应时间;
(3)在没有障碍物的情况下,上述所说的重复周期要求很长,我实测了一款,从发射到检测完成的时间为 216.972ms,这是一个超声波测量所需要的时间,要是4个超声波,加在一起的时间在无障碍的情况下就要 867.888ms 了,这个时间近 1 秒了,这样遥控相应时间以及避障的响应时间都存在很大的隐患。
我发现的这些不足,在我的工作中做了一些优化和改进。
3. 改进与优化
3.1 遥控器中断方式解码,与实时输出
在void setup()中设置中断,见下面的“*****”部分,这个在“七烟”的工作中已经实现了。
void setup() {
Serial.begin(115200);
pinMode(Echo, INPUT); //超声波测距
pinMode(Trig, OUTPUT);
digitalWrite(Trig, LOW);
pinMode(RC1_In, INPUT); //遥控器 1 通道输入
attachInterrupt(0, RC1_Int, CHANGE); //*****
rco1.attach(4);
}
下面中断处理函数与“七烟”的基本相同,但我加了一句,还是“*****”部分。
void RC1_Int() { //遥控器 1 通道解码
if (digitalRead(RC1_In) == HIGH)
time0 = micros(); // store the current micros() value
else
t_rc1 = micros() - time0;
if(Ob_ST == 0) rco1.writeMicroseconds(t_rc1); //*****
}
新增加的部分表示在没有要处理的情况下(通过设置一个标识Ob_ST判断),遥控器解码后立即输出这个通道的遥控信号给飞控,在这里输出,而不是在主循环loop里等其他处理函数处理完成后再输出,这样实时性就几乎与遥控器直接操作完全相同了,仅延时最大2ms的时间,遥控信号更新率仍保持在20ms左右。
而且输出使用“writeMicroseconds()”函数,参数变量是us,比魏宇科所用的“write()”函数精度高多了,而且不用校准和修正了,因为保持了原来的遥控输出信号精度和范围不变,如果非要校准的话也很简单,将实测值直接给下列语句即可。
OUTAIL = map(rc1_val, rc1_min, rc1_max, 1000, 2000);
其中,rc1_min是遥控器该通道输出的最小值;rc1_max是遥控器该通道输出的最大值。将遥控器的输出规范到1000us到2000us之间。
3.2 超声波测距的改进
超声波测距以前他们直接采用下列语句:
Dist = pulseIn(Echo, HIGH);
这样的话,在没有障碍时,超声波下次测量时必须要等200多ms以上,为此我简单的加了一个超时限制,譬如超时值为15000us,语句如下:
Dist = pulseIn(Echo, HIGH, 15000);
给出一个单超声波避障的例程如下。
SR04避障.zip
(889 Bytes, 下载次数: 12)
避障扩展板原理图:
这里的程序只做了接近距离的比例避障,大家可以考虑加速接近速度项,这样就成了类似PD算法了。
进一步的扩展方法可以使用原理图中的RC1对接收机的PPM信号进行解码,这样就可实现 8 通道接收信号的中断实时处理,也可以做更多、更丰富的扩展功能了。
如果有人感兴趣的话,我将继续说上面还未说到的一些问题,且听下回分解吧!!!
|