APM飞控学习之路:1 无人机的分类与发展

   “旧时王谢堂前燕,飞入寻常百姓家”。无人机也像那堂前燕,从以前为军事所专属,负责侦查和战斗,飞入民用领域,在航拍、植保、快递、救灾、巡检、拍摄等行业大显身手,无人机+的应用遍地开花,成为智能时代机器人领域的尖兵。

        无人机,顾名思义,即不载人的飞行器。目前飞行器主要分为3类:固定翼(fixed wing);直升机(helicopter);多旋翼(multi-rotor)。最近风头最热、也最有前景的,当属多旋翼大家族的主力军——四旋翼无人机(quadcopter),大大小小的无人机厂商如雨后春笋般冒出来。大的有DJI、零度、亿航、极飞等,小的就数不胜数了,最近京东也众筹了一款PowerEgg无人机,无人机行业的繁荣可见一斑。各飞行器的特点简介如下:

飞行器分类

固定翼

直升机

多旋翼

稳定性

自稳定

不稳定,完整驱动

不稳定,欠驱动

续航时间

飞行效率

载荷

其他

起飞助跑,降落滑行

可垂直起降,机械结构复杂

可垂直起降,机械结构简单        

         本系列博客的重点也是四旋翼无人机。四旋翼含4个螺旋桨,即4个电机,4个自由度,而三维空间的位姿有6个自由度,4<6,因而称欠驱动。受控的自由度可以从遥控器的输入看出端倪:左边的摇杆控制上下的高度和机头的朝向(Yaw),右边的摇杆控制飞机的前后和左右,共4个自由度。而欠驱动的2个自由度为飞机的俯仰(Pitch)和横滚(Roll),和飞机的前后、左右是耦合的,因此也可以说右边的摇杆控制飞机的俯仰和横滚。无人机在前后左右运动时机身会产生一定倾斜的原因即在于此。

        上表大致总结了各飞行器的特点,那么问题来了,多旋翼各项指标落后仍受大众青睐到底为哪般?让我们走近科学,探秘多旋翼。由于多旋翼系统不稳定、欠驱动,需要自动控制器来控制飞行器的姿态,而要取得姿态,就不得不提惯性导航系统(Inertial Navigation System,以下简称INS)。INS的主要原理是利用加速度计和陀螺仪,对时间积分获得速度,进而获得飞行器的位置和姿态。INS最初用于导弹、火箭等军事领域,十几公斤的大铁疙瘩对于按吨计的巨型铁疙瘩来说那都不算事儿。但要放到多旋翼头上,这可是泰山压顶,愚公有心也无力,多旋翼的研究一度停滞。

        到了上世纪90年代,随着微机电系统(Micro-Electro-Mechanical System,以下简称MEMS)的发展,几克重的mm级INS被开发出来,多旋翼的自动控制器又重新抬头。但是条件还不够,传感器的噪声、多传感器的数据融合、多旋翼的非线性系统结构、飞行控制算法等问题仍像一座座大山,等待探路者去征服。到了2005年,稳定靠谱的多旋翼自动控制器才正式面世。四旋翼作为多旋翼无人机中最简洁的一种,开始受到广泛关注和研究。由于其结构简单、控制灵活、成本较低,也逐渐进入了商业领域和大众视野。

        之后的历史,诸君都是见证者。2009年,《三傻大闹宝莱坞》中Geek的小四轴,把新鲜感带给了大众。2010年,法国Parrot公司发布AR.Drone——世界首款流行的四旋翼,上能飞天拍大地,下可悬停摆造型,成为人们的天空之眼。此时的四旋翼,还是小众人群的玩具。直到2013年,DJI的Phantom与GoPro结合,让四旋翼从一个玩具变身成了航拍精灵。先手优势一发不可收,至今DJI已成为世界上首屈一指的无人机厂商,成为中国智造的骄傲,也成功帮汪峰求婚,新娘头条双丰收!除了DJI,国际的3D Robotics、AscTec,国内的零度、亿航也加入战局,群雄争霸,硝烟四起。

        一个Interesting&Exciting的无人机时代正在拉开序幕,让我们拭目以待。

APM飞控学习之路:2 四旋翼的工作原理与系统组成

2016年10月31日 20:48:47

阅读数:8807

        “一叶障目,不见泰山”。在研究四旋翼飞行器之前,有必要从整体介绍其工作原理、主要部件、技术名词等基础知识。不然就像羊入虎口,陷入一大堆不同层次的资料,难觅出口。接下我就抛砖引玉,尽自己所能,介绍四旋翼的工作原理和主要部件。余虽不敏,然余诚也。

