远征2号飞控例行报告,APM源代码分析及介绍(科创基金资助项目)(内容持续更新)
17031152016/08/26喷气推进 IP:广东
感谢科创基金,感谢科创基金,感谢科创基金(重要的事情说三遍)以及百度文科,百度图片,APM官网XXXXXXXXXXXXXXXXXXXXXXXXXXX/ardupilot/XXXXXXXXml。周末上图和测试(最近没空,学校补课)

前言
随着自制固体火箭的发展,数据的记录与回收以成为固体火箭最关键的技术所在,尤其是一些大型的固体探空火箭必不可少的一部分。可是一般使用的开伞系统都是由arduino设定的定时开伞和姿态或高度开伞,但是数据的记录和降落后的找回工作很难开展。即使找到了火箭的降落位置,有些数据也可能丢失难以修复,造成无法挽回的后果。能否有一种可是实现数据,视频,位置远程传输且易于编程的航电系统?在远征一号探空火箭回收失败后,远征系列探空火箭设计组选择对APM飞控进行开发研究。(图少了点,请笑纳!)
一.APM的简介
(1).APM发展历史
引/XXXXXXXXXXXXXXXXXXXXXX/XXXXXXXXXXXXXXXXml的介绍
2007年5月 – 克里斯·安德森用乐高 mindstorm搭建无人机时,建立了 XXXXXXXXXXXXX .

2008年9月– Jordi 制作了一个可以自动飞行的传统直升机无人机并赢得了第一届Sparkfun AVC大赛.

2009年 – 克里斯·安德森和Jordi Munoz 成立了3D Robotics(3DR)

2009年5月 – Jordi/3DRobotics 发布了第一款Ardupilot板子 (使用红外温度传感器)

2009年11月 – Jordi创建了ardupilot代码仓库

2009年11月 – Jordi, Doug Weibel, Jose Julio编写了第一版使用William Premerlani的DCM算法的ArduIMU

2009年11月 至 2010年2月 – Jason从头开始重写了 (v2.5),包括了使用中断驱动的遥控信号输入, 遥控油门保护, 返航, 悬停, 绕圈, 垂直航路修正, 更佳的稳定性, 全数字电传操纵, 系统事件, 四通道RC输出, 2线通信的数传. (Post)

2009年12月 – Doug 推出了改善了的 Ardupilot v2.4,第一次支持基于IMU的飞行器任务飞行

2010年 – 3d Robotics 推出了APM1

2010年初 – Doug and Jason 发布了Ardupilot 2.6 ,改善了油门控制, 支持ArduIMU

2010年夏天 – APM Code development:
• Jason – 任务脚本, 飞行模式, 导航
• Jose – 代码库, DCM, and 硬件传感器支持
• Doug – 高级飞行控制, 飞行日志记录, DCM
• MikeS – 参数, CLI, 高速串口, 高级硬件优化




2010年5月 – Ardupilot合并了AeroQuad (包括Jani Hirvinen) ,开始在ArduCopterNG(海盗)进行工作。

2010年6月 – APM 1 在SW上实现了自主任务脚本飞行。

2010年6月 – APM1首次让固定翼飞机实现了自主飞行。


360截图20160826212719801.jpg
360截图20160826212917622.jpg
360截图20160826212926777.jpg

二、性能特点
1.免费的开源程序,ArduRover模式支持地面车辆
2.体积小,重量轻,有八个输出电路,更加强大的控制程序
2.人性化的图形地面站控制软件,通过一根Micro_USB线,一套无线数传连接或使用lz的GPRS数传,鼠标点击操作就可以进行设置和下载程序到控制板的MCU中,无需编程知识和下载线等其它硬件设备。但如果你想更深入的了解APM的代码的话,你仍旧可以使用Arduino来手动编程下载
3.基于MAVLink 协议,支持双向遥测和实时传输命令
4.多种免费地面站可选,包括Mission Planner ,HK GCS等,还可以使用手机上的地面站软件,地面站中空中视频显示,语音合成和查看飞行记录等

