• PX4学习之-uORB msg 自动生成模板解读


    最后更新日期 2019-06-22

    一、前言

    PX4学习之-uORB简单体验 中指出, 使用 uORB 进行通信的第一步是新建 msg。在实际编译过程中,新建的 msg 会转换成对应的 .h、.cpp 文件。

    Firmware 使用 CMake 来管理整个项目,文件解析以及转换成也是使用相关 CMakeLists.txt 里的命令来完成。 msg 文件调用的是 CMakeLists.txt 中的 add_custom_command 命令。add_custom_command 最终调用在 msg中的 CMakeLists.txt 中使用着 add_custom_command 最终调用 tools/px_generate_uorb_topic_files.py 脚本解析。

    # Generate uORB headers
    add_custom_command(OUTPUT ${uorb_headers}
    	COMMAND ${PYTHON_EXECUTABLE} tools/px_generate_uorb_topic_files.py
    		--headers
    		-f ${msg_files}
    		-i ${CMAKE_CURRENT_SOURCE_DIR}
    		-o ${msg_out_path}
    		-e templates/uorb
    		-t ${CMAKE_CURRENT_BINARY_DIR}/tmp/headers
    		-q
    	DEPENDS
    		${msg_files}
    		templates/uorb/msg.h.template
    		tools/px_generate_uorb_topic_files.py
    	COMMENT "Generating uORB topic headers"
    	WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    	VERBATIM
    	)
    

    本文相关的 Demo可在 Github-uorb-msg-parser-demo 获取。

    直接进入对应的文件夹,执行 sh script.sh, 会将 actuator.msg 生成对应的头文件源文件.

    二、源码分析

    shell 脚本会自动的去执行 tools/px_generate_uorb_topic_files.py 文件。Python 脚本首先使用 argparse.ArgumentParser 来解析对应的参数,根据 --headers--sources 来进行区分是生成源文件还是头文件,最重要的是解析出待解析的文件 file、模板文件 temporarydir 以及相关的目录。

            parser = argparse.ArgumentParser(
                description='Convert msg files to uorb headers/sources')
            # true or false 
            parser.add_argument('--headers', help='Generate header files',
                action='store_true')
            parser.add_argument('--sources', help='Generate source files',
                action='store_true')
            parser.add_argument('-d', dest='dir', help='directory with msg files')
            parser.add_argument('-f', dest='file',
                                help="files to convert (use only without -d)",
                                nargs="+")
            parser.add_argument('-i', dest="include_paths",
                                help='Additional Include Paths', nargs="*",
                                default=None)
            parser.add_argument('-e', dest='templatedir',
                                help='directory with template files',)
            parser.add_argument('-o', dest='outputdir',
                                help='output directory for header files')
            parser.add_argument('-t', dest='temporarydir',
                                help='temporary directory')
            parser.add_argument('-p', dest='prefix', default='',
                                help='string added as prefix to the output file '
                                ' name when converting directories')
            parser.add_argument('-q', dest='quiet', default=False, action='store_true',
                                help='string added as prefix to the output file '
                                ' name when converting directories')
            args = parser.parse_args()
    

    解析完成后,调用 generate_output_from_file(generate_idx, f, args.temporarydir, args.templatedir, INCL_DEFAULT) 方法来生成对应的文件。

    def generate_output_from_file(format_idx, filename, outputdir, templatedir, includepath):
            """
            Converts a single .msg file to an uorb header/source file
            """
            msg_context = genmsg.msg_loader.MsgContext.create_default()
            full_type_name = genmsg.gentools.compute_full_type_name(PACKAGE, os.path.basename(filename))
    
            spec = genmsg.msg_loader.load_msg_from_file(msg_context, filename, full_type_name)
    
            topics = get_multi_topics(filename)
    
            if includepath:
                    search_path = genmsg.command_line.includepath_to_dict(includepath)
            else:
                    search_path = {}
            genmsg.msg_loader.load_depends(msg_context, spec, search_path)
            md5sum = genmsg.gentools.compute_md5(msg_context, spec)
            if len(topics) == 0:
                    topics.append(spec.short_name)
            em_globals = {
                "file_name_in": filename,
                "md5sum": md5sum,
                "search_path": search_path,
                "msg_context": msg_context,
                "spec": spec,
                "topics": topics
            }
    
            # Make sure output directory exists:
            if not os.path.isdir(outputdir):
                    os.makedirs(outputdir)
    
            template_file = os.path.join(templatedir, TEMPLATE_FILE[format_idx])
            output_file = os.path.join(outputdir, spec.short_name +
                    OUTPUT_FILE_EXT[format_idx])
    
            return generate_by_template(output_file, template_file, em_globals)
    
  • 相关阅读:
    [pycharm]远程调试服务器项目
    [Linux]防火墙关闭与开启
    [Linux]安装pyenv
    [Linux]ubuntu安装基本流程
    [python]html格式转md格式
    [python]目录及文件操作
    [Linux]安装node.js
    Linux基础
    爬虫基础(3)
    爬虫基础(2)
  • 原文地址:https://www.cnblogs.com/gaox97329498/p/11913957.html
Copyright © 2020-2023  润新知