diff --git a/Tools/autotest/param_metadata/htmlemit.py b/Tools/autotest/param_metadata/htmlemit.py index e8c5205e33..493a0b6b5a 100644 --- a/Tools/autotest/param_metadata/htmlemit.py +++ b/Tools/autotest/param_metadata/htmlemit.py @@ -3,7 +3,7 @@ Emit docs in a form acceptable to the old Ardupilot wordpress docs site """ -from param import known_param_fields +from param import known_param_fields, known_units from emit import Emit import cgi @@ -71,6 +71,11 @@ DO NOT EDIT v = value.split(':') t += "%s%s\n" % (v[0], v[1]) t += "\n" + elif field == 'Units': + abreviated_units = param.__dict__[field] + if abreviated_units != '': + units = known_units[abreviated_units] # use the known_units dictionary to convert the abreviated unit into a full textual one + t += "
  • %s: %s
  • \n" % (field, cgi.escape(units)) else: t += "
  • %s: %s
  • \n" % (field, cgi.escape(param.__dict__[field])) t += "\n" diff --git a/Tools/autotest/param_metadata/param.py b/Tools/autotest/param_metadata/param.py index 3080c80076..02c21b9213 100644 --- a/Tools/autotest/param_metadata/param.py +++ b/Tools/autotest/param_metadata/param.py @@ -30,6 +30,71 @@ known_param_fields = [ 'ReadOnly', ] +# Follow SI units conventions from: +# http://physics.nist.gov/cuu/Units/units.html +# http://physics.nist.gov/cuu/Units/outside.html +# and +# http://physics.nist.gov/cuu/Units/checklist.html +# http://www.bipm.org/en/publications/si-brochure/ +# http://www1.bipm.org/en/CGPM/db/3/2/ g_n unit for G-force +# one further constrain is that only printable (7bit) ASCII characters are allowed +known_units = { +# abreviation : full-text (used in .html .rst and .wiki files) +# time + 's' : 'seconds' , + 'ds' : 'deciseconds' , + 'cs' : 'centiseconds' , + 'ms' : 'milliseconds' , + 'PWM' : 'PWM in microseconds' , # should be microseconds, this is NOT a SI unit, but follows https://github.com/ArduPilot/ardupilot/pull/5538#issuecomment-271943061 and µs is not 7bit-ASCII + 'Hz' : 'hertz' , +# distance + 'km' : 'kilometers' , # metre is the SI unit name, _NOT_ meter + 'm' : 'meters' , # metre is the SI unit name, _NOT_ meter + 'm/s' : 'meters per second' , # metre is the SI unit name, _NOT_ meter + 'm/s/s' : 'meters per square second' , # metre is the SI unit name, _NOT_ meter + 'm/s/s/s' : 'meters per cubic second' , # metre is the SI unit name, _NOT_ meter + 'cm' : 'centimeters' , # metre is the SI unit name, _NOT_ meter + 'cm/s' : 'centimeters per second' , # metre is the SI unit name, _NOT_ meter + 'cm/s/s' : 'centimeters per square second', # metre is the SI unit name, _NOT_ meter + 'cm/s/s/s': 'centimeters per cubic second' , # metre is the SI unit name, _NOT_ meter + 'mm' : 'millimeters' , # metre is the SI unit name, _NOT_ meter +# temperature + 'degC' : 'degrees Celsius' , # °C would be the correct abreviation, but it is not 7bit-ASCII +# angle + 'deg' : 'degrees' , # ° would be the correct abreviation, but it is not 7bit-ASCII + 'deg/s' : 'degrees per second' , # °/s would be the correct abreviation, but it is not 7bit-ASCII + 'cdeg' : 'centidegrees' , # c° would be the correct abreviation, but it is not 7bit-ASCII + 'cdeg/s' : 'centidegrees per second', # c°/s would be the correct abreviation, but it is not 7bit-ASCII + 'cdeg/s/s': 'centidegrees per square second' , + 'rad' : 'radians' , + 'rad/s' : 'radians per second' , + 'rad/s/s' : 'radians per square second' , +# electricity + 'A' : 'ampere' , + 'V' : 'volt' , + 'W' : 'watt' , +# magnetism + 'Gauss' : 'gauss' , # Gauss is not an SI unit, but 1 tesla = 10000 gauss so a simple replacement is not possible here + 'Gauss/s' : 'gauss per second' , # Gauss is not an SI unit, but 1 tesla = 10000 gauss so a simple replacement is not possible here + 'mGauss' : 'milligauss' , # Gauss is not an SI unit, but 1 tesla = 10000 gauss so a simple replacement is not possible here +# pressure + 'Pa' : 'pascal' , + 'mbar' : 'millibar' , +# ratio + '%' : 'percent' , + '%/s' : 'percent per second' , + 'd%' : 'decipercent' , # ‰ would be the correct abreviation, but it is not 7bit-ASCII. decipercent is strange, but "per-mille" is even more exotic +# compound + 'm.m/s/s' : 'square meter per square second', # m·m/s/s would be the correct abreviation, but it is not 7bit-ASCII + 'deg/m/s' : 'degrees per meter per second' , # °/m/s would be the correct abreviation, but it is not 7bit-ASCII + 'm/s/m' : 'meters per second per meter' , # Why not use Hz here ???? + 'mGauss/A': 'milligauss per ampere' , + 'mA.h' : 'milliampere hour' , # mA·h would be the correct abreviation, but it is not 7bit-ASCII + 'A/V' : 'ampere per volt' , + 'm/V' : 'meters per volt' , + 'gravities': 'standard acceleration due to gravity' , # g_n would be a more correct unit, but IMHO no one understands what g_n means + } + required_param_fields = [ 'Description', 'DisplayName', diff --git a/Tools/autotest/param_metadata/param_parse.py b/Tools/autotest/param_metadata/param_parse.py index 5056cc094e..a35d83928d 100755 --- a/Tools/autotest/param_metadata/param_parse.py +++ b/Tools/autotest/param_metadata/param_parse.py @@ -7,7 +7,7 @@ import sys from optparse import OptionParser from param import (Library, Parameter, Vehicle, known_group_fields, - known_param_fields, required_param_fields) + known_param_fields, required_param_fields, known_units) from htmlemit import HtmlEmit from rstemit import RSTEmit from wikiemit import WikiEmit @@ -203,6 +203,10 @@ def validate(param): if not is_number(max_value): error("Max value not number: %s %s" % (param.name, max_value)) return + # Validate units + if (hasattr(param, "Units")): + if (param.__dict__["Units"] != "") and (param.__dict__["Units"] not in known_units): + error("unknown units field '%s'" % param.__dict__["Units"]) for vehicle in vehicles: for param in vehicle.params: diff --git a/Tools/autotest/param_metadata/rstemit.py b/Tools/autotest/param_metadata/rstemit.py index da5b7f8db8..61528aeb7a 100644 --- a/Tools/autotest/param_metadata/rstemit.py +++ b/Tools/autotest/param_metadata/rstemit.py @@ -1,7 +1,7 @@ #!/usr/bin/env python from __future__ import print_function import re -from param import known_param_fields +from param import known_param_fields, known_units from emit import Emit import cgi @@ -241,6 +241,11 @@ Complete Parameter List elif field == "Range": (param_min, param_max) = (param.__dict__[field]).split(' ') row.append("%s - %s" % (param_min, param_max,)) + elif field == 'Units': + abreviated_units = param.__dict__[field] + if abreviated_units != '': + units = known_units[abreviated_units] # use the known_units dictionary to convert the abreviated unit into a full textual one + row.append(cgi.escape(units)) else: row.append(cgi.escape(param.__dict__[field])) if len(row): diff --git a/Tools/autotest/param_metadata/wikiemit.py b/Tools/autotest/param_metadata/wikiemit.py index 61da69834d..e921adb5e6 100644 --- a/Tools/autotest/param_metadata/wikiemit.py +++ b/Tools/autotest/param_metadata/wikiemit.py @@ -3,7 +3,7 @@ import re from emit import Emit -from param import known_param_fields +from param import known_param_fields, known_units # Emit docs in a form acceptable to the APM wiki site @@ -63,6 +63,11 @@ class WikiEmit(Emit): for value in values: v = value.split(':') t += "|| " + v[0] + " || " + self.camelcase_escape(v[1]) + " ||\n" + elif field == 'Units': + abreviated_units = param.__dict__[field] + if abreviated_units != '': + units = known_units[abreviated_units] # use the known_units dictionary to convert the abreviated unit into a full textual one + t += " * %s: %s\n" % (self.camelcase_escape(field), self.wikichars_escape(units)) else: t += " * %s: %s\n" % (self.camelcase_escape(field), self.wikichars_escape(param.__dict__[field])) diff --git a/Tools/autotest/param_metadata/xmlemit.py b/Tools/autotest/param_metadata/xmlemit.py index f14c7381a7..8e8d0b642a 100644 --- a/Tools/autotest/param_metadata/xmlemit.py +++ b/Tools/autotest/param_metadata/xmlemit.py @@ -3,7 +3,7 @@ from xml.sax.saxutils import escape, quoteattr from emit import Emit -from param import known_param_fields +from param import known_param_fields, known_units # Emit APM documentation in an machine readable XML format @@ -60,6 +60,12 @@ class XmlEmit(Emit): t += '''%s\n''' % (quoteattr(v[0]), escape(v[1])) # i.e. numeric value, string label t += "\n" + elif field == 'Units': + abreviated_units = param.__dict__[field] + if abreviated_units != '': + units = known_units[abreviated_units] # use the known_units dictionary to convert the abreviated unit into a full textual one + t += '''%s\n''' % (quoteattr(field), escape(abreviated_units)) # i.e. A/s + t += '''%s\n''' % (quoteattr('UnitText'), escape(units)) # i.e. ampere per second else: t += '''%s\n''' % (quoteattr(field), escape(param.__dict__[field])) # i.e. Range: 0 10