Skip to content

Commit

Permalink
Tools: added Carbonix Param Auto Check python script
Browse files Browse the repository at this point in the history
This script will check the parameter validation to Arduplane for below files.
libraries/AP_HAL_ChibiOS/hwdef/CubeOrange-Ottano/defaults.parm',
'libraries/AP_HAL_ChibiOS/hwdef/CubeOrange-Volanti/defaults.parm',
'libraries/AP_HAL_ChibiOS/hwdef/CarbonixCommon/defaults.parm']

SW-159
  • Loading branch information
loki077 committed Jun 12, 2024
1 parent 0613f59 commit 6da1188
Showing 1 changed file with 195 additions and 0 deletions.
195 changes: 195 additions & 0 deletions Tools/Carbonix_scripts/param_auto_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
import os
import xml.etree.ElementTree as ET

# Load the XML file
tree = ET.parse('Tools/autotest/param_metadata/apm.pdef.xml')
root = tree.getroot()

# Define the paths to the file to compare
text_file_paths = ['libraries/AP_HAL_ChibiOS/hwdef/CubeOrange-Ottano/defaults.parm',
'libraries/AP_HAL_ChibiOS/hwdef/CubeOrange-Volanti/defaults.parm',
'libraries/AP_HAL_ChibiOS/hwdef/CarbonixCommon/defaults.parm']

# Define default path
text_default_file_path = ()

return_status = 0

# Create a dictionary to store parameter names,
# ranges, values, and other properties
param_dict = {}

# Iterate through the XML tree and populate
# the dictionary for parameters with ranges
# or bitmask values
for param_elem in root.iter('param'):
param_name_with_prefix = param_elem.get('name')
param_name = param_name_with_prefix.replace(
'ArduPlane:', '') # Remove "ArduPlane:" prefix

# if there is any field name Readonly whose value is true, skip it
readonly_elem = param_elem.find(".//field[@name='ReadOnly']")
if readonly_elem is not None:
readonly_value = readonly_elem.text
if readonly_value == 'True':
param_dict[param_name] = {'type': 'ReadOnly', 'values': 'True'}
continue

# If 'values' element does not exist,
# look for 'field' element with
# name="Range"
range_elem = param_elem.find(".//field[@name='Range']")
if range_elem is not None:
range_values = range_elem.text.split()
if len(range_values) == 2:
try:
range_values = [float(val) for val in range_values]
param_dict[param_name] = {
'type': 'Range', 'values': range_values}
except ValueError:
param_dict[param_name] = None
else:
param_dict[param_name] = None
else:
param_range = param_elem.find('values')

# If 'values' element exists, it's
# a parameter with values
if param_range is not None:
param_values = {
value.get('code'): value.text
for value in param_range.findall('value')
}
# Check if values can be converted
# to int or float
parsed_values = []
for code, val in param_values.items():
try:
parsed_val = int(code)
except ValueError:
try:
parsed_val = float(code)
except ValueError:
parsed_val = None
parsed_values.append(parsed_val)
try:
parsed_val = int(val)
except ValueError:
try:
parsed_val = float(val)
except ValueError:
parsed_val = None

parsed_values.append(parsed_val)
parsed_values = list(
filter(lambda item: item is not None, parsed_values))
param_dict[param_name] = {
'type': 'values', 'values': str(parsed_values)}
else:
# Look for 'field' element with the
# specified name attribute "Bitmask"
field_elem = param_elem.find(".//field[@name='Bitmask']")
if field_elem is not None:
field_values = field_elem.text.split(',')
field_values = [value.strip().split(':')[0]
for value in field_values]
param_dict[param_name] = {
'type': 'Bitmask', 'values': field_values}
else:
param_dict[param_name] = {'type': 'Int', 'values': None}

# Initialize an empty dictionary to store the data
para_default_dict = {}

if text_default_file_path and os.path.exists(text_default_file_path):
para_default_dict = dict(
line.strip().replace('@READONLY', '').split(' ', 1)
for line in open(text_default_file_path)
if line.strip() and not line.strip().startswith('#')
)
else:
print(f"Text file '{text_default_file_path}' does not exist.")

for text_file_path in text_file_paths:
# Check if the text file exists
if not text_file_path or not os.path.exists(text_file_path):
print(f"Text file '{text_file_path}' does not exist.")
else:
# Load the text file and check parameter names and values
print(f"Checking parameters in '{text_file_path}'...")
with open(text_file_path, 'r') as file:
for line in file:
if line.strip() == '' or line.strip().startswith('#') or line.strip().startswith('@'):
continue
temp_line = line.strip().split('#', 1)[0]
param_name, param_value = temp_line.strip().split(',')
if param_name in param_dict:
param_info = param_dict[param_name]
if param_info is not None:
param_type = param_info['type']
param_values = param_info['values']
if param_type == 'ReadOnly':
print(
f"Parameter '{param_name}' is read-only "
f"shouldn't be in the param file."
)
return_status = 1
# Check if the parameter value is different from default
if (
param_name in para_default_dict
and str(param_value).replace(" ", "")
!= str(para_default_dict[param_name]).replace(" ", "")
):
print(
f"Parameter '{param_name}' has a "
f"different value from default: {param_value} "
f": {para_default_dict[param_name]}"
)
return_status = 1
elif param_type == 'ReadOnly':
print(
f"Parameter '{param_name}' is read-only "
f"shouldn't be in the param file."
)
return_status = 1
elif param_type == 'values':
# Check if the parameter value is in the list of values
if param_value not in param_values:
print(
f"Parameter '{param_name}' "
f"has an invalid value: {param_value} "
f": {param_values}"
)
return_status = 1
elif param_type == 'range':
# Check if the parameter value is in the range
if (
float(param_value) < param_values[0]
or float(param_value) > param_values[1]
):
print(
f"Parameter '{param_name}' has an "
f"out-of-range value: {param_value}"
)
return_status = 1
elif param_type == 'bitmask':
# Check if the parameter value is in the list of values
if param_value not in param_values:
print(
f"Parameter '{param_name}' has an "
f"invalid value: {param_value}"
)
return_status = 1
else:
print(
f"Parameter '{param_name}' has no "
f"defined range or values in the XML."
)
return_status = 1
else:
print(f"Parameter '{param_name}' does not exist in the XML.")
return_status = 1
print(f'Finished checking parameters in {text_file_path}.')

if return_status == 1:
exit(return_status)

0 comments on commit 6da1188

Please sign in to comment.