工作原理

        四旋翼飞行器,通过4个对称布置的电机,改变螺旋桨的转速,实现升力的变化,进而控制飞行器的姿态和位置。姿态具体指3个欧拉角:横滚(Roll)、俯仰(Pitch)、偏航(Yaw)。位置具体指1个高度油门(Throttle)和2个位置(X和Y)。欧拉角是一种描述物体姿态的常见方式,广泛应用于惯性导航、机器人等领域。为了方便大家理解,在网上找了3个欧拉角的动图,分别为Roll、Pitch、Yaw,让我们致敬制作者3秒钟。

        横滚:Roll,控制四旋翼左右运动。

        俯仰:Pitch,控制四旋翼前后运动。

        偏航:Yaw,控制四旋翼的朝向。

        无人机的姿态和位置共有6个自由度,每个自由度的控制如下图所示。4个电机2个正转(电机2和4),2个反转(电机1和3),对称布置。电机正反转配合正反桨,可使螺旋桨的风都往下刮以平衡重力,同时抵消因桨叶旋转带来的空气阻力扭矩。由于输入只有4个自由度,因此多出的2个自由度是不完全受控的,其中俯仰运动和前后运动耦合,滚转运动和侧向运动耦合。

        坐标系:标准右手系。规定X轴正方向为前向。螺旋桨的箭头向上↑:电机转速上升。螺旋桨的箭头向下↓:电机转速下降。

        (a) 垂直运动(Throttle):4个电机均加大马力,螺旋桨产生的升力大于重力,飞机便垂直上升。当升力与重力平衡时,飞机便悬停。悬停是考验算法的重要一环,靠的是PID不断反馈,调整转速。

        (b) 俯仰运动(Pitch):电机1加大马力,电机3减小马力,二者的变化量相同。1处升力变大,3处升力减小,重力仍保持平衡,但对Y轴产生一个力矩,机身绕Y轴旋转,实现俯仰。

        (c) 滚转运动(Roll):与 (b) 原理相同,只是Y轴换成了X轴。

        (d) 偏航运动(Yaw):电机1、3加大马力,电机2、4减小马力,二者的变化量相同。重力和绕X、Y轴的扭矩仍保持平衡,但要注意的是,根据作用力和反作用力原理,由于2个正转的速度>2个反转的速度,空气阻力产生的扭矩不平衡了,使得机身绕Z轴旋转,实现偏航。

        (e) 前后运动:与 (b) 耦合,机身绕Y轴旋转一定角度后,使得升力沿水平方向有了分量,实现前后运动。

        (f) 侧向运动:与 (c) 耦合,原理与 (e) 相同。

        如果有朋友接触过麦克纳姆轮,也称“全向轮”,那就更容易理解四旋翼的工作原理了。麦克纳姆轮通过4个对称布置的电机和轮盘,可实现车身水平任意方向的移动和原地旋转,无比灵活。

主要部件

        以S500为例,S500是一架入门级的四旋翼飞机,这里的500指的是轴距(对角2个电机之间的距离),单位 :mm。对于开源爱好者而言,如果想一站式玩四旋翼,在某宝上选购一架S500是个不错的选择。下面我就从上表出发,详细介绍四旋翼的主要部件和技术名词。

四旋翼本体

        四旋翼分2种模式,1种是+模式:飞行方向(机头)与旋翼重合;1种是X模式:飞行方向(机头)平分旋翼。

        +模式:直观,简单,驱动弱,调参容易。

        X模式:复杂,稳定,驱动好,调参麻烦。

        对于四旋翼,稳定和驱动是第一位的,调参可以站在巨人的肩膀上,因此一般采用X模式。

飞行控制器

        飞行控制器简称飞控,是无人机的大脑。目前主要分开源和闭源两派,开源飞控的鼻祖来自Arduino,著名的WMC飞控和APM飞控都是Arduino飞控的直接衍生品,APM全称ArduPilotMega,其中的Ardu代表的就是Arduino。APM飞控是目前成熟度最高的开源飞控,但由于容量和计算量有限,在不久的将来一定会被更强大的PIX4、PIXHAWK所超越,成为一个时代的缩影。还有一些较为初级的飞控,如KK、QQ、玉兔等,在这就不赘述了。闭源飞控主要由商业公司推出,如DJI的工业级飞控A2、A3,入门级飞控Naza系列,还有零度的S4、X4和双子星GEMINI。值得一提是其中的双子星,是国内首个双余度安全飞行控制系统。随着安全性的重视和提高,冗余度设计也将成为无人机的标配。

螺旋桨

        4个螺旋桨,2正桨(顺时针转)2反桨(逆时针转),正反桨的风都向下吹,正反的目的主要是抵消螺旋桨的自旋。安装的时候,无论正反桨,有字的一面均向上。桨型中1045这4位数字,前2位10代表桨的直径(单位:英寸inch),后2位45代表桨的角度(单位:度°)。

电机

        4个无刷电机,2正转2反转。2212这4位数字,前2位22代表电机转子直径,后2位12代表电机转子高度,单位:毫米mm,注意均指电机转子而非外壳。如果大家留心的话,电机外壳上一般会并注明这4位数字,除此之外,还会看到一个KV值,代表外加1V电压时电机每分钟空转转速。如“KV:900”代表外加1V电压时,电机空转时每分钟转900圈。常见的电机品牌有新西达(XXD)、朗宇(SunnySky)等,并且很多外壳上会有一串神秘字符:MADE IN CHINA。

电调

        说完电机说电调,电调和电机配套使用,是飞控和电机之间的桥梁。电调全称电子调速器(Electronic Speed Control),负责将飞控的控制信号(PWM波)转变为电流的大小,进而控制电机转速。除了明面上的转换功能,还能承载电机所需的大电流,以及将11.1V转为5V供飞控和遥控模块使用(BEC输出)。电调的主要参数是电流输出能力,单位A,如30A代表电调能提供的最大电流为30A。常见的电调品牌有新西达(XXD)、中特威(ZTW)、好盈(HobbyWing)等。

