Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate param metadata as MAVLink-compatible JSON component info #15389

Merged
merged 8 commits into from
Aug 3, 2020
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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
26 changes: 25 additions & 1 deletion 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 @@ -109,12 +109,36 @@ add_custom_command(OUTPUT ${parameters_xml}
)
add_custom_target(parameters_xml DEPENDS ${parameters_xml})

set(parameters_json ${PX4_BINARY_DIR}/parameters.json)
add_custom_command(OUTPUT ${parameters_json}
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/px_process_params.py
--src-path ${module_list} ${generated_params_dir}
--json ${parameters_json}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we generate both json + xml in the same python call? I.e. merge this with the above.

--inject-xml ${CMAKE_CURRENT_SOURCE_DIR}/parameters_injected.xml
--overrides ${PARAM_DEFAULT_OVERRIDES}
--board ${PX4_BOARD}
#--verbose
DEPENDS
${param_src_files}
${generated_serial_params_file}
parameters_injected.xml
px4params/srcparser.py
px4params/srcscanner.py
px4params/xmlout.py
px4params/jsonout.py
px_process_params.py
parameters_injected.xml
COMMENT "Generating parameters.json"
)
add_custom_target(parameters_json DEPENDS ${parameters_json})

# generate px4_parameters.c and px4_parameters{,_public}.h
add_custom_command(OUTPUT px4_parameters.c px4_parameters.h px4_parameters_public.h
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/px_generate_params.py
--xml ${parameters_xml} --dest ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS
${PX4_BINARY_DIR}/parameters.xml
${PX4_BINARY_DIR}/parameters.json
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only added this for testing, we're going to need to add the dependency at the right place.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. Since I don't know what I'm doing, can you make the needed change?

Copy link
Member

@bkueng bkueng Jul 31, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here it is: bkueng@6349aea. I also made the compression generic.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @bkueng . I've added that. What next?

px_generate_params.py
templates/px4_parameters.c.jinja
templates/px4_parameters.h.jinja
Expand Down
119 changes: 119 additions & 0 deletions src/lib/parameters/px4params/jsonout.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
from xml.sax.saxutils import escape
import codecs
import json
import gzip #to create .gz file of 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)

#create gz version
gz_filename=filename+'.gz'
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved
with gzip.open(gz_filename, 'wt') as f:
f.write(self.output)
21 changes: 17 additions & 4 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,7 +47,7 @@
import sys
import os
import argparse
from px4params import srcscanner, srcparser, injectxmlparams, xmlout, markdownout
from px4params import srcscanner, srcparser, injectxmlparams, xmlout, markdownout, jsonout

import re
import json
Expand Down Expand Up @@ -84,6 +84,12 @@ 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")
Expand All @@ -95,7 +101,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 @@ -148,7 +154,14 @@ def main():
print("Creating markdown file " + args.markdown)
out.Save(args.markdown)

#print("All done!")
# Output to JSON file
if args.json:
if args.verbose:
print("Creating Json/Json.gz 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)


if __name__ == "__main__":
Expand Down