三、硬件构成
o 核心MCU采用ATMEL的8bit ATMEGA2560
o 整合三轴陀螺仪与三轴加速度的六轴MEMS传感器MPU6000
o 高度测量采用高精度数字空气压力传感器MS-5611
o 板载16MB的AT45DB161D存储器
o 三轴磁力计HMC5883
o 8路PWM控制输入
o 11路模拟传感器输入
o 11路PWM输出(8路电源输出+3路云台增稳)
o GPS 模块可选MTK 3329及支持ublox输出的NEO-6M、7M、LEA-6H等
o 可屏蔽板载PPM解码功能,外接PPM解码板或者外接PPM接收机
o 可屏蔽板载罗盘通过I2C接口使用外置扩展罗盘
o OSD模块,将无人机姿态、模式、速度、位置等重要数据叠加到图像上实时回传
o 电流电压传感器 (控制电流电压的输入)
o (可扩展)其它UART、I2C、SPI设备
五、飞控板概览 (图片摘自网络)
正面图
360截图20160826213133219.jpg
1、数传接口
2、模拟传感器接口
3、增稳云台输出接口
4、ATMEGA2560 SPI在线编程接口(可用于光流传感器)
5、USB接口
6、遥控输入
7、功能选择跳线(最下的为内置,外置罗盘选择)
8、GPS接口
9、I2C外接罗盘接口
10、ATMEGA32U2 SPI在线编程接口
11、多功能可配置MUX接口(默认为OSD输出)
12、电流电压接口
13、电调供电选择跳线(插上用电流计供电)
14、电调输出接口
背面图
360截图20160826213149390.jpg
1、SPI的MISO电压选择
2、PPM输入选择
3、MUX接口功能选择

介绍到此结束更多教程上网百度。

四,APM飞控系统主程序安排。
是固定翼飞机的。
XXXXXXXXXXXXXXXXXXXXXXXXXXX/ardupilot/XXXXXXXXml找到的。

void loop()
{
	// We want this to execute at 50Hz if possible
	// -------------------------------------------
	if (millis()-fast_loopTimer > 19)                                       1
{
		delta_ms_fast_loop	= millis() - fast_loopTimer;                    2
		load= (float)(fast_loopTimeStamp - fast_loopTimer)/delta_ms_fast_loop; //cpu使用率                                                                   3
		G_Dt=(float)delta_ms_fast_loop/1000.f; //陀螺仪积分时间(DCM算法) 4
		fast_loopTimer  = millis();                                       5

		mainLoop_count++;                                             6

		// Execute the fast loop
		// ---------------------
		fast_loop();                                                    7

		// Execute the medium loop
		// -----------------------
		medium_loop();                                                8

		counter_one_herz++;                                            9
		if(counter_one_herz == 50)                                       10
{
			one_second_loop();                                         11
			counter_one_herz = 0;                                       12
		}

		if(millis()-perf_mon_timer>20000)                                 13
{       //性能监控时间到,执行性能监控
			if (mainLoop_count != 0)                                     14
{
				gcs.send_message(MSG_PERF_REPORT);                   15
				if (g.log_bitmask & MASK_LOG_PM)                      16
					Log_Write_Performance();                            17
				resetPerfData();                                         18
			}
		}

		fast_loopTimeStamp = millis();                                    19
	}
}