电池

        一般为锂电池,因为同等电池容量锂电池最轻。大家可以看到有3个参数:3200mAh 11.1V 30c。和手机电池一样,3200mAh代表以3200mA电流放电,可持续1小时。11.1V代表电压,一般由3节标准锂电池组成(3.7V×3=11.1V),相应标识为3S。30c代表放电能力,在航模中是个重要参数,意味着可以3200mA×30的电流强度放电。说完了放电,还有充电,一般为2c充电,即充电电流可为3200mA×2。由于航模锂电池采用多节标准锂电池组成,而各节标准锂电池之间存在充放电性能差异,因此充电器一般采用平衡充,避免某节电池过充。

遥控器

        主要分美国手和日门手,美国手的油门在左边,日本手的油门在右边。在四旋翼的控制中,一般采用美国手。怎么判断油门呢?很简单,遥控器左右2个摇杆中,推上去不回弹的是油门。也很好理解,油门一般稳定在一个位置就好了,回弹的话飞手会流泪。遥控器中也有1个神秘数字,6代表6通道,即遥控器可控的动作路数。因为四旋翼有4个自由度,所以遥控器至少需要4通道,剩余的通道用于控制飞行模式等。

        至此四旋翼的主要部件和技术名词介绍完毕,还有一些可选部件,如数传、OSD、云台、相机、图传等,待大家入门后即可自行挖掘。最后附上一个Exciting的TED视频,震撼你的眼球。拉菲罗·安德烈:四轴飞行器灵活的运动性

   

APM飞控学习之路:3 APM系统介绍与开发环境搭建

置顶2016年11月03日 11:08:55

阅读数:31859

        “工欲善其事,必先利其器”。在进行无人机飞控开发时,选择一个合适的软硬件平台以及IDE是十分重要的。目前,APM飞控成熟度高,开发工具齐全,社区建设完善,开发者文档丰富,适合开源选手入门和二次开发。因此,本系列博客以APM飞控作为切入点,在Windows环境下介绍其代码结构和开发应用。

APM系统介绍

        APM全称ArduPilotMega,Ardu源自Arduino,Pilot意指飞行,Mega代表主芯片为ATMEGA2560(Atmel公司的8位AVR单片机)。是的,没有看错,一个简单8位单片机竟完成了如此复杂的飞控任务! 51单片机表示哭晕在厕所,同为8位出身,命运截然不同。笔者大概是2011年接触的单片机,当时也同大多数初学者一样,从经典的51单片机入门,一个个模块、寄存器的学习,曲线虽说不上陡峭,但至少不那么友好。反观Arduino,近3年在国内迅速崛起,除了Geek文化和开源文化的普及,一个很关键的原因在于Arduino让不懂硬件电路的普通人(甚至小学生)也能轻松上手硬件了。没有了烦人的寄存器,没有了纷繁的头文件,一个setup()和一个loop(),再加一个自带教程的简洁IDE,Arduino名副其实——源自意大利的男姓用名,意为“强壮的朋友”。世界如此美好,我想和Arduino做朋友。

        APM内置六轴MEMS传感器MPU6000,气压计MS-5611,三轴磁力计HMC5883,一般还会配置GPS模块,以便更精确的惯性导航。其中,MPU6000整合了三轴陀螺仪和三轴加速度计,积分可得速度和位姿。MS-5611通过测量气压得到高度,辅助GPS定位。HMC5883通过测量地磁场得到方位,辅助无人机定向。飞控采集并融合多种传感器的数据,计算并校正无人机的位姿。给APM一张正面裸板特写!

APM与PIXHAWK的关系        

        说到APM,就不得不提它的进化版:PX4和PIXHAWK,来自苏黎世联邦理工大学。“PX4是一个软硬件开源项目(遵守BSD协议),目的在于为学术、爱好和工业团体提供一款低成本、高性能的高端自驾仪。PX4FMU自驾仪模块运行高效的实时操作系统(RTOS),Nuttx提供可移植操作系统接口(POSIX)类型的环境。由3DR联合APM小组与PX4小组于2014年推出的PIXHAWK飞控是PX4飞控的升级版本,拥有PX4和APM(ArduPilot)两套固件和相应的地面站软件,也是目前全世界飞控产品中硬件规格最高的产品。”

        好了说人话,目前主流就2种:APMPIXHAWK。有时指硬件,有时指软件(固件),为了明确,在此做个区分。硬件分2种:APM和PIXHAWK。APM的版本有2.5,2.6和2.8,PIXHAWK的版本有v1和v2。软件也分2种:APM和PX4。软件版本就多了去了,详见github。APM硬件由于存储空间有限,最高支持到3.2.1的APM软件。PIXHAWK硬件是STM32F4,存储空间大,对APM软件(3.2.1之后的版本也支持)和PX4都支持。

        APM和PIXHAWK都开源,不过二者遵守的开源协议不同。APM多用于DIY和小型产品,某宝上大量的无人机就采用APM,成本低。公司商用一般采用PIXHAWK。目前很多PIXHAWK里跑的还是APM固件,个人认为有几大原因:1. APM固件出来的更早,使用人群习惯的延续;2. APM固件成熟度更高、资料更全。3. APM固件走开源路线更彻底,遵守GPL V3协议,PX4更倾向商业和实验用途,遵守BSD协议。目前APM小组已和PX4小组分道扬镳,详见新闻:ArduPilot脱离Dronecode真相

