Skip to content

Commit

Permalink
Merge pull request #351 from Daimler/DBC_write_cycle_time
Browse files Browse the repository at this point in the history
  • Loading branch information
juleq committed Oct 13, 2021
2 parents ea17e2a + 7fb7837 commit d2617c9
Show file tree
Hide file tree
Showing 18 changed files with 98 additions and 55 deletions.
100 changes: 63 additions & 37 deletions cantools/database/can/formats/dbc.py
Original file line number Diff line number Diff line change
Expand Up @@ -606,14 +606,27 @@ def _dump_signal_types(database):

return valtype

def _create_GenMsgCycleTime_definition():
return AttributeDefinition('GenMsgCycleTime',
default_value=0,
kind='BO_',
type_name='INT',
minimum=0,
maximum=2**16-1)

def _dump_attribute_definitions(database):
ba_def = []

if database.dbc is None:
return ba_def
definitions = odict()
else:
definitions = database.dbc.attribute_definitions

definitions = database.dbc.attribute_definitions
# define "GenMsgCycleTime" attribute for specifying the cycle
# times of messages if it has not been explicitly defined
if 'GenMsgCycleTime' not in definitions:
definitions['GenMsgCycleTime'] = \
_create_GenMsgCycleTime_definition()

def get_value(definition, value):
if definition.minimum is None:
Expand Down Expand Up @@ -664,9 +677,15 @@ def _dump_attribute_definition_defaults(database):
ba_def_def = []

if database.dbc is None:
return ba_def_def
definitions = odict()
else:
definitions = database.dbc.attribute_definitions

definitions = database.dbc.attribute_definitions
# define "GenMsgCycleTime" attribute for specifying the cycle
# times of messages if it has not been explicitly defined
if 'GenMsgCycleTime' not in definitions:
definitions['GenMsgCycleTime'] = \
_create_GenMsgCycleTime_definition()

for definition in definitions.values():
if definition.default_value is not None:
Expand All @@ -680,7 +699,6 @@ def _dump_attribute_definition_defaults(database):

return ba_def_def


def _dump_attributes(database):
ba = []

Expand All @@ -695,43 +713,49 @@ def get_value(attribute):
if database.dbc is not None:
if database.dbc.attributes is not None:
for attribute in database.dbc.attributes.values():
ba.append(
'BA_ "{name}" {value};'.format(name=attribute.definition.name,
value=get_value(attribute)))
ba.append(f'BA_ "{attribute.definition.name}" '
f'{get_value(attribute)};')

for node in database.nodes:
if node.dbc is not None:
if node.dbc.attributes is not None:
for attribute in node.dbc.attributes.values():
ba.append(
'BA_ "{name}" {kind} {node_name} {value};'.format(
name=attribute.definition.name,
kind=attribute.definition.kind,
node_name=node.name,
value=get_value(attribute)))
ba.append(f'BA_ "{attribute.definition.name}" '
f'{attribute.definition.kind} '
f'{node.name} '
f'{get_value(attribute)};')

for message in database.messages:
if message.dbc is not None:
if message.dbc.attributes is not None:
for attribute in message.dbc.attributes.values():
ba.append(
'BA_ "{name}" {kind} {frame_id} {value};'.format(
name=attribute.definition.name,
kind=attribute.definition.kind,
frame_id=get_dbc_frame_id(message),
value=get_value(attribute)))

# retrieve the ordered dictionary of message attributes
msg_attributes = odict()
if message.dbc is not None and message.dbc.attributes is not None:
msg_attributes = message.dbc.attributes

# synchronize the attribute for the message cycle time with
# the cycle time specified by the message object
if message.cycle_time is None and 'GenMsgCycleTime' in msg_attributes:
del msg_attributes['GenMsgCycleTime']
elif message.cycle_time is not None:
msg_attributes['GenMsgCycleTime'] = \
Attribute(value=message.cycle_time,
definition=_create_GenMsgCycleTime_definition())

# output all message attributes
for attribute in msg_attributes.values():
ba.append(f'BA_ "{attribute.definition.name}" '
f'{attribute.definition.kind} '
f'{get_dbc_frame_id(message)} '
f'{get_value(attribute)};')

# handle the signals contained in the message
for signal in message.signals[::-1]:
if signal.dbc is not None:
if signal.dbc.attributes is not None:
for attribute in signal.dbc.attributes.values():
ba.append(
'BA_ "{name}" {kind} {frame_id} {signal_name} {value};'.format(
name=attribute.definition.name,
kind=attribute.definition.kind,
frame_id=get_dbc_frame_id(message),
signal_name=signal.name,
value=get_value(attribute)))
if signal.dbc is not None and signal.dbc.attributes is not None:
for attribute in signal.dbc.attributes.values():
ba.append(f'BA_ "{attribute.definition.name}" '
f'{attribute.definition.kind} '
f'{get_dbc_frame_id(message)} '
f'{signal.name} '
f'{get_value(attribute)};')

return ba

Expand Down Expand Up @@ -1247,7 +1271,7 @@ def get_signal_initial_value(frame_id_dbc, name):