以上是飞控系统的主循环程序,有19条语句,我在右侧标了语句号。循环的频率是50Hz,与标准舵机控制频率相同,这是通过第一条语句if (millis()-fast_loopTimer > 19)实现的,这个语句中millis( )函数在程序开始运行后开始执行,中间不停顿,返回的是从程序开始一直到当前的时间(毫秒),在第5条语句有fast_loopTimer = millis(); 所以if (millis()-fast_loopTimer > 19)的意思就是如果现在的时间距离上一次执行时间超过了19ms,也就是20ms的时候,就会执行一次下面所有的程序,如果不满足条件,就一直等待。
接下来从第2条语句到第6条,除了第三条语句是计算主程序执行一次的时间外(可以认为是CPU使用率),其他的都是做标记用。
接下来的程序是执行fast_loop()、medium_loop()、one_second_loop()以及20秒一次的性能监视。此外,在medium_loop( )中还会调用slow_loop( )(执行周期1/3s)。其他语句是辅助作用。飞控系统的主程序执行的就是这几个子程序。以下一一说明功能。
(1) fast_loop( ) : 这是飞控系统控制的控制核心之一。执行频率50Hz。程序如下:

void fast_loop()
{
	// This is the fast loop - we want it to execute at 50Hz if possible
	// -----------------------------------------------------------------
	if (delta_ms_fast_loop > G_Dt_max)
		G_Dt_max = delta_ms_fast_loop;

	// Read radio         ////读取遥控信号
	// ----------
	read_radio(); //APM_RC.InputCh(CH_ROLL)-> ch1_temp-> g.channel_roll.set_pwm(ch1_temp)(即转为control_in)
	                //油门还有control_failsafe(g.channel_throttle.radio_in);
                    //g.channel_throttle.servo_out = g.channel_throttle.control_in;
                    //airspeed_nudge,throttle_nudge,

	// check for loss of control signal failsafe condition    ////检查丢失控制信号故障安
	// ------------------------------------
	check_short_failsafe();           //关于failsafe和ch3_failsafe的处理
	
		// Read Airspeed        ///读取空速
		// -------------
	if (g.airspeed_enabled == true && HIL_MODE != HIL_MODE_ATTITUDE) 
{  		//使能空速计真实飞行时为1
read_airspeed();     //读取空速,并calc_airspeed_errors();
	} 
else if (g.airspeed_enabled == true && HIL_MODE == HIL_MODE_ATTITUDE) 
{   //真实飞行时为0
		calc_airspeed_errors();
	}

	#if HIL_MODE == HIL_MODE_SENSORS    //飞行模式时为0
		// update hil before dcm update
		hil.update();
	#endif

	dcm.update_DCM(G_Dt);             ////更新DCM

	// uses the yaw from the DCM to give more accurate turns    ///使用从DCM获得的偏航数据,进行更精确的转弯
	calc_bearing_error();        //计算得出bearing_error

	# if HIL_MODE == HIL_MODE_DISABLED     //飞行模式时为1
		if (g.log_bitmask & MASK_LOG_ATTITUDE_FAST)
			Log_Write_Attitude((int)dcm.roll_sensor, (int)dcm.pitch_sensor, (uint16_t)dcm.yaw_sensor);

		if (g.log_bitmask & MASK_LOG_RAW)
			Log_Write_Raw();
	#endif

	// inertial navigation          ////惯性导航
	// ------------------
	#if INERTIAL_NAVIGATION == ENABLED      //这个不执行。本程序的捷联惯性导航算法只能计算飞机飞行姿态,无法结算三维位置,,所以,不能实施完全的惯性导航。或者程序作者正在进行相关试验,或者程序作者的惯性导航不是这个意思,仅是调试时调用这个。
		// TODO: implement inertial nav function  //实施惯性导航功能
		inertialNavigation();       
	#endif

	// custom code/exceptions for flight modes     ///飞行模式的自定义代码/异常
	// ---------------------------------------
	update_current_flight_mode();   //  导航级PID

	// apply desired roll, pitch and yaw to the plane   ////控制飞机的副翼,升降,方向      	if (control_mode > MANUAL)                                                                                                                  		stabilize();               //  控制级PID                                                                                                                                                                                                                                                                    	//write out the servo PWM values 
//
	set_servos_4();     
                                                                                                                            
	// XXX is it appropriate to be doing the comms below on the fast loop?   ////现在适合做快速环路上的COMMS吗?

	#if HIL_MODE != HIL_MODE_DISABLED && HIL_PORT != GCS_PORT  //飞行模式时为0
		// kick the HIL to process incoming sensor packets //使用HIL处理传入的传感器数据包
		hil.update();

		#if HIL_PROTOCOL == HIL_PROTOCOL_MAVLINK
			hil.data_stream_send(45,1000);
		#else
			hil.send_message(MSG_SERVO_OUT);
		#endif
	#elif HIL_PROTOCOL == HIL_PROTOCOL_MAVLINK && HIL_MODE == HIL_MODE_DISABLED && HIL_PORT == 0   //飞行模式时为1
		// Case for hil object on port 0 just for mission planning  //HIL端口的对象,只是用来进行任务规划
		hil.update();
		hil.data_stream_send(45,1000);
	#endif

	// kick the GCS to process uplink data      ////让GCS处理上行数据
	gcs.update();
	#if GCS_PROTOCOL == GCS_PROTOCOL_MAVLINK  //飞行模式时为
		gcs.data_stream_send(45,1000);
	#endif
	// XXX this should be absorbed into the above,
	// or be a "GCS fast loop" interface
}