APM固件下载

        刚提到APM硬件的最高版本为2.8,现在说说APM固件(源码)的版本。既然是开源项目,那么在github上肯定有仓库。曾经的APM源码存于code.google.com,后来github席卷全球,成为广泛接受的代码仓库,于是谷歌把自己的仓库关了(反正国内也上不去:-()。github上的源头在此:https://github.com/ArduPilot/ardupilot。其中的ArduCopter支持多旋翼、直升机等,四旋翼源码即在其中,但是别急着下载,先点击release看看源码版本。可以看到带Copter的最新版本是“Copter-3.4.0”,带ArduCopter的最新版本是“ArduCopter-3.2.1-apm-px4”,很多朋友直接参照网上的《通过Arduino给APM编译下载最新固件》用git克隆代码到本地,发现无法使用,问题就在于git获取的是最新版,而APM支持的最高版本是“ArduCopter-3.2.1-apm-px4”,从命名也可以发现,该版本固件同时支持APM和PX4。

        获取ArduCopter-3.2.1版本的源码有2种方式:I. 在github页面点击release,往下翻几页,找到“ArduCopter-3.2.1-apm-px4”下载即可。II. 喜欢git的朋友在克隆最新代码后,也可以回退到3.2.1的版本,与第一种方法获得的源码无异。

 
  1. git clone https://github.com/ArduPilot/ardupilot.git

  2. cd ardupilot/

  3. git branch -a

  4. git checkout -b arducopter-3.2.1 origin/ArduCopter-3.2.1

        使用方法解压之后就可以看到源码啦,结构如下。其中,APMrover2支持地面车辆,ArduPlane支持固定翼,ArduCopter支持多旋翼和直升机。对于四旋翼的开发,就对应ArduCopter文件夹。值得一提的是,打开ArduCopter文件夹后,可以看到一大波.pde文件,.pde为Arduino文件的旧版后缀,新版的为.ino(Arduino的后3个字母),可以简单类比成.cpp文件。熟悉C++的朋友可能会想去找main文件,这回改头换面了,主文件叫ArduCopter.pde。

APM开发环境

        巧妇难为无米之炊”,现在米有了,用什么工具做饭呢。先把火备好,即编译的工具链和驱动:MHV_AVR_Tools_20121007.exe(AVR单片机编译和下载程序用)和MissionPlanner-latest.msi(飞控地面站,含APM的USB接口驱动)。接下来就是用什么灶台做饭了,以Windows平台为例,灶台根据方便程度有2种:I. 土灶:ArduPilot-Arduino-1.0.3-gcc-4.7.2-windows(为ArdupPilot定制的Arduino IDE)。II. 电磁炉:Visual Studio配合Visual Micro插件(Arduino for Visual Studio插件)。二者本质没有区别,可以看到都是调用gcc工具链,Visual Studio只是通过Visual Micro在上层封装了操作接口,便于程序员查看和编写代码。强烈建议使用Visual Studio!!!

环境I(轻量). Arduino IDE

        先介绍Arduino派的IDE:ArduPilot-Arduino-1.0.3-gcc-4.7.2-windows,此IDE不同于普通的Arduino IDE,而是为ArdupPilot定制的。解压之后,打开“arduino.exe”,一张白板扑面而来。唯一和飞控有关的就在菜单栏上,相比通用ArduinoIDE多了“ArduPilot”一项。工具栏的“√”是编译,“→”是下载。

        点击“文件->参数设置”,可设置程序库的位置,即APM源码位置,注意不要勾选“启动时检查更新”,因为本IDE专为ArduPilot定制。其他选项可根据个人喜好设置。

        设置完成后退出再重开,以保证程序库位置生效。点击“文件->程序库->ArduCopter”,源代码一览无余。之后配置APM固件,主芯片:“工具->板卡->Arduino Mega 2560 or Mega ADK”,串口:“工具->串口->相应USB串口”(确保驱动已安装),编程器:“工具->编程器->AVRISP mkll”(默认),APM硬件型号:“ArduPilot->HALBoard->ArduPilot Mega 2.x”。

        至此,Arduino IDE的完毕,可以点击编译了。等待3分钟左右,编译完毕,生成一个hex文件用于下载到APM板。

        切记:不要下载!不要下载!不要下载!下载会变砖!

环境II(推荐). Visual Studio&Visual Micro

 

        Arduino IDE编译APM的代码还可以,但要是用来浏览和编写代码,那就是千丝万缕扭不清了,所以ArduinoIDE的设置里也机智地留下一条后路:“□使用外部编辑器”。

        Visual Studio(以下简称VS)作为宇宙最强IDE,怎么能不支持下Arduino,感谢微软救民于水火。以VS2012为例,点击“工具->扩展和更新->联机”,搜索“Visual Micro”,下载安装即可。顺便推荐下Visual Assist,VS下最好的代码补全工具,以前写1行代码的功夫,现在可以写3行~

        安装好之后,VS的菜单栏多了一些振奋人心的东西。“VMICRO”中可设置Arduino的选项,点击“VMICOR->Visual Micro Explorer”,如下图所示。对比Arduino IDE可发现,编译、下载、COM口应有尽有,还可适配不同的Arduino 版本。

        点击“Configure”进行配置,选择Arduino版本:1.0,配置Arduino目录,笔者的是:D:\Fly\ArduPilot-Arduino-1.0.3-windows,即ArduPilot-Arduino-1.0.3-gcc-4.7.2-windows解压后的文件夹。注意此插件的名字是“Arduino IDE for Visual Studio”,并不是专为Ardupilot/APM定制,因此还需适配apm硬件信息(点击蓝字链接下载,解压后为一名为apm的文件夹,内仅含boards.txt)。将该apm文件夹放入D:\Fly\ArduPilot-Arduino-1.0.3-windows\hardware中。配置完成之后,可在“Installed”选项卡中查看支持的硬件类型,如所需的“Arduino Mega 2560 HAL (Apm 2)”,插上APM后在COM口选择对应的串口号。此外,在“Examles”选项卡中可查看Arduino和ArduCopter的例程。

        重启VS,点击“文件->打开->Arduino Project”,选择ArduCopter文件夹中的ArduCopter.pde打开,即可在“解决方案资源管理器”中看到APM的源码结构。解释一下,ArduCopter.pde相当于平时常见的Main.cpp,在ArduCopter.pde的最后一行是真正的main函数。

AP_HAL_MAIN();

        除此之外,有一点需要注意,在“VMICRO”中,“Debugger”取消勾选“Automatic Debug(Release/Debug)”,否则会编译失败。因为APM2.8不支持在线Debug,同时对于“多线程”程序,Debug本身意义不大,一般采用串口print进行调试以便观察程序流程。对于普通Arduino板(如nano)可以勾选,下载后会自动进入调试状态。

        至此,Visual Studio&Visual Micro的配置完毕,又可以愉快地编译了。同样等待大概3分钟左右,可以看到编译完成,生成一个hex文件用于下载到APM板。对于编译,第1次会较慢,修改代码再次编译就很快了。

        切记:不要下载!不要下载!不要下载!下载会变砖!

        在此给出笔者用VS2012编译的工程:APM3.2.1固件-VS2012工程,打开ArduCopter文件夹中的ArduCopter.sln即可使用。如果你好奇心太重点了下载,也没关系,笔者会在下一篇博客让板砖起死回生:)

