四旋翼飞行器搭建教程px4ardupoilotapm.docx
《四旋翼飞行器搭建教程px4ardupoilotapm.docx》由会员分享,可在线阅读,更多相关《四旋翼飞行器搭建教程px4ardupoilotapm.docx(10页珍藏版)》请在冰豆网上搜索。
四旋翼飞行器搭建教程px4ardupoilotapm
四旋翼飞行器搭建教程
(译自————加里斯.欧文)
本文将带你通过建立自己的飞行控制器(飞空软件),同时教你工作的具体细节。
这些信息很难找到,特别是那些本身就不是航天工程师的人!
就我个人而言,我用了六个月,因为我花费了太多的时间查找bug和调试bug,但通过这篇文章你可以短期收获同样的经验。
我会教你避开陷阱,这样你就不会像我一样浪费时间。
第一个关键是你对硬件的选择。
我选择从零开始建立自己系统,在这一阶段的时候我都不知道RC(remotecontrolled遥控; radiocoding无线电编码;)和飞行器是如何飞行的,这是一个巨大错误。
开始我以为,通过自行购买附加电路,芯片和传感器能省很多钱,结果最终我花了一大笔钱!
放过自己吧,直接去购买ardupilot2.5控制板,组装你的直升机,了解遥控,了解飞行原理,然后回到这里。
这个板子本质上是只是一个连有一些传感器Arduino(开源主控板,可查),和我们将在这篇文章介绍的程序——我们自己编写的。
你得将所有东西连接起来,你的四旋翼飞机才能得飞:
当然你也得会用优秀的arducopter软件。
本项目(ardupilot)由3DRobotics提供赞助,这意味着他们销售所设计的硬件获利,并将所得利润回馈社区。
该软硬件是完全开源的,所有人可以免费复制下载。
你可以直接从他们那里购买,或者从Hobbyking(namedHKPilot)andRCTimer(namedArduFlyer).购买相同的拷贝件。
在这篇文章中,我将假定您有ardupilot硬件——其本质上上是附传感器Arduino。
如果你选择忽视我的建议,并且建立自己的硬件,或使用Arduino电路板,那么您需要更换的底层代码(HAL库)。
我也会以为你在X配置(x型四旋翼),+/X(两种四旋翼配置)和六/八旋翼飞行器之间切换(只是不同的电机的组合),配置的改变不会让它在本文有任何实质性的区别。
理想的情况是,你已经飞行过加载了arducopter代码的四旋翼,因此你应该将电机连接如下所示的位置和旋转方向。
我也要假设你有一些arduino的经验,或至少是C/C++的经验。
Arduino库不是特别智能的或适合,所以我们将使用一些更加合适的的ardupilot库。
然而,我们会尽量少使用、最小幅度的使用,以提供DIY式解决方案的支持(这就是为什么你在这里毕竟)。
我们将要使用的第一和主要库是ardupilot硬件抽象层(HAL)库。
这个库试图隐藏了底层的区别,例如你如何读取和写入引脚和其它一些东西——其优势是,软件可移植到新的硬件,只需更换硬件抽象层。
在ardupilot的情况下,有两个硬件平台,APM和PX4,每一个都有自己的底层库允许ardupilot代码运行。
如果您稍后决定在RaspberryPi上运行你的代码,你只需要改变硬件层代码。
硬件层是由如下几个部分组成:
RCInput无线输入——阅读RC无线电rcinput-。
RCOutput无线输出——用于控制电动机和其它输出rcoutput-。
Scheduler计划表——运行特定的任务在固定时间间隔调度程序-。
console控制台——提供访问串行端口。
I2C,SPI——总线驱动程序(用于连接传感器小电路板网络)
GPIO——一般目的的输入/输出——允许直接访问Arduino引脚,但是在我们的案例中,主要的发光二极管
如何下载:
你需要下载Arduino的IDEardupilot版。
还需要将库文件放在你的延伸文件夹中。
还要确保你选择你的板类型像Arduino的菜单这样:
ReadingtheRadioInputs
读取无线电输入
我们的飞行控制系统要读取无线电输入信号(飞行指令),测量四旋翼的实时的姿态(偏航/俯仰/滚动),改变电机的转速——以适应四旋翼按照我们所期望的方式飞行。
所以让我们开始通过无线电开始学习。
RC接收机有几个输出,有好几个通道(或称为棒/开关/旋钮)。
无线电输出的50Hz脉冲,这个脉冲的宽度是由无线电发射机的摇杆位置决定的。
通常情况下,脉冲持续1000us到2000us长并有18000us到19000us的间隙,所以表示0的油门会产生一个1000us的脉冲,表示完全的油门则有2000us长。
可悲的是,大多数的接收机是不准确的,我们通常要测量每个杆位的最小或最大值脉冲宽度(这我们接下来将要做的)。
Ardupilot的底层库,为我们做了测量这些脉冲宽度的痛苦工作。
如果你自己编写这些代码,你需要中断其他工作并用定时器来测量无线电信号——analogreadArduino不适合做这项工作,因为它占用了处理器全部的计算容量,虽然它可以测量,但是同时也阻止我们其他事。
(即Arduino是单线程软件,无法同时做两项工作)实现一个测量信号的工作并不难,让这种程序持续1个小时甚至更长是很普通的事,我们不是只做这么简单的程序。
下面是一些使用APM底层库,测量通道“值”的代码的简单例子。
通道“值”就是测量毫秒级的脉冲宽度。
#include
#include
#include
#include
#include
#include
#include
#include
constAP_HAL:
:
HAL&hal=AP_HAL_AVR_APM2; //Hardwareabstractionlayer
voidsetup()
{
}
voidloop()
{ uint16_tchannels[8]; //arrayforrawchannelvalues
//ReadRCchannelsandstoreinchannelsarray
hal.rcin->read(channels,8);
//Copyfromchannelsarraytosomethinghumanreadable-arrayentry0=input1,etc.
uint16_trcthr,rcyaw,rcpit,rcroll; //Variablestostorercinput rcthr=channels[2];
rcyaw=channels[3];
rcpit=channels[1];
rcroll=channels[0];
hal.console->printf_P(
PSTR("individualreadTHR%dYAW%dPIT%dROLL%d\r\n"),
rcthr,rcyaw,rcpit,rcroll);
hal.scheduler->delay(50); //Wait50ms
}
AP_HAL_MAIN(); //specialmacrothatreplace'soneofArduino'stosetupthecode(e.g.ensureloop()iscalledinaloop).
创建一个新的草稿脚本,并将该脚本上传到Ardupilot硬件上。
使用串行记录仪纪录下每个通道的最大和最小值。
(同时将脉冲调至极限)
现在让我们来衡量脉冲的“值”,以显示他们所含有的意义。
我们要使用一种称为Map的功能,这是一种确定一个数值在某一区间将其判读为另一“值”的功能。
例如,有一个50的数值,在0——100之间,而我们想要将他放入0到500这个区间来衡量,Map的功能将会定义其为250,并返回250这个值。
Map功能会在你引用并定义(#include&defines)之后被启用(从Arduino库中引用)
longmap(longx,longin_min,longin_max,longout_min,longout_max)
{
return(x-in_min)*(out_max-out_min)/(in_max-in_min)+out_min;
}
这样使用Map功能:
result=map(VALUE,FROM_MIN,FROM_MAX,TO_MIN,TO_MAX).
你会感到仍然没有接触到油门,毫无疑问你会对于自己没有参与建立油门的判读而感到高兴,这个阀值是由电调生成的(如果你是按照我的建议做的)。
俯仰和翻滚在正负45度之间会被测量,当然你也可以设定为正负150度。
我的loop()函数现在看起来像,更换为测量最大最小杆位的Map功能。
我们也会改变函数类型,变为long型,以支持负数。
longrcthr,rcyaw,rcpit,rcroll; //Variablestostorercinput
rcthr=channels[2];
rcyaw=map(channels[3],1068,1915,-150,150);
rcpit=map(channels[1],1077,1915,-45,45);
rcroll=map(channels[0],1090,1913,-45,45);
俯仰在杆位向前是是负的,翻滚或偏航在杆位向左是负的。
如果实际操控中不对,请调整到正确位置。
你现在应该输出这些值,并在串行接口上面观察数据。
理想状态下,当杆位在中间的时候,这些值应该为零(除了thr变量)。
调试最大最小值,直到合适为止。
这些数据会有一些扰动(在真值上下浮动)因为摇杆是模拟信号输出,所以会有1度到2度的偏差。
一旦你能够将你的四旋翼飞起来的时候,你就会考虑回到这里介绍均值滤波器。
确保向前倾斜,滚动和偏航为左时,数值为负数——如果不是的,请将Map函数前改为负函数。
当然你也要确保当你增加油门值时,实际油门值也会增加。
Controllingthemotors
控制电机
电机是由电调来控制的,他们的工作脉宽大约有1000us和2000us和无线接收机一样——脉宽为1000us意味着无,而脉宽为2000us意味着有。
电调被设定为接受50Hz的信号,但是大多数电机将5-10个储存的值平均后,再发送给电机。
这种模式也可以在四旋翼上使用,如果将平均滤波效应最小化,四旋翼会表现的更好。
因此,APM底层库的脉冲工作在490Hz,这意味着5到10个脉冲将会快速被平均,很大程度上减小了滤波效应。
在setup()函数中,可以这样输出:
hal.rcout->set_freq(0xF,490);
hal.rcout->enable_mask(0xFF);
在你引用之后,让我们定义一下每个Mapping输出的电机名字——mapping的输出口名与四旋翼(Arducopter)使用的一样,只不过是从零开始而已。
(编程中从0开始命名,所以四个电机的命名是0到3,四旋翼四个电机则是1到4)
#defineMOTOR_FL 2 //Frontleft
#defineMOTOR_FR 0 //Frontright
#defineMOTOR_BL 1 //backleft
#defineMOTOR_BR 3 //backright
你的loop函数里,读取无线电信号后,将这个无线电阀值直接输出给电机
hal.rcout->write(MOTOR_