[go: nahoru, domu]

Skip to content

Commit

Permalink
Merge pull request cantools#281 from Daimler/arxml_non_decimal_encodings
Browse files Browse the repository at this point in the history
ARXML: allow to specify non-base 10 integer numbers
  • Loading branch information
eerimoq committed Mar 2, 2021
2 parents 87d1ec2 + ca16382 commit 2f66e18
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 18 deletions.
40 changes: 26 additions & 14 deletions cantools/database/can/formats/arxml.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,17 @@

LOGGER = logging.getLogger(__name__)

def parse_int_string(in_string):
in_string = in_string.strip()
if not in_string:
return 0
elif in_string[0] == '0' and in_string[1:2].isdigit():
# interpret strings starting with a 0 as octal because
# python's int(*, 0) does not for some reason.
return int(in_string, 8)

return int(in_string, 0) # autodetect the base

class SystemLoader(object):
def __init__(self, root, strict):
self._root = root
Expand Down Expand Up @@ -263,12 +274,12 @@ def _load_message_name(self, can_frame_triggering):
'SHORT-NAME').text

def _load_message_frame_id(self, can_frame_triggering):
return int(self._get_unique_arxml_child(can_frame_triggering,
'IDENTIFIER').text)
return parse_int_string(self._get_unique_arxml_child(can_frame_triggering,
'IDENTIFIER').text)

def _load_message_length(self, can_frame):
return int(self._get_unique_arxml_child(can_frame,
'FRAME-LENGTH').text)
return parse_int_string(self._get_unique_arxml_child(can_frame,
'FRAME-LENGTH').text)

def _load_message_is_extended_frame(self, can_frame_triggering):
can_addressing_mode = \
Expand Down Expand Up @@ -354,7 +365,7 @@ def _load_signal(self, i_signal_to_i_pdu_mapping):
initial = False
# TODO: strings?
else:
initial = int(initial)
initial = parse_int_string(initial)

# ToDo: receivers

Expand All @@ -380,14 +391,15 @@ def _load_signal_name(self, i_signal):
'SHORT-NAME').text

def _load_signal_start_position(self, i_signal_to_i_pdu_mapping):
return int(self._get_unique_arxml_child(i_signal_to_i_pdu_mapping,
'START-POSITION').text)
pos = self._get_unique_arxml_child(i_signal_to_i_pdu_mapping,
'START-POSITION').text
return parse_int_string(pos)

def _load_signal_length(self, i_signal, system_signal):
i_signal_length = self._get_unique_arxml_child(i_signal, 'LENGTH')

if i_signal_length is not None:
return int(i_signal_length.text)
return parse_int_string(i_signal_length.text)

if not self.autosar_version_newer(4) and system_signal is not None:
# AUTOSAR3 supports specifying the signal length via the
Expand All @@ -396,7 +408,7 @@ def _load_signal_length(self, i_signal, system_signal):
'LENGTH')
if system_signal_length is not None:
# get the length from the system signal.
return int(system_signal_length.text)
return parse_int_string(system_signal_length.text)

return None # error?!

Expand Down Expand Up @@ -518,7 +530,7 @@ def _load_texttable(self, compu_method, decimal, is_float):
maximum = None
choices = {}

text_to_num_fn = float if is_float else int
text_to_num_fn = float if is_float else parse_int_string

for compu_scale in self._get_arxml_children(compu_method,
[
Expand All @@ -537,7 +549,7 @@ def _load_texttable(self, compu_method, decimal, is_float):
if maximum is None: maximum = maximum_scale
elif maximum_scale is not None: maximum = max(maximum, maximum_scale)
if vt is not None:
choices[vt.text] = int(lower_limit.text)
choices[vt.text] = text_to_num_fn(lower_limit.text)

decimal.minimum = minimum
decimal.maximum = maximum
Expand Down Expand Up @@ -583,7 +595,7 @@ def _load_linear(self, compu_method, decimal, is_float):
lower_limit = self._get_unique_arxml_child(compu_scale, '&LOWER-LIMIT')
upper_limit = self._get_unique_arxml_child(compu_scale, '&UPPER-LIMIT')

text_to_num_fn = float if is_float else int
text_to_num_fn = float if is_float else parse_int_string
minimum = None if lower_limit is None else text_to_num_fn(lower_limit.text)
maximum = None if upper_limit is None else text_to_num_fn(upper_limit.text)

Expand All @@ -600,7 +612,7 @@ def _load_scale_linear_and_texttable(self, compu_method, decimal, is_float):
offset = 0
choices = {}

text_to_num_fn = float if is_float else int
text_to_num_fn = float if is_float else parse_int_string

for compu_scale in self._get_arxml_children(compu_method,
[
Expand Down Expand Up @@ -632,7 +644,7 @@ def _load_scale_linear_and_texttable(self, compu_method, decimal, is_float):

if vt is not None:
assert(minimum_scale is not None and minimum_scale == maximum_scale)
choices[vt.text] = int(minimum_scale)
choices[vt.text] = minimum_scale

decimal.minimum = Decimal(minimum)
decimal.maximum = Decimal(maximum)
Expand Down
8 changes: 4 additions & 4 deletions tests/files/arxml/system-4.2.arxml
Original file line number Diff line number Diff line change
Expand Up @@ -101,15 +101,15 @@
<SHORT-NAME>signal1</SHORT-NAME>
<INIT-VALUE>
<NUMERICAL-VALUE-SPECIFICATION>
<VALUE>5</VALUE>
<VALUE>0b101</VALUE>
</NUMERICAL-VALUE-SPECIFICATION>
</INIT-VALUE>
<LENGTH>3</LENGTH>
<LENGTH>0b11</LENGTH>
<SYSTEM-SIGNAL-REF DEST="SYSTEM-SIGNAL">/SystemSignal/Signal1</SYSTEM-SIGNAL-REF>
</I-SIGNAL>
<I-SIGNAL UUID="b077fb759e9e255d0ddb6e6ab49b8d7c">
<SHORT-NAME>signal2</SHORT-NAME>
<LENGTH>11</LENGTH>
<LENGTH>0xb</LENGTH>
<NETWORK-REPRESENTATION-PROPS>
<SW-DATA-DEF-PROPS-VARIANTS>
<SW-DATA-DEF-PROPS-CONDITIONAL>
Expand All @@ -121,7 +121,7 @@
</I-SIGNAL>
<I-SIGNAL UUID="1b81d9d6c79916117b4848178814a31a">
<SHORT-NAME>signal2_1c</SHORT-NAME>
<LENGTH>11</LENGTH>
<LENGTH>013</LENGTH>
<NETWORK-REPRESENTATION-PROPS>
<SW-DATA-DEF-PROPS-VARIANTS>
<SW-DATA-DEF-PROPS-CONDITIONAL>
Expand Down

0 comments on commit 2f66e18

Please sign in to comment.