APM资料说明

        有关APM的资料,首推ArduPilot官网:http://ardupilot.org/ardupilot/。如果是开发四旋翼,左侧的“Copter”和“Developers”是你经常要去逛的。里面详细介绍了APM的方方面面,值得反复咀嚼。网上的APM资料,很多就是翻译自ArduPilot官网,但是良莠不齐。不要惧怕英文而选择逃避,蔡康永有一段很有名的话,“15岁觉得游泳难,放弃游泳,到18岁遇到一个你喜欢的人约你去游泳,你只好说"我不会耶”。18岁觉得英文难,放弃英文,28岁出现一个很棒但要会英文的工作,你只好说“我不会耶”。人生前期越嫌麻烦,越懒得学,后来就越可能错过让你动心的人和事,错过新风景。”万事开头难,但也不要放大开头的困难,跨过去就好了。

        国内的资料,主要推荐“模友之吧”里“泡泡老师”的视频教程,教你一步步上手APM2.8:[泡泡老师教程] 新手课堂:APM2.8的使用方法

        个人收集的2个资料:新编APM-2.8.0中文入门手册APM2.8接口介绍

  “月盈则亏,水满则溢”。当博主编译完成,以为离成功更近一步准备下载的时候,殊不知陷阱也早已准备好,等待我的踏入。连上USB线,下载,timeout...,timeout...,timeout...,留下博主一脸懵逼,和一块已然变砖的APM板。遂作此文,为广大APM开发者避开下载的坑。

        下载环境:APM2.8,固件版本3.2.1,通过USB下载。

原因定位

        事出突然,案发现场只留下了一张截图,代表着下载失败。

        从这张截图开始分析:avrdude是AVR系列单片机的下载模块,负责将hex文件写入APM板的ROM和EEPROM。写入文件之后,avrdude向APM板Send数据,估计用于校验,却等不到回应:“programmer is not responding”,只能向电脑返回:timeout,顺便不忘问候博主:“avrdude done. Thank you.”

        由此看来下载完程序之后,APM板直接变砖,已无法和PC端取得有效通信。博主经过多种尝试,如重新编译并下载、通过地面站(Mission Planner)刷固件、下载老版本固件,皆因timeout或无法连接而告终。痛定思痛,想到安卓手机刷机时也可能变砖,变砖后还能刷回来,靠的是什么?Bootloader!难道是因为程序过大,把APM板中的Bootloader,也就是引导程序给覆盖了?!

        回过头来看编译结果:编译之后,程序大小为256258bytes,也就是250KB的样子,占用了总容量的99%!很可能把Bootloader给占用了。就好比把一个很大的文件往电脑的C盘塞,把C盘塞爆了,顺便把系统也弄崩了。果不其然,查阅资料可知,APM 程序存储容量为256KB,其中8KB被Bootloader占用。如果程序大于248KB,当程序烧写进APM中时,会破坏APM的Bootloader。Bootloader破坏之后的现象就是:APM板上电后只有电源灯亮,且无法连接地面站。正是如此!

