源码框架
pixhawk代码框架:
pixhawk代码框架基础分析:
- 阅读下面内容时请结合源码阅读,便于理解。
The basic structure of ArduPilot is broken up into 5 main parts:
- (1) vehicle directories
- (2) AP_HAL
- (3) libraries
- (4) tools directories
- (5) external support code
(1)Vehicle Directories
The vehicle directories are the top level directories that define the firmware for each vehicle type. Currently there are 4 vehicle types – Plane、 Copter、APMrover2 and AntennaTracker。
Along with the *.cpp files, each vehicle directory contains a make.inc file which lists library dependencies. The Makefiles read this to create the -I and -L flags for the build.
(2) AP_HAL
The AP_HAL layer (Hardware Abstraction Layer) is how we make ArduPilot portable to lots of different platforms。 There is a top level AP_HAL in libraries/AP_HAL that defines the interface that the rest of the code has to specific board features, then there is a AP_HAL_XXX subdirectory for each board type, for example AP_HAL_AVR for AVR based boards, AP_HAL_PX4 for PX4 boards and AP_HAL_Linux for Linux based boards。
(3) libraries
(4) Tools directories
The tools directories are miscellaneous support directories. For examples, tools/autotest provides the autotest infrastructure behind the autotest.diydrones.com site and tools/Replay provides our log replay utility.
(5) External support code
On some platforms we need external support code to provide additional features or board support. Currently the external trees are:
- PX4NuttX – the core NuttX RTOS used on PX4 boards
- PX4Firmware – the base PX4 middleware and drivers used on PX4 boards
- uavcan – the uavcan CANBUS implementation used in ArduPilot
- mavlink – the mavlink protocol and code generator
2)Libraries介绍
(1)核心库
AP_AHRS:采用DCM(方向余弦矩阵方法)或EKF(扩展卡尔曼滤波方法)预估飞行器姿态。
AP_Common:所有执行文件(sketch格式,arduino IDE的文件)和其他库都需要的基础核心库。
AP_Math:包含了许多数学函数,特别对于矢量运算。
AC_PID:PID控制器库。
AP_InertialNav:扩展带有gps和气压计数据的惯性导航库。
AC_AttitudeControl:姿态控制相关库。
AP_WPNav:航点相关的导航库。
AP_Motors:多旋翼和传统直升机混合的电机库。
RC_Channel:更多的关于从APM_RC的PWM输入/输出数据转换到内部通用单位的库,比如角度。
AP_HAL,AP_HAL_AVR,AP_HAL_PX4:硬件抽象层库,提供给其他高级控制代码一致的接口,而不必担心底层不同的硬件。AP_HAL_PX4:GPIO、I2C、UART、RCinput/output、scheduler、semaphores、storage。
(2)传感器相关库
AP_InertialSensor:读取陀螺仪和加速度计数据,并向主程序执行标准程序和提供标准单位数据(deg/s,m/s)。
AP_RangerFinder:声呐和红外测距传感器的交互库
AP_Baro:气压计相关库
AP_GPS:GPS相关库
AP_Compass:三轴罗盘相关库
AP_OpticalFlow:光流传感器相关库
(3)其他库
AP_Mount,AP_Camera, AP_Relay:相机安装控制库,相机快门控制库
AP_Mission: 从eeprom(电可擦只读存储器)存储/读取飞行指令相关库
AP_Buffer:惯性导航时所用到的一个简单的堆栈(FIFO,先进先出)缓冲区
AP_AccelCal、AP_Declination、AP_RCMapper、AP_RPM、AP_RSSI
AP_ADC:Analog to Digital
APM_Control: pitch/roll/yaw controller
DataFlash:flash memory
GCS_Console/GCS_MAVLink:地面站通信、飞行日志
3)关于主控MCU STM32F4的选择和协处理器STM32F1
在源代码中,大部分代码都是运行在主控MCU STM32F4芯片上,并且是通过直接配置寄存器来实现相应的功能,代码位于“/ardupilot/modules/PX4Firmware/Build/px4fmu-v2_APM.build/nuttx-export/arch/chip”中。
4)关于pixhawk使用的OS:NuttX
在modules /PX4NuttX/nuttx/sched文件中有os_start.c定义文件,内部进行了一系列的关于操作系统的初始化。在os_start()函数里面进行了如下初始化。
以上并非必须初始化,可以有选择性的初始化。Ifdef/ifndef….
重点了解一下关于nuttx中的modules /PX4NuttX/nuttx/mm。
5)姿态控制的软件流程
简单的软件流程官方给出了大致的介绍,该部分详见官方介绍:Code Overview
6)再深入一点
如下顺序不分先后,都是平时自己整理的,等以后对ardupilot的整体框架了解的比较透彻以后再回头修改吧。
- 1)关于飞行模式
- 2)关于参数的使用
- 3)关于一些报警和灯显、日志
- 4)关于校准和失控保护
- 5)关于RC输入和输出(接收机)
- 6)关于机型选择和电机控制
代码赏析:
如下事例摘自motors.cpp中的一段关于电机解锁和上锁的源码
// arm_motors_check - checks for pilot input to arm or disarm the copter
// called at 10hz
void Copter::arm_motors_check()
{
static int16_t arming_counter;
// ensure throttle is down首先判断油门是否为最小
if (channel_throttle->control_in > 0)
{
arming_counter = 0;
return;
}
//油门最小则检测yaw的行程量
int16_t tmp = channel_yaw->control_in;
// full right 解锁
if (tmp > 4000)
{
// increase the arming counter to a maximum of 1 beyond the auto trim counter
if( arming_counter <= AUTO_TRIM_DELAY )
{
arming_counter++;
}
// arm the motors and configure for flight
if (arming_counter == ARM_DELAY && !motors.armed())
{
// reset arming counter if arming fail
if (!init_arm_motors(false))
{
arming_counter = 0;
}
}
// arm the motors and configure for flight
if (arming_counter == AUTO_TRIM_DELAY && motors.armed() && control_mode == STABILIZE)
{
auto_trim_counter = 250;
// ensure auto-disarm doesn't trigger immediately
auto_disarm_begin = millis();
}
// full left 上锁
}
else if (tmp < -4000)
{
if (!mode_has_manual_throttle(control_mode) && !ap.land_complete) {
arming_counter = 0;
return;
}
// increase the counter to a maximum of 1 beyond the disarm delay
if( arming_counter <= DISARM_DELAY )
{
arming_counter++;
}
// disarm the motors
if (arming_counter == DISARM_DELAY && motors.armed())
{
init_disarm_motors();
}
// Yaw is centered so reset arming counter
}
Else
{
arming_counter = 0;
}
}