danielhrisca / asammdf

Fast Python reader and editor for ASAM MDF / MF4 (Measurement Data Format) files
GNU Lesser General Public License v3.0
612 stars 216 forks source link

DBC file and negative values #964

Closed n10n-n10n closed 6 months ago

n10n-n10n commented 6 months ago

Python version

('python=3.9.13 (main, May 24 2022, 21:28:44) \n' '[Clang 13.0.0 (clang-1300.0.29.30)]') 'os=macOS-13.6-x86_64-i386-64bit' 'numpy=1.24.3' ldf is not supported xls is not supported xlsx is not supported 'asammdf=7.3.17'

Code

MDF version

N/A - generated MDF file

Code snippet

import numpy
from asammdf import MDF
from asammdf import Signal
from asammdf.blocks.source_utils import Source

types = [
    ('CAN_DataFrame.BusChannel', 'u1'),
    ('CAN_DataFrame.ID', '<u2'),
    ('CAN_DataFrame.IDE', 'u1'),
    ('CAN_DataFrame.DLC', 'u1'),
    ('CAN_DataFrame.DataLength', 'u1'),
    ('CAN_DataFrame.DataBytes', 'u1', (8,)),
    ('CAN_DataFrame.Dir', 'u1')
]

frame = [
    [0x01],   # BusChannel
    [0x7E8],  # Response PID
    [0x00],   # IDE
    [0x08],   # DLC
    [0x08],   # DataLength
    [[0x05, 0x62, 0x44, 0xD2, 0xFF, 0xC4, 0xAA, 0xAA]],   # DataBytes
    [0x00]    # Dir
]

src = Source(
    source_type=Source.SOURCE_BUS,
    bus_type=Source.BUS_TYPE_CAN,
    name="CAN1",
    path="CAN1",
    comment="CAN1")
sig = Signal(
    numpy.core.records.fromarrays(frame, numpy.dtype(types)),
    [numpy.datetime64()],
    name = 'CAN_DataFrame',
    comment = 'CAN1',
    raw = False,
    source = src
)

mdf = MDF(version = '4.10')
mdf.append([sig], comment='CAN_DataFrame', common_timebase=True)
mdf = mdf.extract_bus_logging(database_files = { 'CAN': [ ('issue.dbc',0) ], "LIN": []})

for ch in mdf.iter_channels():
    if ch.name.startswith('fuel_temperature'):
        print('{0}: {1}'.format(ch.name, ch.samples))

Traceback

N/A - no errors are thrown

Description

Having a DBC file as below, referred to as 'issue.dbc' in the code section:

BO_ 2024 Responses_7E8: 8 Vector__XXX
    SG_ MultiplexIndexSignal M : 15|24@0+ (1,0) [0|0] "" Vector__XXX
    SG_ fuel_temperature_1 m6440146 : 39|16@0+ (0.1,0) [-100|100] "C" 0x6244D2
    SG_ fuel_temperature_2 m6440146 : 39|16@0- (0.1,0) [-100|100] "C" 0x6244D2
    SG_ fuel_temperature_3 m6440146 : 38|15@0- (0.1,0) [-100|100] "C" 0x6244D2

The snippet outputs the following:

fuel_temperature_1: [6547.6]
fuel_temperature_2: [-1510.5]
fuel_temperature_3: [-6.]

The data extracted by DBC file is 16-bit signed integer starting from bit 39: 0xFFC4. It's extracted three times - fuel_temperature_1as unsigned integer, fuel_temperature_2 as signed and fuel_temperature_3 as signed but offset by 1 bit and only 15 bits of length.

Correct representation of 0xFFC4 as signed decimal is -60, hence -6.0 should be the correct result from DBC conversion minding the scaling and offset.

fuel_temperature_1 gives a correct result for unsigned integer - thus validating start bit and length

fuel_temperature_2 yields a clearly incorrect result - while the result is negative it's value is out of reasonable ranges.

fuel_temperature_3 yields correct looking result but has incorrect start bit in DBC and loses 1 bit of resolution.

n10n-n10n commented 6 months ago

I believe this is related to #884 - indeed with 7.2.0 DBC decoding seems to correctly interpret signed integers as demonstrated by fuel_temperature_2 output of above snippet

$ pip show asammdf | grep Version
Version: 7.2.0

$ python3 issue.py 
fuel_temperature_1: [6547.6]
fuel_temperature_2: [-6.]
fuel_temperature_3: [-6.]
danielhrisca commented 6 months ago

@n10n-n10n please try the development branch code

n10n-n10n commented 6 months ago

@danielhrisca thank you!

Development branch seems to fix the issue both for the above simple test case as well as multitude of my actual metrics - I think we can call this case closed.

$ pip show asammdf | grep Version
Version: 7.3.19.dev7

$ python3 issue.py 
fuel_temperature_1: [6547.6]
fuel_temperature_2: [-6.]
fuel_temperature_3: [-6.]