代码执行流程
1. 编译时将cmake/configs/nuttx_px4fmu-v2_default.cmake文件中配置的模块全部编译并烧写到固件中去。
2. 地面站的配置会在flash中生成/fs/mtd_params文件,该文件包含了飞行器的各类信息(机架,校准信息,飞行模式等)。
3. 启动pixhawk,执行/Firmware/ROMFS/px4fmu_common/init.d/rcS,该文件会读入之前生成的参数文件,进而选择执行哪一个脚本文 件。(如选择DJI450机架会执行/Firmware/ROMFS/px4fmu_common/init.d/rc.mc_apps 和/Firmware/ROMFS/px4fmu_common/init.d/4011_dji_f450),它们的主要作用为启动飞控所需的各类软件。
4. 不同模块通过uORB通信。
上图形象说明启动流程
以下为代码做了部分注释
rcS
#!nsh
#
# PX4FMU startup script.
#
# NOTE: COMMENT LINES ARE REMOVED BEFORE STORED IN ROMFS.
#
#
# Start CDC/ACM serial driver
#
sercon
#
# Default to auto-start mode. //一些默认设置
#
set MODE autostart
set FRC /fs/microsd/etc/rc.txt
set FCONFIG /fs/microsd/etc/config.txt
set TUNE_ERR ML<> $LOG_FILE
set IO_PRESENT yes
else
echo "PX4IO Trying to update" >> $LOG_FILE
tone_alarm MLL32CP8MB
if px4io start//启动px4io
then
# try to safe px4 io so motor outputs dont go crazy
if px4io safety_on//判断px4io是否安全
then
# success! no-op
else
# px4io did not respond to the safety command
px4io stop
fi
fi
if px4io forceupdate 14662 ${IO_FILE}//是否强制升级
then
usleep 500000
if px4io checkcrc $IO_FILE
then
echo "PX4IO CRC OK after updating" >> $LOG_FILE
tone_alarm MLL8CDE
set IO_PRESENT yes
else
echo "ERROR: PX4IO update failed" >> $LOG_FILE
tone_alarm $TUNE_ERR
fi
else
echo "ERROR: PX4IO update failed" >> $LOG_FILE
tone_alarm $TUNE_ERR
fi
fi
unset IO_FILE
if [ $IO_PRESENT == no ] //没有找到px4io
then
echo "[i] ERROR: PX4IO not found"
echo "ERROR: PX4IO not found" >> $LOG_FILE
tone_alarm $TUNE_ERR
fi
fi
#
# Set default output if not set//如果不设置,则为默认设置none
#
if [ $OUTPUT_MODE == none ]
then
if [ $USE_IO == yes ] //px4的版本为v2,所以条件满足
then
set OUTPUT_MODE io
else
set OUTPUT_MODE fmu
fi
fi
if [ $OUTPUT_MODE == io -a $IO_PRESENT != yes ]
then
# Need IO for output but it not present, disable output//需要IO口输出,但是它不存在
set OUTPUT_MODE none
echo "[i] ERROR: PX4IO not found, disabling output"
# Avoid using ttyS0 for MAVLink on FMUv1
if ver hwcmp PX4FMU_V1//比较px4的版本
then
set FMU_MODE serial //设置FMU_MODE为serial模式
fi
fi
if [ $OUTPUT_MODE == ardrone ]
then
set FMU_MODE gpio_serial
fi
if [ $HIL == yes ] //比较HIL参数设置
then
set OUTPUT_MODE hil
set GPS no
if ver hwcmp PX4FMU_V1
then
set FMU_MODE serial
fi
fi
unset HIL
# waypoint storage //存储路径
# REBOOTWORK this needs to start in parallel
if dataman start
then
fi
#
# Sensors System (start before Commander so Preflight checks are properly run)
#//起飞前传感器检查
sh /etc/init.d/rc.sensors//执行rc.sensors(标准的PX4FMU v1, v2, v3传感器启动脚本)
if [ $GPS == yes ] //检查GPS和GPS_FRAK
then
if [ $GPS_FAKE == yes ]
then
echo "[i] Faking GPS"
gps start -f
else
gps start
fi
fi
unset GPS
unset GPS_FAKE
# Needs to be this early for in-air-restarts
commander start //启动commander,类似于任务管理器
#
# Start primary output//以下为一系列判断,再启动如何输出
#
set TTYS1_BUSY no
#
# Check if UAVCAN is enabled, default to it for ESCs//检查UAVCAN是否使能
#
if param greater UAVCAN_ENABLE 2 //如果UAVCAN_ENABLE大于2
then
set OUTPUT_MODE uavcan_esc
fi
# If OUTPUT_MODE == none then something is wrong with setup and we shouldn't try to enable output
//如果OUTPUT_MODE == none,那么有问题,不能尝试使能输出
if [ $OUTPUT_MODE != none ]
then
if [ $OUTPUT_MODE == uavcan_esc ]
then
if param compare UAVCAN_ENABLE 0
then
echo "[i] OVERRIDING UAVCAN_ENABLE = 1"
param set UAVCAN_ENABLE 1
fi
fi
if [ $OUTPUT_MODE == io -o $OUTPUT_MODE == uavcan_esc ]
then
if px4io start
then
sh /etc/init.d/rc.io//执行rc.io
else
echo "ERROR: PX4IO start failed" >> $LOG_FILE
tone_alarm $TUNE_ERR
fi
fi
if [ $OUTPUT_MODE == fmu -o $OUTPUT_MODE == ardrone ]
then
if fmu mode_$FMU_MODE
then
echo "[i] FMU mode_$FMU_MODE started"
else
echo "[i] ERROR: FMU mode_$FMU_MODE start failed"
echo "ERROR: FMU start failed" >> $LOG_FILE
tone_alarm $TUNE_ERR
fi
if ver hwcmp PX4FMU_V1
then
if [ $FMU_MODE == pwm -o $FMU_MODE == gpio ]
then
set TTYS1_BUSY yes
fi
if [ $FMU_MODE == pwm_gpio -o $OUTPUT_MODE == ardrone ]
then
set TTYS1_BUSY yes
fi
fi
fi
if [ $OUTPUT_MODE == mkblctrl ]
then
set MKBLCTRL_ARG ""
if [ $MKBLCTRL_MODE == x ]
then
set MKBLCTRL_ARG "-mkmode x"
fi
if [ $MKBLCTRL_MODE == + ]
then
set MKBLCTRL_ARG "-mkmode +"
fi
if mkblctrl $MKBLCTRL_ARG
then
echo "[i] MK started"
else
echo "[i] ERROR: MK start failed"
echo "ERROR: MK start failed" >> $LOG_FILE
tone_alarm $TUNE_ERR
fi
unset MKBLCTRL_ARG
fi
unset MK_MODE
if [ $OUTPUT_MODE == hil ]
then
if pwm_out_sim mode_port2_pwm8
then
echo "[i] PWM SIM output started"
else
echo "[i] ERROR: PWM SIM output start failed"
echo "ERROR: PWM SIM output start failed" >> $LOG_FILE
tone_alarm $TUNE_ERR
fi
fi
#
# Start IO or FMU for RC PPM input if needed//如果需要,则启动IO和FMU接收PPM
#
if [ $IO_PRESENT == yes ]
then
if [ $OUTPUT_MODE != io ]
then
if px4io start
then
echo "[i] PX4IO started"
sh /etc/init.d/rc.io
else
echo "[i] ERROR: PX4IO start failed"
echo "ERROR: PX4IO start failed" >> $LOG_FILE
tone_alarm $TUNE_ERR
fi
fi
else
if [ $OUTPUT_MODE != fmu -a $OUTPUT_MODE != ardrone ]
then
if fmu mode_$FMU_MODE
then
echo "[i] FMU mode_$FMU_MODE started"
else
echo "[i] ERROR: FMU mode_$FMU_MODE start failed"
echo "ERROR: FMU mode_$FMU_MODE start failed" >> $LOG_FILE
tone_alarm $TUNE_ERR
fi
if ver hwcmp PX4FMU_V1
then
if [ $FMU_MODE == pwm -o $FMU_MODE == gpio ]
then
set TTYS1_BUSY yes
fi
if [ $FMU_MODE == pwm_gpio -o $OUTPUT_MODE == ardrone ]
then
set TTYS1_BUSY yes
fi
fi
fi
fi
fi
//以下为mavlink的设置
if [ $MAVLINK_F == default ]
then
# Normal mode, use baudrate 57600 (default) and data rate 1000 bytes/s
if [ $TTYS1_BUSY == yes ]
then
# Start MAVLink on ttyS0, because FMU ttyS1 pins configured as something else
set MAVLINK_F "-r 1200 -d /dev/ttyS0"
# Exit from nsh to free port for mavlink
set EXIT_ON_END yes
else
set MAVLINK_F "-r 1200"
# Avoid using ttyS1 for MAVLink on FMUv4
if ver hwcmp PX4FMU_V4
then
set MAVLINK_F "-r 1200 -d /dev/ttyS1"
# Start MAVLink on Wifi (ESP8266 port)
mavlink start -r 20000 -m config -b 921600 -d /dev/ttyS0
fi
fi
fi
mavlink start $MAVLINK_F
unset MAVLINK_F
#
# MAVLink onboard / TELEM2
#
if ver hwcmp PX4FMU_V1
then
else
# XXX We need a better way for runtime eval of shell variables,
# but this works for now
if param compare SYS_COMPANION 921600
then
mavlink start -d /dev/ttyS2 -b 921600 -m onboard -r 80000 -x
fi
if param compare SYS_COMPANION 57600
then
mavlink start -d /dev/ttyS2 -b 57600 -m onboard -r 5000 -x
fi
if param compare SYS_COMPANION 157600
then
mavlink start -d /dev/ttyS2 -b 57600 -m osd -r 1000
fi
if param compare SYS_COMPANION 257600
then
mavlink start -d /dev/ttyS2 -b 57600 -m magic -r 5000 -x
fi
if param compare SYS_COMPANION 357600
then
mavlink start -d /dev/ttyS2 -b 57600 -r 1000
fi
# Sensors on the PWM interface bank
# clear pins 5 and 6
if param compare SENS_EN_LL40LS 1
then
set AUX_MODE pwm4
fi
if param greater TRIG_MODE 0
then
# Get FMU driver out of the way
set MIXER_AUX none
set AUX_MODE none
camera_trigger start
fi
fi
# Transitional support: Disable safety on all Pixracer boards
if ver hwcmp PX4FMU_V4
then
param set CBRK_IO_SAFETY 22027
fi
#
# UAVCAN
#
sh /etc/init.d/rc.uavcan//执行rc.uavcan,也就是启动rc.uavcan
#
# Logging
#
sh /etc/init.d/rc.logging//执行rc.logging,也就是启动rc.logging
#
# Start up ARDrone Motor interface
#
if [ $OUTPUT_MODE == ardrone ]
then
ardrone_interface start -d /dev/ttyS1
fi
#
# Fixed wing setup//固定翼的设置
#
if [ $VEHICLE_TYPE == fw ]
then
echo "[i] FIXED WING"
if [ $MIXER == none ]
then
# Set default mixer for fixed wing if not defined
set MIXER AERT
fi
if [ $MAV_TYPE == none ]
then
# Use MAV_TYPE = 1 (fixed wing) if not defined
set MAV_TYPE 1
fi
param set MAV_TYPE $MAV_TYPE
# Load mixer and configure outputs
sh /etc/init.d/rc.interface//执行rc.interface,配置控制接口
# Start standard fixedwing apps
if [ $LOAD_DAPPS == yes ]
then
sh /etc/init.d/rc.fw_apps//执行rc.fw_apps,开启姿态和位置估算
fi
fi
#
# Multicopters setup//多旋翼的设置
#
if [ $VEHICLE_TYPE == mc ]
then
echo "[i] MULTICOPTER"
if [ $MIXER == none ]
then
echo "Mixer undefined"
fi
if [ $MAV_TYPE == none ]//根据用户的选择,设置MAV_TYPE
then
# Use mixer to detect vehicle type
if [ $MIXER == quad_x -o $MIXER == quad_+ ]
then
set MAV_TYPE 2
fi
if [ $MIXER == quad_w -o $MIXER == sk450_deadcat ]
then
set MAV_TYPE 2
fi
if [ $MIXER == quad_h ]
then
set MAV_TYPE 2
fi
if [ $MIXER == tri_y_yaw- -o $MIXER == tri_y_yaw+ ]
then
set MAV_TYPE 15
fi
if [ $MIXER == hexa_x -o $MIXER == hexa_+ ]
then
set MAV_TYPE 13
fi
if [ $MIXER == hexa_cox ]
then
set MAV_TYPE 13
fi
if [ $MIXER == octo_x -o $MIXER == octo_+ ]
then
set MAV_TYPE 14
fi
if [ $MIXER == octo_cox -o $MIXER == octo_cox_w ]
then
set MAV_TYPE 14
fi
fi
# Still no MAV_TYPE found//mav的类型没找到
if [ $MAV_TYPE == none ]
then
echo "Unknown MAV_TYPE"
param set MAV_TYPE 2
else
param set MAV_TYPE $MAV_TYPE
fi
# Load mixer and configure outputs
sh /etc/init.d/rc.interface//执行rc.interface,配置控制接口
# Start standard multicopter apps
if [ $LOAD_DAPPS == yes ]
then
sh /etc/init.d/rc.mc_apps// 执行rc.mc_apps,启动姿态位置的估计和控制
fi
fi
#
# VTOL setup//工具类型设置
#
if [ $VEHICLE_TYPE == vtol ]
then
echo "[init] Vehicle type: VTOL"
if [ $MIXER == none ]
then
echo "Default mixer for vtol not defined"
fi
if [ $MAV_TYPE == none ]
then
# Use mixer to detect vehicle type
if [ $MIXER == caipirinha_vtol ]
then
set MAV_TYPE 19
fi
if [ $MIXER == firefly6 ]
then
set MAV_TYPE 21
fi
if [ $MIXER == quad_x_pusher_vtol ]
then
set MAV_TYPE 22
fi
fi
# Still no MAV_TYPE found
if [ $MAV_TYPE == none ]
then
echo "Unknown MAV_TYPE"
param set MAV_TYPE 19
else
param set MAV_TYPE $MAV_TYPE
fi
# Load mixer and configure outputs
sh /etc/init.d/rc.interface//执行rc.interface,下载mixer并配置输出
# Start standard vtol apps
if [ $LOAD_DAPPS == yes ]
then
sh /etc/init.d/rc.vtol_apps//执行rc.vtol_apps,
//启动attitude_estimator_q start、
//position_estimator_inav start、
//vtol_att_control start、
//mc_att_control start、
//mc_pos_control start、
//fw_att_control start、
//fw_pos_control_l1 start
fi
fi
#
# Rover setup//漫游设置
#
if [ $VEHICLE_TYPE == rover ]
then
# 10 is MAV_TYPE_GROUND_ROVER
set MAV_TYPE 10
# Load mixer and configure outputs
sh /etc/init.d/rc.interface//执行rc.interface,下载mixer并配置输出
# Start standard rover apps
if [ $LOAD_DAPPS == yes ]
then
sh /etc/init.d/rc.axialracing_ax10_apps//ekf_att_pos_estimator start
fi
param set MAV_TYPE 10
fi
unset MIXER
unset MAV_TYPE
unset OUTPUT_MODE
#
# Start the navigator//启动导航
#
navigator start
#
# Generic setup (autostart ID not found) //常规设置
#
if [ $VEHICLE_TYPE == none ]
then
echo "[i] No autostart ID found"
fi
# Start any custom addons //启动自定义插件
set FEXTRAS /fs/microsd/etc/extras.txt
if [ -f $FEXTRAS ]
then
echo "[i] Addons script: $FEXTRAS"
sh $FEXTRAS
fi
unset FEXTRAS
# Run no SD alarm //运行没有sd卡的警告
if [ $LOG_FILE == /dev/null ]
then
echo "[i] No microSD card found"
# Play SOS
tone_alarm error
fi
# End of autostart
fi
# There is no further script processing, so we can free some RAM
# XXX potentially unset all script variables.
unset TUNE_ERR
# Boot is complete, inform MAVLink app(s) that the system is now fully up and running
mavlink boot_complete
# Sensors on the PWM interface bank
if param compare SENS_EN_LL40LS 1
then
if pwm_input start //启动pwm输入设置
then
if ll40ls start pwm
then
fi
fi
fi
if ver hwcmp PX4FMU_V4
then
frsky_telemetry start -d /dev/ttyS6
fi
if ver hwcmp PX4FMU_V2
then
# Check for flow sensor - as it is a background task, launch it last
px4flow start & //如果检测到光流,则启动
fi
# Start USB shell if no microSD present, MAVLink else //如果没找到sd卡,则启动usb shell,
if [ $LOG_FILE == /dev/null ] //找到了则启动mavlink
then
# Try to get an USB console
nshterm /dev/ttyACM0 &
else
mavlink start -r 800000 -d /dev/ttyACM0 -m config -x
fi
if [ $EXIT_ON_END == yes ]
then
echo "Exit from nsh"
exit
fi
unset EXIT_ON_END
rc.sensors
#!nsh
#
# Standard startup script for PX4FMU v1, v2, v3 onboard sensor drivers.
#
if ver hwcmp PX4FMU_V1 //比较px4版本
then
if ms5611 start
then
fi
else
if ms5611 -s start
then
fi
# Blacksheep telemetry
if bst start
then
fi
fi
if adc start
then
fi
if ver hwcmp PX4FMU_V2//比较px4版本
then
# External I2C bus
if hmc5883 -C -T -X start //启动hmc5883
then
fi
# Internal I2C bus
if hmc5883 -C -T -I -R 4 start
then
fi
# external MPU6K is rotated 180 degrees yaw
if mpu6000 -X -R 4 start
then
set BOARD_FMUV3 true
else
set BOARD_FMUV3 false
fi
if [ $BOARD_FMUV3 == true ]
then
# external L3GD20H is rotated 180 degrees yaw
if l3gd20 -X -R 4 start
then
fi
# external LSM303D is rotated 270 degrees yaw
if lsm303d -X -R 6 start
then
fi
# internal MPU6000 is rotated 180 deg roll, 270 deg yaw
if mpu6000 -R 14 start
then
fi
if hmc5883 -C -T -S -R 8 start
then
fi
else
# FMUv2
if mpu6000 start
then
fi
if l3gd20 start
then
fi
if lsm303d start
then
fi
fi
else
if ver hwcmp PX4FMU_V4
then
# External I2C bus
if hmc5883 -C -T -X start
then
fi
# Internal SPI bus is rotated 90 deg yaw
if hmc5883 -C -T -S -R 2 start
then
fi
# Internal SPI bus ICM-20608-G is rotated 90 deg yaw
if mpu6000 -R 2 -T 20608 start
then
fi
# Internal SPI bus mpu9250 is rotated 90 deg yaw
if mpu9250 -R 2 start
then
fi
else
# FMUv1
if mpu6000 start
then
fi
if l3gd20 start
then
fi
# MAG selection
if param compare SENS_EXT_MAG 2
then
if hmc5883 -C -I start
then
fi
else
# Use only external as primary
if param compare SENS_EXT_MAG 1
then
if hmc5883 -C -X start
then
fi
else
# auto-detect the primary, prefer external
if hmc5883 start
then
fi
fi
fi
fi
fi
if meas_airspeed start
then
else
if ets_airspeed start
then
else
if ets_airspeed start -b 1
then
fi
fi
fi
if sf10a start
then
fi
# Wait 20 ms for sensors (because we need to wait for the HRT and work queue callbacks to fire)
usleep 20000
if sensors start
then
fi
rc.mc_apps
#!nsh
#
# Standard apps for multirotors:
# att & pos estimator, att & pos control.
#
# The system is defaulting to INAV_ENABLED = 1
# but users can alternatively try the EKF-based
# filter by setting INAV_ENABLED = 0
//选择姿态位置估计和控制使用的算法,默认INAV_ENABLED = 1,那么
姿态估计 Attitude_estimator_q
位置估计 position_estimator_inav
姿态控制 mc_att_control
位置控制 mc_pos_control
if param compare INAV_ENABLED 1
then
attitude_estimator_q start
position_estimator_inav start
else
if param compare LPE_ENABLED 1
then
attitude_estimator_q start
local_position_estimator start
else
ekf2 start
fi
fi
if mc_att_control start
then
else
# try the multiplatform version
mc_att_control_m start
fi
if mc_pos_control start
then
else
# try the multiplatform version
mc_pos_control_m start
fi
#
# Start Land Detector
#
land_detector start multicopter
如果您觉得此文对您的发展有用,请随意打赏。
您的鼓励将是笔者书写高质量文章的最大动力^_^!!