Skip to content

Commit 08a24da

Browse files
authored
Merge pull request #887 from BohdanBuinich/fix/arxml-compu-rational-robustness
Improve COMPU-RATIONAL-COEFFS scaling robustness Thanks!
2 parents 8233183 + a055bac commit 08a24da

1 file changed

Lines changed: 52 additions & 7 deletions

File tree

src/canmatrix/formats/arxml.py

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,16 +1105,61 @@ def decode_compu_method(compu_method, ea, float_factory):
11051105
# scale_desc = ea.get_element_desc(compu_scale)
11061106
if rational is not None:
11071107
numerator_parent = ea.get_child(rational, "COMPU-NUMERATOR")
1108-
numerator = ea.get_children(numerator_parent, "V")
1108+
numerator_vs = ea.get_children(numerator_parent, "V") if numerator_parent is not None else []
1109+
11091110
denominator_parent = ea.get_child(rational, "COMPU-DENOMINATOR")
1110-
denominator = ea.get_children(denominator_parent, "V")
1111+
denominator_vs = ea.get_children(denominator_parent, "V") if denominator_parent is not None else []
1112+
11111113
try:
1112-
factor = float_factory(numerator[1].text) / float_factory(denominator[0].text)
1113-
offset = float_factory(numerator[0].text) / float_factory(denominator[0].text)
1114-
except decimal.DivisionByZero:
1115-
if numerator[0].text != denominator[0].text or numerator[1].text != denominator[1].text:
1114+
# Parse coefficients
1115+
num = [float_factory(v.text) for v in numerator_vs]
1116+
1117+
# AUTOSAR: missing denominator usually implies 1
1118+
if denominator_vs:
1119+
den = [float_factory(v.text) for v in denominator_vs]
1120+
else:
1121+
den = [float_factory(1)]
1122+
1123+
d0 = den[0] if den else float_factory(1)
1124+
1125+
if d0 == 0:
1126+
raise decimal.DivisionByZero
1127+
1128+
# Detect polynomial (more than linear)
1129+
if len(num) > 2 or len(den) > 1:
11161130
logger.warning(
1117-
"ARXML signal scaling: polynom is not supported and it is replaced by factor=1 and offset =0.")
1131+
"ARXML signal scaling: polynomial scaling not fully supported, "
1132+
"replacing by factor=1 and offset=0. "
1133+
"numerator=%r denominator=%r",
1134+
num, den,
1135+
)
1136+
factor = float_factory(1)
1137+
offset = float_factory(0)
1138+
else:
1139+
# Linear / affine cases
1140+
if len(num) >= 2:
1141+
# phys = (num0 + num1 * raw) / d0
1142+
offset = num[0] / d0
1143+
factor = num[1] / d0
1144+
elif len(num) == 1:
1145+
# Only offset or constant mapping: phys = num0 / d0
1146+
offset = num[0] / d0
1147+
factor = float_factory(0)
1148+
else:
1149+
# No coefficients — keep default 1/0 and warn
1150+
logger.warning(
1151+
"ARXML signal scaling: COMPU-RATIONAL-COEFFS without coefficients. "
1152+
"Using factor=1 and offset=0."
1153+
)
1154+
factor = float_factory(1)
1155+
offset = float_factory(0)
1156+
1157+
except (decimal.DivisionByZero, decimal.InvalidOperation, IndexError) as e:
1158+
logger.warning(
1159+
"ARXML signal scaling: invalid rational coefficients (%s). "
1160+
"Replacing with factor=1 and offset=0. numerator=%r denominator=%r",
1161+
e, [v.text for v in numerator_vs], [v.text for v in denominator_vs],
1162+
)
11181163
factor = float_factory(1)
11191164
offset = float_factory(0)
11201165
else:

0 commit comments

Comments
 (0)