刷写Bootloader

        虽然Bootloader被博主无意中破坏,但天无绝人之路,从哪里弄坏,就从哪里修好。当自己买电子元器件和电路板,根据开源的APM硬件焊接APM板时,也需要给APM板重新烧写Bootloader。

硬件准备

        AVR单片机的USBASP或USBISP下载器×1。

软件准备

        1. 下载器配套软件,推荐progisp1.72。

        2. AVR的USB自编程软件:Flip。

        3. 32u2的驱动程序。

        4. 三个hex文件:Atmega2560的bootloader文件、32u2的bootloader文件和32u2的ppm程序文件。

        烧写过程概述:先给Atmega2560烧写bootloader,然后给Atmega32u2烧写bootloader,最后给32u2写入PPM解码通讯程序。

        烧写的视频教程(含驱动和hex文件下载):[泡泡老师教程] 新手课堂,如何给修复或空板APM烧写 Bootloader

        烧写的文字教程:烧写APM板的Bootloader

        按照视频教程操作即可,可以不用转接线,直接用几根杜邦线连接,注意线序。

程序裁剪与下载

        既然程序容量有限,就需要对程序进行裁剪,比如拿剪刀把APM板剪掉一角。好了正经一点,所谓裁剪,最简单的就是将部分程序注释或删除,使编译之后的程序容量变小。要想裁剪APM,首先需要对飞控程序的结构有个大致的了解,才能在注释或删除代码的同时保证飞控的稳定性。先看看官网是怎么介绍飞控程序的:“The ArduPilot code base is quite large (about 700k lines for thecore ardupilot git tree) and can be quite intimidating to a new user.”,翻译过来就是飞控代码太太太多了,足足70万行估计你这小白搞不定。

        “他强任他强,清风抚山岗。他横由他横,明月照大江。”虽然飞控代码多,但是程序员有两板斧子,一看代码结构,二看主函数。

        根据上篇博文所述,使用VS2012配合VM插件查看APM3.2.1工程代码,其代码主要由多个pde文件组成,可简单理解为cpp文件。根据pde文件的命名,博主将代码分为6类:(1)主函数ArduCopter;(2)各种飞行模式,占了大部分程序,如control_acro、control_althold、control_auto等;(3)系统初始化system;(4)Mavlink通信GCS_Mavlink;(5)用户程序UserCode;(6)其他杂项。既然飞行模式的程序最多,博主就准备拿它开刀。

        要裁剪飞行模式,就得看主函数是如何调用各飞行模式的。看大型代码一定要带着目的去看,既然通过遥控可以切换飞行模式,那么判断处于飞行模式的代码一定是在某个循环中。这样一来就好办了,从ArduCopter.pde的fast_loop()函数入手,可以看到其代码不多,列出如下。

 
  1. static void fast_loop()

  2. {

  3.  
  4. // IMU DCM Algorithm

  5. // --------------------

  6. read_AHRS();

  7.  
  8. // run low level rate controllers that only require IMU data

  9. attitude_control.rate_controller_run();

  10.  
  11. #if FRAME_CONFIG == HELI_FRAME

  12. update_heli_control_dynamics();

  13. #endif //HELI_FRAME

  14.  
  15. // write out the servo PWM values

  16. // ------------------------------

  17. set_servos_4();

  18.  
  19. // Inertial Nav

  20. // --------------------

  21. read_inertia();

  22.  
  23. // run the attitude controllers

  24. update_flight_mode();

  25.  
  26. // optical flow

  27. // --------------------

  28. #if OPTFLOW == ENABLED

  29. if(g.optflow_enabled) {

  30. update_optical_flow();

  31. }

  32. #endif // OPTFLOW == ENABLED

  33.  
  34. }

        细心的朋友可能注意到了,顾名思义,update_flight_mode()就是更新飞行模式的函数。右键转到定义或按快捷键F12,可查看update_flight_mode()中是一串熟悉的switch-case语句,根据不同的case切换不同的飞行模式。以常见的自稳模式stabilize为例,可一直追踪下去,如高度控制,电机控制等。醉翁之意不在酒,在乎“飞行模式”也。

        目前已了解飞行模式如何调用,那么裁剪也就很自然了——注释掉暂时不同的飞行模式。博主将APM所支持的飞行模式列举如下,用的最多的当属自稳STABILIZE和悬停LOITER,因此可将其他的一些飞行模式注释掉。博主所用S500无人机的遥控器为6通道,开关SWC拨到上为自稳模式,拨到中为悬停模式,因此博主在代码中只保留了自稳STABILIZE、定高ALT_HOLD、悬停LOITER和降落LAND共4种模式。

        将飞行模式裁剪后,重新编译代码,惊喜出现了,程序容量从99%降到了89%。现在自信地下载代码,成功!快给博主点个赞~

        温馨提示:下载源码不会改变APM中传感器的参数,如加速度计、罗盘等,其参数在APM板的EEPROM中,通过地面站的一系列校准步骤写入。有关地面站的使用,详见新编APM-2.8.0中文入门手册

APM飞控学习之路:5 串口概述与收发调试

2016年11月23日 20:11:23

