Skip to content

Commit

Permalink
params: generate param metadata as MAVLink-compatible JSON component …
Browse files Browse the repository at this point in the history
…info (#15389)
  • Loading branch information
hamishwillee committed Aug 3, 2020
1 parent 6923d9e commit 958d5a3
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 11 deletions.
9 changes: 8 additions & 1 deletion cmake/metadata.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,18 @@ add_custom_target(metadata_parameters
--src-path `find ${PX4_SOURCE_DIR}/src -maxdepth 4 -type d`
--inject-xml ${PX4_SOURCE_DIR}/src/lib/parameters/parameters_injected.xml
--markdown ${PX4_BINARY_DIR}/docs/parameters.md

COMMAND ${PYTHON_EXECUTABLE} ${PX4_SOURCE_DIR}/src/lib/parameters/px_process_params.py
--src-path `find ${PX4_SOURCE_DIR}/src -maxdepth 4 -type d`
--inject-xml ${PX4_SOURCE_DIR}/src/lib/parameters/parameters_injected.xml
--json ${PX4_BINARY_DIR}/docs/parameters.json

COMMAND ${PYTHON_EXECUTABLE} ${PX4_SOURCE_DIR}/src/lib/parameters/px_process_params.py
--src-path `find ${PX4_SOURCE_DIR}/src -maxdepth 4 -type d`
--inject-xml ${PX4_SOURCE_DIR}/src/lib/parameters/parameters_injected.xml
--xml ${PX4_BINARY_DIR}/docs/parameters.xml
COMMENT "Generating full parameter metadata (markdown and xml)"

COMMENT "Generating full parameter metadata (markdown, xml, and json)"
USES_TERMINAL
)

Expand Down
8 changes: 6 additions & 2 deletions src/lib/parameters/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
############################################################################
#
# Copyright (c) 2017 PX4 Development Team. All rights reserved.
# Copyright (c) 2017 - 2020 PX4 Development Team. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
Expand Down Expand Up @@ -87,11 +87,14 @@ add_custom_command(OUTPUT ${generated_serial_params_file}
)

set(parameters_xml ${PX4_BINARY_DIR}/parameters.xml)
set(parameters_json ${PX4_BINARY_DIR}/parameters.json)
file(GLOB_RECURSE param_src_files ${PX4_SOURCE_DIR}/src/*params.c)
add_custom_command(OUTPUT ${parameters_xml}
add_custom_command(OUTPUT ${parameters_xml} ${parameters_json}
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/px_process_params.py
--src-path ${module_list} ${generated_params_dir}
--xml ${parameters_xml}
--json ${parameters_json}
--compress
--inject-xml ${CMAKE_CURRENT_SOURCE_DIR}/parameters_injected.xml
--overrides ${PARAM_DEFAULT_OVERRIDES}
--board ${PX4_BOARD}
Expand All @@ -102,6 +105,7 @@ add_custom_command(OUTPUT ${parameters_xml}
parameters_injected.xml
px4params/srcparser.py
px4params/srcscanner.py
px4params/jsonout.py
px4params/xmlout.py
px_process_params.py
parameters_injected.xml
Expand Down
112 changes: 112 additions & 0 deletions src/lib/parameters/px4params/jsonout.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
from xml.sax.saxutils import escape
import codecs
import json
import sys


class JsonOutput():
def __init__(self, groups, board, inject_xml_file_name):
all_json=dict()
all_json['version']=1
all_json['uid']=1 #COMPONENT_INFORMATION.comp_metadata_type
all_json['scope']="Firmware"
all_params=[]
all_json['parameters']=all_params

#xml_parameters = ET.Element("parameters")
#xml_version = ET.SubElement(xml_parameters, "version")
#xml_version.text = "3"
#xml_version = ET.SubElement(xml_parameters, "parameter_version_major")
#xml_version.text = "1"
#xml_version = ET.SubElement(xml_parameters, "parameter_version_minor")
#xml_version.text = "15"

schema_map = {
"short_desc": "shortDescription",
"long_desc": "longDescription",
"unit": "units",
"decimal": "decimalPlaces",
"min": "min",
"max": "max",
"increment": "increment",
"reboot_required": "rebootRequired"
}
allowed_types = { "Uint8", "Int8", "Uint16", "Int16", "Uint32", "Int32", "Float"}

last_param_name = ""
board_specific_param_set = False
for group in groups:
group_name=group.GetName()

for param in group.GetParams():
if (last_param_name == param.GetName() and not board_specific_param_set) or last_param_name != param.GetName():
curr_param=dict()
curr_param['name'] = param.GetName()
curr_param['defaultValue'] = param.GetDefault()
curr_param['type'] = param.GetType().capitalize()
if not curr_param['type'] in allowed_types:
print("Error: %s type not supported: curr_param['type']" % (curr_param['name'],curr_param['type']) )
sys.Exit(1)

curr_param['group'] = group_name
if (param.GetCategory()):
curr_param['category'] = param.GetCategory()

if (param.GetVolatile() == "true"):
curr_param['volatile'] = param.GetVolatile()

last_param_name = param.GetName()
for code in param.GetFieldCodes():
value = param.GetFieldValue(code)
if code == "board":
if value == board:
board_specific_param_set = True
# JSON schema has no field for board_specific schema. Ignore.
else:
#xml_group.remove(xml_param)
continue
else:
#map PX4 param field names to schema names
if code in schema_map:
curr_param[schema_map[code]] = value
else:
print('ERROR: Field not in json schema: %s' % code)
sys.exit(1)


if last_param_name != param.GetName():
board_specific_param_set = False

enum_codes=param.GetEnumCodes() or '' # Gets numerical values for parameter.
if enum_codes:
enum_codes=sorted(enum_codes,key=float)
codes_list=list()
for item in enum_codes:
code_dict=dict()
code_dict['value']=item
code_dict['description']=param.GetEnumValue(item)
codes_list.append(code_dict)
curr_param['values'] = codes_list


if len(param.GetBitmaskList()) > 0:
bitmasks_list=list()
for index in param.GetBitmaskList():
bitmask_dict=dict()
bitmask_dict['index']=index
bitmask_dict['description']=param.GetBitmaskBit(index)
bitmasks_list.append(bitmask_dict)
curr_param['bitmask'] = bitmasks_list


all_params.append(curr_param)


#Json string output.
self.output = json.dumps(all_json,indent=2)


def Save(self, filename):
with codecs.open(filename, 'w', 'utf-8') as f:
f.write(self.output)

53 changes: 45 additions & 8 deletions src/lib/parameters/px_process_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
############################################################################

#
# PX4 paramers processor (main executable file)
# PX4 paramaters processor (main executable file)
#
# This tool scans the PX4 source code for declarations of tunable parameters
# and outputs the list in various formats.
Expand All @@ -47,12 +47,22 @@
import sys
import os
import argparse
from px4params import srcscanner, srcparser, injectxmlparams, xmlout, markdownout
from px4params import srcscanner, srcparser, injectxmlparams, xmlout, markdownout, jsonout

import gzip #to create .gz file
import re
import json
import codecs

def SaveCompressed(filename):
#create gz compressed version
gz_filename=filename+'.gz'
with gzip.open(gz_filename, 'wt') as f:
with open(filename, 'r') as content_file:
f.write(content_file.read())



def main():
# Parse command line arguments
parser = argparse.ArgumentParser(description="Process parameter documentation.")
Expand Down Expand Up @@ -84,9 +94,18 @@ def main():
metavar="FILENAME",
help="Create Markdown file"
" (default FILENAME: parameters.md)")
parser.add_argument("-j", "--json",
nargs='?',
const="parameters.json",
metavar="FILENAME",
help="Create Json file"
" (default FILENAME: parameters.json)")
parser.add_argument('-v', '--verbose',
action='store_true',
help="verbose output")
parser.add_argument('-c', '--compress',
action='store_true',
help="compress parameter file")
parser.add_argument("-o", "--overrides",
default="{}",
metavar="OVERRIDES",
Expand All @@ -95,7 +114,7 @@ def main():
args = parser.parse_args()

# Check for valid command
if not (args.xml or args.markdown):
if not (args.xml or args.markdown or args.json):
print("Error: You need to specify at least one output method!\n")
parser.print_usage()
sys.exit(1)
Expand Down Expand Up @@ -134,22 +153,40 @@ def main():
param.default = val
print("OVERRIDING {:s} to {:s}!!!!!".format(name, val))

output_files = []

# 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_files.append(args.xml)

# Output to Markdown/HTML tables
if args.markdown:
out = markdownout.MarkdownTablesOutput(param_groups)
if args.markdown:
if args.verbose:
print("Creating markdown file " + args.markdown)
out.Save(args.markdown)

#print("All done!")
out = markdownout.MarkdownTablesOutput(param_groups)
out.Save(args.markdown)
output_files.append(args.markdown)

# Output to JSON file
if args.json:
if args.verbose:
print("Creating Json file " + args.json)
cur_dir = os.path.dirname(os.path.realpath(__file__))
out = jsonout.JsonOutput(param_groups, args.board,
os.path.join(cur_dir, args.inject_xml))
out.Save(args.json)
output_files.append(args.json)

if args.compress:
for f in output_files:
if args.verbose:
print("Compressing file " + f)
SaveCompressed(f)


if __name__ == "__main__":
main()

0 comments on commit 958d5a3

Please sign in to comment.