PX4 編譯分析之Airframe文檔生成
本文假設已經閱讀了 PX4 的
1 Makefile分析
2 CMakeLists.txt分析
這裏要分析的是 make airframe_metadata
的指令, 在 Makefile
文件中找到 airframe_metadata 的編譯配置
# Documentation
# --------------------------------------------------------------------
.PHONY: parameters_metadata airframe_metadata module_documentation px4_metadata doxygen
parameters_metadata:
@$(MAKE) --no-print-directory px4_sitl_default metadata_parameters
airframe_metadata:
@$(MAKE) --no-print-directory px4_sitl_default metadata_airframes
可以發現它實際執行的是make px4_sitl_default metadata_airframes
, 第一選項是px4 的仿真配置選項這個會傳給CMakeLists.txt
中的cmake-build
在build/px4_sitl_default
生成一些配置文件, 第二個和airframe_metadata
和metadata_airframe
相比只是前後兩個單詞互換了一下, 接下來依照我們在 Makefile分析 中的分析, 在Firmware 文件夾下的 CMakeLists.txt 中找到以下語句
add_custom_target(metadata_airframes
COMMAND ${CMAKE_COMMAND} -E make_directory ${PX4_BINARY_DIR}/docs
COMMAND ${PYTHON_EXECUTABLE} ${PX4_SOURCE_DIR}/Tools/px_process_airframes.py
-v -a ${PX4_SOURCE_DIR}/ROMFS/px4fmu_common/init.d
--markdown ${PX4_BINARY_DIR}/docs/airframes.md
COMMAND ${PYTHON_EXECUTABLE} ${PX4_SOURCE_DIR}/Tools/px_process_airframes.py
-v -a ${PX4_SOURCE_DIR}/ROMFS/px4fmu_common/init.d
--xml ${PX4_BINARY_DIR}/docs/airframes.xml
COMMENT "Generating full airframe metadata (markdown and xml)"
USES_TERMINAL
)
由以上定義語句我們發現, 編譯metadata_airframes
的主要操作是(假設當前目錄爲源碼 Firmware
文件夾):
- 在
build/px4_sitl_default
中建立輸出文件夾docs
- 執行
python Tools/px_process_airframes.py -v -a ROMFS/px4fmu_common/init.d --markdown build/px4_sitl_default/docs/airframes.md
- 執行
python Tools/px_process_airframes.py -v -a ROMFS/px4fmu_common/init.d --xml build/px4_sitl_default/docs/airframes.xml
接下來, 繼續分析一下 px_process_airframes.py
程序, 摘抄如下
# PX4 airframe config processor (main executable file)
#
# This tool scans the PX4 ROMFS code for declarations of airframes
#
# Currently supported formats are:
# * XML for the parametric UI generator
# * Markdown for the PX4 dev guide (https://github.com/PX4/Devguide)
#
#
from __future__ import print_function
import sys
import os
import argparse
from px4airframes import srcscanner, srcparser, xmlout, rcout, markdownout
def main():
# Parse command line arguments
parser = argparse.ArgumentParser(description="Process airframe documentation.")
parser.add_argument("-a", "--airframes-path",
default="../ROMFS/px4fmu_common",
metavar="PATH",
help="path to source files to scan for parameters")
parser.add_argument("-x", "--xml",
nargs='?',
const="airframes.xml",
metavar="FILENAME",
help="Create XML file"
" (default FILENAME: airframes.xml)")
parser.add_argument("-m", "--markdown",
nargs='?',
const="airframes.md",
metavar="FILENAME",
help="Create Markdown file"
" (default FILENAME: airframes.md)")
default_image_path = '../../assets/airframes/types'
parser.add_argument("-i", "--image-path",
default=default_image_path,
metavar="IMAGEPATH",
help="HTML image path for Markdown (containing the airframe svg files)"
" (default IMAGEPATH: "+default_image_path+")")
parser.add_argument("-s", "--start-script",
nargs='?',
const="rc.autostart",
metavar="FILENAME",
help="Create start script file")
parser.add_argument("-b", "--board",
nargs='?',
const="",
metavar="BOARD",
help="Board to create airframes xml for")
parser.add_argument('-v', '--verbose', action='store_true', help="verbose output")
args = parser.parse_args()
# Check for valid command
if not (args.xml) and not (args.start_script) and not args.markdown:
print("Error: You need to specify at least one output method!\n")
parser.print_usage()
sys.exit(1)
# Initialize source scanner and parser
scanner = srcscanner.SourceScanner()
parser = srcparser.SourceParser()
# Scan directories, and parse the files
if args.verbose: print("Scanning source path " + args.airframes_path)
if not scanner.ScanDir(args.airframes_path, parser):
sys.exit(1)
# We can't validate yet
# if not parser.Validate():
# sys.exit(1)
param_groups = parser.GetParamGroups()
# Output to XML file
if args.xml:
if args.verbose: print("Creating XML file " + args.xml)
out = xmlout.XMLOutput(param_groups, args.board)
out.Save(args.xml)
# Output to markdown file
if args.markdown:
if args.verbose: print("Creating markdown file " + args.markdown)
out = markdownout.MarkdownTablesOutput(param_groups, args.board, args.image_path)
out.Save(args.markdown)
if args.start_script:
if args.verbose: print("Creating start script " + args.start_script)
out = rcout.RCOutput(param_groups, args.board)
out.Save(args.start_script)
if (args.verbose): print("All done!")
if __name__ == "__main__":
main()
可以看到這裏只是一個入口函數, 解析了一些用戶選項, 然後通過srcscanner
和 srcparser
解析了 -a
選項給定的路徑裏的.hil
文件或者無擴展名的文件進行解析,這裏摘錄一個ROMFS/px4fmu_common/init.d/airframes/1001_rc_quad_x.hil
文件如下
#!/bin/sh
#
# @name HIL Quadcopter X
#
# @type Simulation
# @class Copter
#
# @maintainer Lorenz Meier <[email protected]>
#
sh /etc/init.d/rc.mc_defaults
set MIXER quad_x
set PWM_OUT 1234
if [ $AUTOCNF = yes ]
then
param set COM_DISARM_LAND 5
fi
param set SYS_HITL 1
這裏基於上面 .hil
文件我們分析一下Tools/px4airframes/srcparser.py
中的 SourceParser類
的 parse
方法的執行步驟, 由於其文件比較長,這裏只給出簡要描述, 並不附上代碼.
- 首先通過
.hil
文件名解析得到序號, 這裏是1001
- 進行如下圖流程圖中的操作的描述(尚未全部完成)
主要過程就是把"url", "maintainer", "output", "arch", "name", "type"
這幾個域對應的信息解析出來. 然後調用xmlout
導出到xml
,md
或者rc
文件中.
所以 make metadata_airframe
的操作就是把這些信息導出到md
和xml
中.