这是fast_loop程序。语句后含有对程序的解释说明。
(2) medium_loop( ),这是飞控系统的另外一个核心,执行频率10Hz。用于执行GPS数据和磁力计数据的更新、根据GPS数据进行导航计算、更新高度信息和命令、向地面发送无线数传数据、控制slow_loop( )执行和其他。其中对导航起很重要作用的导航航向的计算就再medium_loop( )中执行。
(3) slow_loop( ),执行周期是1/3s。主要执行长时间故障安全检查、读取三段开关、读取舵面正方向及混控开关、读取地面站指令等操作。
(4) one_second_loop( ),执行周期1s。主要执行记录电池电压、发送CPU使用时间等操作。
五,APM飞控系统在远征2号的改进之处

(1). 3DR无线数传。
3DR无线数传是APM的一个数传模块,我们用的数传模块发射接收频率是433MHz,功率是100mw,有效距离大约是500米左右。但基于中大型固体探空火箭,回收半径大,所有传输信号很可能无法接收。
改进方法:推荐使用GPRS数传,基于网络服务器的远程传输,以下就不再细说。
(2).地面站的手机端连接方式与支持的系统。
前面有介绍APM的地面端包括手机端,可是要运行手机端手机必须有谷歌的通信协议,额且连接方式不是GPRS链接。参照网友在APM论坛上发送的资源,取消了对谷歌的依赖,且添加了GPRS的服务器终端的连接。
(3).arduion的程序改写。
APM的元程序可以通过ardoion改写,团队已经整理出了一个比较乱的代码,用于控制8路输出端为火箭开伞,整理完毕就发上论坛。
内容持续更新……

[修改于 8年5个月前 - 2016/08/26 22:03:00]

来自:航空航天 / 喷气推进
2
1
已屏蔽 原因:{{ notice.reason }}已屏蔽
{{notice.noticeContent}}
~~空空如也
chenhello2
8年0个月前 IP:陕西
829741
学习了,十分感谢!期待更新。pixhawk和APM用一样的源代码吗?
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论

想参与大家的讨论?现在就 登录 或者 注册

所属专业
上级专业
同级专业
1703115
学者 机友 笔友
文章
34
回复
176
学术分
3
2014/11/03注册,3年6个月前活动

1703115,17岁火箭工程师,远征系列探空火箭总设计师。

主体类型:个人
所属领域:无
认证方式:手机号
IP归属地:广东
插入公式
评论控制
加载中...
文号:{{pid}}
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

加载中...
详情
详情
推送到专栏从专栏移除
设为匿名取消匿名
查看作者
回复
只看作者
加入收藏取消收藏
收藏
取消收藏
折叠回复
置顶取消置顶
评学术分
鼓励
设为精选取消精选
管理提醒
编辑
通过审核
评论控制
退修或删除
历史版本
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{format('YYYY/MM/DD HH:mm:ss', toc)}}