阅读数:9558

        “云中谁寄锦书来,雁字回时,月满西楼”。当无人机在空中飞翔时,从APM飞控到飞手之间有几条看不见的“风筝线”——(1)2.4GHz的遥控;(2)433/915MHz的数传;(3)5.8GHz的图传;(4)osd(on-screen display)。其中遥控是大家最为熟知的,用于控制飞行和切换模式。数传说白了是一个披着射频的皮的无线串口,波特率57600,连接地面站可实时观测飞行数据和在线调参。图传是FPV(First Person View)必备,传输视频信号用于航拍。osd是锦上添花的部件,将飞行数据叠加到视频信号上一起传回地面接收机。

        遥控、图传和osd都是很成熟的产品,对于开源用户来说定制性不强,而数传可以传回用户感兴趣的任何数据以及在线调参,实为居家必备之良品。如果选购与APM适配的3DR数传,无需任何修改,插上APM即可在地面站(Mission Planner)监测无人机的飞行数据。从功能上看,数传与下载程序兼具串口功能的USB线别无二致,只是形态上有线无线而已。二者的技术基础是串口以及基于串口的Mavlink通信,本文主要讨论如何使用APM中的串口并进行二次开发。

APM2.8串口概述


        串口的英文名是UART,全称Universal Asynchronous Receiver/Transmitter,即通用异步接收/发送机,只要一对传输线(RX-TX)即可实现双向通信。串口通过USB转TTL模块可插在电脑的USB口,在设备管理器上体现为COM口,是单片机调试和通信的重要接口。

        对于APM2.8飞控,其主控芯片为Atmega2560,有4个串口,分别为UART0~UART3,在APM中起作用的只是前3个,即UART0、UART1和UART2。UART0接USB,UART1接GPS,UART2接数传。

        APM3.2.1源码为适应除APM之外的不同硬件(如PIXHAWK),在硬件抽象层HAL(Hardware Abstraction Layer)提供了通用的外设接口。在HAL.h中可以查看HAL类的声明,串口方面保留了_uartA~_uartE共5个。

 
  1. class AP_HAL::HAL {

  2. public:

  3. HAL(AP_HAL::UARTDriver* _uartA, // console

  4. AP_HAL::UARTDriver* _uartB, // 1st GPS

  5. AP_HAL::UARTDriver* _uartC, // telem1

  6. AP_HAL::UARTDriver* _uartD, // telem2

  7. AP_HAL::UARTDriver* _uartE, // 2nd GPS

  8. AP_HAL::I2CDriver* _i2c,

  9. AP_HAL::SPIDeviceManager* _spi,

  10. AP_HAL::AnalogIn* _analogin,

  11. AP_HAL::Storage* _storage,

  12. AP_HAL::UARTDriver* _console,

  13. AP_HAL::GPIO* _gpio,

  14. AP_HAL::RCInput* _rcin,

  15. AP_HAL::RCOutput* _rcout,

  16. AP_HAL::Scheduler* _scheduler,

  17. AP_HAL::Util* _util)

  18. :

  19. uartA(_uartA),

  20. uartB(_uartB),

  21. uartC(_uartC),

  22. uartD(_uartD),

  23. uartE(_uartE),

  24. i2c(_i2c),

  25. spi(_spi),

  26. analogin(_analogin),

  27. storage(_storage),

  28. console(_console),

  29. gpio(_gpio),

  30. rcin(_rcin),

  31. rcout(_rcout),

  32. scheduler(_scheduler),

  33. util(_util)

  34. {}

  35.  
  36. virtual void init(int argc, char * const argv[]) const = 0;

  37.  
  38. AP_HAL::UARTDriver* uartA;

  39. AP_HAL::UARTDriver* uartB;

  40. AP_HAL::UARTDriver* uartC;

  41. AP_HAL::UARTDriver* uartD;

  42. AP_HAL::UARTDriver* uartE;

  43. AP_HAL::I2CDriver* i2c;

  44. AP_HAL::SPIDeviceManager* spi;

  45. AP_HAL::AnalogIn* analogin;

  46. AP_HAL::Storage* storage;

  47. AP_HAL::UARTDriver* console;

  48. AP_HAL::GPIO* gpio;

  49. AP_HAL::RCInput* rcin;

  50. AP_HAL::RCOutput* rcout;

  51. AP_HAL::Scheduler* scheduler;

  52. AP_HAL::Util* util;

  53. };

        落实到APM2.8飞控板上,从HAL_AVR_APM2_Class.cpp中可以查看串口的对应关系,同样可以得出只用了前3个,且UART0接USB,UART1接GPS,UART2接数传。源码与飞控板,一个底层,一个上层,“默契”地达成了一致。

 
  1. HAL_AVR_APM2::HAL_AVR_APM2() :

  2. AP_HAL::HAL(

  3. &avrUart0Driver, /* phys UART0 -> uartA */

  4. &avrUart1Driver, /* phys UART1 -> uartB */

  5. &avrUart2Driver, /* phys UART2 -> uartC */

  6. NULL, /* no uartD */

  7. NULL, /* no uartE */

  8. &avrI2CDriver,

  9. &apm2SPIDriver,

  10. &avrAnalogIn,

  11. &avrEEPROMStorage,

  12. &avrUart0Driver,

  13. &avrGPIO,

  14. &apm2RCInput,

  15. &apm2RCOutput,

  16. &avrScheduler,

  17. &avrUtil )

  18. {}

        如果大家仔细观察上面APM2.8的方框图,可以发现数传和USB接口都是走的UART0,这是为何?因为APM2.8采用了一种MUX复用的方式,使得当数传与USB同时接上的时候,USB会把数传屏蔽,即UART0占主导地位。在此祭出硬件原理图,TS5A23157是一个模拟开关,3DR代表数传。当USB和数传同时接上时,模拟开关会将3DR_RX与RX0接上,3DR_TX与TX0接上,即串口0把数传给屏蔽了。