def get_signal_spn(frame_id_dbc, name):
signal_attributes = get_attributes(frame_id_dbc, name)

try:
return signal_attributes['SPN'].value
except (KeyError, TypeError):
Expand Down Expand Up @@ -1357,10 +1381,12 @@ def get_cycle_time(frame_id_dbc):
message_attributes = get_attributes(frame_id_dbc)

try:
return int(message_attributes['GenMsgCycleTime'].value)
result = int(message_attributes['GenMsgCycleTime'].value)
return None if result == 0 else result
except (KeyError, TypeError):
try:
return int(definitions['GenMsgCycleTime'].default_value)
result = int(definitions['GenMsgCycleTime'].default_value)
return None if result == 0 else result
except (KeyError, TypeError):
return None

Expand Down
3 changes: 3 additions & 0 deletions cantools/subparsers/list.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ def _print_message(message):
print(f' Size: {message.length} bytes')
print(f' Is extended frame: {message.is_extended_frame}')

if message.cycle_time is not None:
print(f' Cycle time: {message.cycle_time} ms')

if message.signals:
print(f' Signals:')

Expand Down
2 changes: 1 addition & 1 deletion tests/files/c_source/multiplex.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ extern "C" {
#define MULTIPLEX_MESSAGE1_IS_EXTENDED (1)

/* Frame cycle times in milliseconds. */
#define MULTIPLEX_MESSAGE1_CYCLE_TIME_MS (0u)


/* Signal choices. */

Expand Down
5 changes: 1 addition & 4 deletions tests/files/c_source/multiplex_2.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,7 @@ extern "C" {
#define MULTIPLEX_2_EXTENDED_TYPES_IS_EXTENDED (1)

/* Frame cycle times in milliseconds. */
#define MULTIPLEX_2_SHARED_CYCLE_TIME_MS (0u)
#define MULTIPLEX_2_NORMAL_CYCLE_TIME_MS (0u)
#define MULTIPLEX_2_EXTENDED_CYCLE_TIME_MS (0u)
#define MULTIPLEX_2_EXTENDED_TYPES_CYCLE_TIME_MS (0u)


/* Signal choices. */

Expand Down
4 changes: 2 additions & 2 deletions tests/files/dbc/floating_point.dbc
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ BO_ 1025 Message2: 8 TestNode


CM_ BU_ TestNode "";


BA_DEF_ BO_ "GenMsgCycleTime" INT 0 65535;
BA_DEF_DEF_ "GenMsgCycleTime" 0;


SIG_VALTYPE_ 1024 Signal1 : 2;
Expand Down
2 changes: 2 additions & 0 deletions tests/files/dbc/mod_name_len_dest.dbc
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,11 @@ CM_ BU_ node_now_short "";
BA_DEF_ BU_ "SystemNodeLongSymbol" STRING ;
BA_DEF_ BO_ "SystemMessageLongSymbol" STRING ;
BA_DEF_ SG_ "SystemSignalLongSymbol" STRING ;
BA_DEF_ BO_ "GenMsgCycleTime" INT 0 65535;
BA_DEF_DEF_ "SystemNodeLongSymbol" "";
BA_DEF_DEF_ "SystemMessageLongSymbol" "";
BA_DEF_DEF_ "SystemSignalLongSymbol" "";
BA_DEF_DEF_ "GenMsgCycleTime" 0;



Expand Down
4 changes: 2 additions & 2 deletions tests/files/dbc/motohawk.dbc
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ BO_ 496 ExampleMessage: 8 PCM1


CM_ BO_ 496 "Example message used as template in MotoHawk models.";


BA_DEF_ BO_ "GenMsgCycleTime" INT 0 65535;
BA_DEF_DEF_ "GenMsgCycleTime" 0;

VAL_ 496 Enable 0 "Disabled" 1 "Enabled" ;

Expand Down
4 changes: 2 additions & 2 deletions tests/files/dbc/multiple_senders.dbc
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ BO_TX_BU_ 1 : FOO,BAR,FIE;





BA_DEF_ BO_ "GenMsgCycleTime" INT 0 65535;
BA_DEF_DEF_ "GenMsgCycleTime" 0;



Expand Down
2 changes: 2 additions & 0 deletions tests/files/dbc/sig_groups.dbc
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ BO_ 0 NormalMsg: 8 Vector__XXX


BA_DEF_ "BusType" STRING ;
BA_DEF_ BO_ "GenMsgCycleTime" INT 0 65535;
BA_DEF_DEF_ "BusType" "CAN";
BA_DEF_DEF_ "GenMsgCycleTime" 0;



Expand Down
2 changes: 2 additions & 0 deletions tests/files/dbc/sig_groups_del.dbc
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ BO_ 0 NormalMsg: 8 Vector__XXX


BA_DEF_ "BusType" STRING ;
BA_DEF_ BO_ "GenMsgCycleTime" INT 0 65535;
BA_DEF_DEF_ "BusType" "CAN";
BA_DEF_DEF_ "GenMsgCycleTime" 0;



Expand Down
2 changes: 2 additions & 0 deletions tests/files/dbc/sig_groups_out.dbc
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ BO_ 0 NormalMsg: 8 Vector__XXX


BA_DEF_ "BusType" STRING ;
BA_DEF_ BO_ "GenMsgCycleTime" INT 0 65535;
BA_DEF_DEF_ "BusType" "CAN";
BA_DEF_DEF_ "GenMsgCycleTime" 0;



Expand Down
2 changes: 2 additions & 0 deletions tests/files/dbc/val_table.dbc
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ BO_ 0 Message1: 8 Vector__XXX


BA_DEF_ "BusType" STRING ;
BA_DEF_ BO_ "GenMsgCycleTime" INT 0 65535;
BA_DEF_DEF_ "BusType" "";
BA_DEF_DEF_ "GenMsgCycleTime" 0;

VAL_ 0 Signal1 1 "One" 0 "Zero" ;

Expand Down
2 changes: 2 additions & 0 deletions tests/files/dbc/vehicle.dbc
Original file line number Diff line number Diff line change
Expand Up @@ -1174,7 +1174,9 @@ CM_ SG_ 2303356194 Validity_Gyro_Rate_Roll "Valid when bit is set, invalid when
CM_ SG_ 2303356194 Validity_Gyro_Rate_Pitch "Valid when bit is set, invalid when bit is clear.";
CM_ SG_ 2303356194 Validity_Gyro_Rate_Yaw "Valid when bit is set, invalid when bit is clear.";
BA_DEF_ SG_ "GenSigStartValue" INT -2147483648 2147483647;
BA_DEF_ BO_ "GenMsgCycleTime" INT 0 65535;
BA_DEF_DEF_ "GenSigStartValue" 0;
BA_DEF_DEF_ "GenMsgCycleTime" 0;
BA_ "GenSigStartValue" SG_ 2304279330 Validity_INS_Vel_Forwards 0;
BA_ "GenSigStartValue" SG_ 2303355937 Accel_Vertical 16120;
BA_ "GenSigStartValue" SG_ 2303355937 Accel_Lateral -30000;
Expand Down
6 changes: 3 additions & 3 deletions tests/test_command_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -880,7 +880,7 @@ def test_dump_with_comments_mux(self):
Destination: 0x34
Format: PDU 1
Length: 8 bytes
Cycle time: 0 ms
Cycle time: - ms
Senders: -
Layout:
Expand Down Expand Up @@ -1102,7 +1102,7 @@ def test_dump_j1939(self):
Destination: 0x02
Format: PDU 1
Length: 8 bytes
Cycle time: 0 ms
Cycle time: - ms
Senders: Node1
Layout:
Expand Down Expand Up @@ -1144,7 +1144,7 @@ def test_dump_j1939(self):
Destination: All
Format: PDU 2
Length: 8 bytes
Cycle time: 0 ms
Cycle time: - ms
Senders: Node2
Layout:
Expand Down
7 changes: 4 additions & 3 deletions tests/test_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -2055,9 +2055,10 @@ def test_timing(self):
self.assertEqual(message.cycle_time, 200)
self.assertEqual(message.send_type, 'Cyclic')

# Default message cycle time is 0, as given by BA_DEF_DEF_.
# Default message cycle time is None which is defined in the
# DBC as 0 (as given by BA_DEF_DEF_)
message = db.get_message_by_frame_id(2)
self.assertEqual(message.cycle_time, 0)
self.assertEqual(message.cycle_time, None)
self.assertEqual(message.send_type, 'NoMsgSendType')

self.assert_dbc_dump(db, filename)
Expand Down Expand Up @@ -4736,7 +4737,7 @@ def test_bus_comment(self):

# This file is not '__main__' when executed via 'python setup.py3
# test'.
logging.basicConfig(level=logging.DEBUG)
logging.basicConfig(level=logging.WARNING)

if __name__ == '__main__':
unittest.main()
2 changes: 1 addition & 1 deletion tests/test_diagnostics_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ def test_unknown_byteorder(self):

# This file is not '__main__' when executed via 'python setup.py3
# test'.
logging.basicConfig()
logging.basicConfig(level=logging.WARNING)

if __name__ == '__main__':
unittest.main()
2 changes: 2 additions & 0 deletions tests/test_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ def test_arxml4(self):
Frame ID: 0x6 (6)
Size: 7 bytes
Is extended frame: True
Cycle time: 200 ms
Signals:
signal3:
Type: Integer
Expand Down Expand Up @@ -283,6 +284,7 @@ def test_kcd(self):
Frame ID: 0x2 (2)
Size: 4 bytes
Is extended frame: False
Cycle time: 100 ms
Signals:
Signal1:
Type: Integer
Expand Down
2 changes: 2 additions & 0 deletions tests/test_plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
from io import StringIO
import cantools
import matplotlib.pyplot
import logging

logging.basicConfig(level=logging.WARNING)

class PyplotMock:

Expand Down

0 comments on commit d2617c9

Please sign in to comment.