[go: nahoru, domu]

Skip to content

Commit

Permalink
Decimal representation of scale, offset, minimum and maximum.
Browse files Browse the repository at this point in the history
  • Loading branch information
eerimoq committed Nov 24, 2018
1 parent 68d4a4d commit 93525d2
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 15 deletions.
33 changes: 25 additions & 8 deletions cantools/database/can/formats/dbc.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from ..attribute_definition import AttributeDefinition
from ..attribute import Attribute
from ..signal import Signal
from ..signal import Decimal as SignalDecimal
from ..message import Message
from ..node import Node
from ..internal_database import InternalDatabase
Expand Down Expand Up @@ -962,16 +963,28 @@ def get_receivers(receivers):
return [_get_node_name(attributes, receiver) for receiver in receivers]

def get_minimum(minimum, maximum):
if minimum == maximum == 0:
if minimum == maximum == '0':
return None
else:
return minimum
return num(minimum)

def get_maximum(minimum, maximum):
if minimum == maximum == 0:
if minimum == maximum == '0':
return None
else:
return maximum
return num(maximum)

def get_minimum_decimal(minimum, maximum):
if minimum == maximum == '0':
return None
else:
return Decimal(minimum)

def get_maximum_decimal(minimum, maximum):
if minimum == maximum == '0':
return None
else:
return Decimal(maximum)

def get_protocol(frame_id_dbc):
"""Get protocol for a given message.
Expand Down Expand Up @@ -1063,10 +1076,14 @@ def get_signal_name(frame_id_dbc, name):
is_signed=(signal[8] == '-'),
scale=num(signal[10]),
offset=num(signal[12]),
minimum=get_minimum(num(signal[15]),
num(signal[17])),
maximum=get_maximum(num(signal[15]),
num(signal[17])),
minimum=get_minimum(signal[15], signal[17]),
maximum=get_maximum(signal[15], signal[17]),
decimal=SignalDecimal(Decimal(signal[10]),
Decimal(signal[12]),
get_minimum_decimal(signal[15],
signal[17]),
get_maximum_decimal(signal[15],
signal[17])),
unit=None if signal[19] == '' else signal[19],
choices=get_choices(frame_id_dbc,
signal[1][0]),
Expand Down
12 changes: 10 additions & 2 deletions cantools/database/can/formats/kcd.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
import sys
import logging
from collections import defaultdict
from decimal import Decimal

from xml.etree import ElementTree
from xml.etree.ElementTree import Element
from xml.etree.ElementTree import SubElement

from ..signal import Signal
from ..signal import Decimal as SignalDecimal
from ..message import Message
from ..node import Node
from ..bus import Bus
Expand Down Expand Up @@ -59,7 +61,8 @@ def _load_signal_element(signal, nodes):
labels = None
notes = None
receivers = []

decimal = SignalDecimal(Decimal(slope), Decimal(intercept))

# Signal XML attributes.
for key, value in signal.attrib.items():
if key == 'name':
Expand All @@ -80,12 +83,16 @@ def _load_signal_element(signal, nodes):
for key, value in value.attrib.items():
if key == 'min':
minimum = num(value)
decimal.minimum = Decimal(value)
elif key == 'max':
maximum = num(value)
decimal.maximum = Decimal(value)
elif key == 'slope':
slope = num(value)
decimal.scale = Decimal(value)
elif key == 'intercept':
intercept = num(value)
decimal.offset = Decimal(value)
elif key == 'unit':
unit = value
elif key == 'type':
Expand Down Expand Up @@ -135,7 +142,8 @@ def _load_signal_element(signal, nodes):
unit=unit,
choices=labels,
comment=notes,
is_float=is_float)
is_float=is_float,
decimal=decimal)


def _load_multiplex_element(mux, nodes):
Expand Down
16 changes: 13 additions & 3 deletions cantools/database/can/formats/sym.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import logging
from collections import OrderedDict as odict
from decimal import Decimal

from pyparsing import Word
from pyparsing import Literal
from pyparsing import Keyword
Expand All @@ -21,6 +23,7 @@
from pyparsing import ParseSyntaxException

from ..signal import Signal
from ..signal import Decimal as SignalDecimal
from ..message import Message
from ..internal_database import InternalDatabase

Expand Down Expand Up @@ -176,7 +179,8 @@ def _load_signal(tokens, enums):
maximum = None
enum = None
length = 0

decimal = SignalDecimal(Decimal(factor), Decimal(offset))

# Type and length.
type_ = tokens[1]

Expand Down Expand Up @@ -207,12 +211,16 @@ def _load_signal(tokens, enums):
unit = value
elif key == '/f:':
factor = num(value)
decimal.scale = Decimal(value)
elif key == '/o:':
offset = num(value)
decimal.offset = Decimal(value)
elif key == '/min:':
minimum = num(value)
decimal.minimum = Decimal(value)
elif key == '/max:':
maximum = num(value)
decimal.maximum = Decimal(value)
elif key == '/e:':
enum = enums[value]
else:
Expand All @@ -231,7 +239,8 @@ def _load_signal(tokens, enums):
unit=unit,
choices=enum,
is_multiplexer=False,
is_float=is_float)
is_float=is_float,
decimal=decimal)


def _load_signals(tokens, enums):
Expand Down Expand Up @@ -271,7 +280,8 @@ def _load_message_signal(tokens,
is_multiplexer=signal.is_multiplexer,
multiplexer_ids=multiplexer_ids,
multiplexer_signal=multiplexer_signal,
is_float=signal.is_float)
is_float=signal.is_float,
decimal=signal.decimal)


def _load_message_signals_inner(message_tokens,
Expand Down
1 change: 0 additions & 1 deletion cantools/database/can/formats/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

def num(number_as_string):
"""Convert given string to an integer or a float.
Expand Down
87 changes: 86 additions & 1 deletion cantools/database/can/signal.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,73 @@
# A CAN signal.