串口源码分析

        一个串口要发挥作用,首先需要初始化,即配置波特率、设置起始位等操作。对于STM32单片机(用于PIXHAWK),还有串口中断等配置。APM中的Arduino单片机比较简单,只需配置好波特率,其余保持默认即可。

        Arduino程序的初始化,一般在setup()函数中。不出所料,串口的初始化也在其中,见ArduCopter.pde的setup()函数,可以看到初始化函数init_ardupilot()。

 
  1. void setup()

  2. {

  3. cliSerial = hal.console;

  4.  
  5. // Load the default values of variables listed in var_info[]s

  6. AP_Param::setup_sketch_defaults();

  7.  
  8. // setup storage layout for copter

  9. StorageManager::set_layout_copter();

  10.  
  11. init_ardupilot();

  12.  
  13. // initialise the main loop scheduler

  14. scheduler.init(&scheduler_tasks[0], sizeof(scheduler_tasks)/sizeof(scheduler_tasks[0]));

  15. }

        在Visual Studio+VMICRO的环境下,按F12或鼠标右键可转到init_ardupilot()的定义,在system.pde的init_ardupilot()中摘出与uartA有关的代码以便分析。

 
  1. hal.uartA->begin(map_baudrate(g.serial0_baud), 512, 128);,

  2.  
  3. //gcs[0].init(hal.uartA);

  4.  
  5. hal.uartA->set_blocking_writes(false);

        第1行和第3行很好理解,分别是uartA设置波特率(115200)和非阻塞模式,第2行的gcs[0]容易让人迷惑。gcs的全称为Ground Control Station,即地面工作站。再转到gcs的定义,可发现其数据类型为GCS_MAVLINK,由此可断定该行代码的作用是绑定Mavlink和uartA,将数据以Mavlink协议与地面站通信。为单独测试串口收发,可取消uartA与Mavlink的绑定,即注释掉gcs所在行的代码。

串口数据收发


        初始化搞定之后,就可以进行简单的串口收发测试——串口助手发数据给飞控,飞控返回原数据。串口的接收一般有2种方式:查询或中断。Arduino中的串口中断函数为SerialEvent,是一种软中断,博主将Arduino nano板中测试通过的串口中断代码移植到APM源码中,发现并不起作用。原因尚不明确,或许 APM板本身并不支持,也可能是博主移植的地方不合适。期待有心人进行尝试,欢迎留言讨论。
        为了推进测试进程,转向查询方式。有2种方式:1.在ArduCopter.pde的fast_loop中查询;2.在UserCode.pde中添加代码。如果要使用UserCode.pde,需在ArduCopter.pde添加相应的宏,才能将UserCode.pde加入编译。为了方便,博主在fast_loop()中添加串口接收查询代码:

 
  1. static void fast_loop()

  2. {

  3.  
  4. // IMU DCM Algorithm

  5. // --------------------

  6. read_AHRS();

  7.  
  8. // run low level rate controllers that only require IMU data

  9. attitude_control.rate_controller_run();

  10.  
  11. #if FRAME_CONFIG == HELI_FRAME

  12. update_heli_control_dynamics();

  13. #endif //HELI_FRAME

  14.  
  15. // write out the servo PWM values

  16. // ------------------------------

  17. set_servos_4();

  18.  
  19. // Inertial Nav

  20. // --------------------

  21. read_inertia();

  22.  
  23. // 串口接收查询 by--岳小飞

  24. while (hal.uartA->available())

  25. {

  26. uint8_t data = (uint8_t)hal.uartA->read();

  27. hal.uartA->write(data);

  28. }

  29.  
  30. // run the attitude controllers

  31. update_flight_mode();

  32.  
  33. // optical flow

  34. // --------------------

  35. #if OPTFLOW == ENABLED

  36. if(g.optflow_enabled) {

  37. update_optical_flow();

  38. }

  39. #endif // OPTFLOW == ENABLED

  40.  
  41. }

        打开串口,APM飞控会发出一串提示字符,包括版本信息,如“Init ArduCopter V3.2.1”。博主发送“YueXiaoFei”,飞控原样返回,测试通过。基于这个简单的收发测试,大家可自定义数据协议,发送和接收感兴趣的飞行数据,也可学习基于串口的Mavlink协议。

        PS:无人机系列的第5篇至此结束,系列博客也随之告一段落。就应用方面而言,从入门到编译,从编译到调试,博主尽可能地将问题讲清楚,所有资料免积分下载,也算是为开源贡献自己的一份力吧。博客中可能存在一些小错误,也欢迎大家在评论区批评指正。力有不逮,敬请见谅~

猜你喜欢

转载自blog.csdn.net/lixia755324/article/details/81295070