class Decimal(object):
"""Holds the same values as
:attr:`~cantools.database.can.Signal.scale`,
:attr:`~cantools.database.can.Signal.offset`,
:attr:`~cantools.database.can.Signal.minimum` and
:attr:`~cantools.database.can.Signal.maximum`, but as
``decimal.Decimal`` instead of ``int`` and ``float`` for higher
precision (no rounding errors).
"""

def __init__(self, scale=None, offset=None, minimum=None, maximum=None):
self._scale = scale
self._offset = offset
self._minimum = minimum
self._maximum = maximum

@property
def scale(self):
"""The scale factor of the signal value as ``decimal.Decimal``.
"""

return self._scale

@scale.setter
def scale(self, value):
self._scale = value

@property
def offset(self):
"""The offset of the signal value as ``decimal.Decimal``.
"""

return self._offset

@offset.setter
def offset(self, value):
self._offset = value

@property
def minimum(self):
"""The minimum value of the signal as ``decimal.Decimal``, or ``None``
if unavailable.
"""

return self._minimum

@minimum.setter
def minimum(self, value):
self._minimum = value

@property
def maximum(self):
"""The maximum value of the signal as ``decimal.Decimal``, or ``None``
if unavailable.
"""

return self._maximum

@maximum.setter
def maximum(self, value):
self._maximum = value


class Signal(object):
"""A CAN signal with position, size, unit and other information. A
signal is part of a message.
Expand Down Expand Up @@ -54,7 +122,8 @@ def __init__(self,
is_multiplexer=False,
multiplexer_ids=None,
multiplexer_signal=None,
is_float=False):
is_float=False,
decimal=None):
self._name = name
self._start = start
self._length = length
Expand All @@ -64,6 +133,7 @@ def __init__(self,
self._offset = offset
self._minimum = minimum
self._maximum = maximum
self._decimal = Decimal() if decimal is None else decimal
self._unit = unit
self._choices = choices
self._dbc = dbc_specifics
Expand Down Expand Up @@ -196,6 +266,21 @@ def maximum(self):
def maximum(self, value):
self._maximum = value

@property
def decimal(self):
"""The high precision values of
:attr:`~cantools.database.can.Signal.scale`,
:attr:`~cantools.database.can.Signal.offset`,
:attr:`~cantools.database.can.Signal.minimum` and
:attr:`~cantools.database.can.Signal.maximum`.
See :class:`~cantools.database.can.signal.Decimal` for more
details.
"""

return self._decimal

@property
def unit(self):
"""The unit of the signal as a string, or ``None`` if unavailable.
Expand Down
3 changes: 3 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ Functions and classes
.. autoclass:: cantools.database.can.Signal
:members:

.. autoclass:: cantools.database.can.signal.Decimal
:members:

.. autoclass:: cantools.database.diagnostics.Database
:members:

Expand Down
Loading

0 comments on commit 93525d2

Please sign in to comment.