Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] cycle_time as generic signal and frame attribute #405

Merged
merged 3 commits into from
Oct 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/cli.rst
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,8 @@ ____________________


* yaml
* scapy
* lua
* json:

--jsonExportCanard
Expand Down
4 changes: 2 additions & 2 deletions examples/BusmasterRestbus.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,10 +171,10 @@ def ticker_ecus(db, dbcname):
bu._cycles = {}
for frame in db.frames:
if bu.name in frame.transmitters:
if "GenMsgCycleTime" in frame.attributes and "GenMsgStartValue" in frame.attributes:
if frame.effective_cycle_time != 0 and "GenMsgStartValue" in frame.attributes:
data = frame.attributes["GenMsgStartValue"][1:-2]
dlc = (math.floor(len(data) / 2))
cycleTime = int(frame.attributes["GenMsgCycleTime"])
cycleTime = frame.effective_cycle_time
if float(cycleTime) > 0:
if cycleTime in bu._cycles:
bu._cycles[cycleTime].append(frame.arbitration_id.id)
Expand Down
4 changes: 2 additions & 2 deletions examples/createccl.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,9 @@ def main():
txDict[frame] = sendIndex
sendIndex += 1
# print frame.name
# if "GenMsgCycleTime" in frame.attributes and int(frame.attributes["GenMsgCycleTime"]) != 0:
# if frame.effective_cycletime != 0:
# print frame.name,
# print frame.attributes["GenMsgCycleTime"]
# print frame.effective_cycletime
# ccl_h += createStoreMacrosForFrame(frame, "_" + frame.name + "_")

tempStr = ""
Expand Down
32 changes: 20 additions & 12 deletions src/canmatrix/canmatrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import itertools
import logging
import math
import fractions
import struct
import typing
from builtins import *
Expand Down Expand Up @@ -165,6 +166,8 @@ class Signal(object):
calc_min_for_none = attr.ib(default=True) # type: bool
calc_max_for_none = attr.ib(default=True) # type: bool

cycle_time = attr.ib(default=0) # type: int

min = attr.ib(
converter=lambda value, float_factory=float_factory: (
float_factory(value)
Expand Down Expand Up @@ -754,6 +757,8 @@ class Frame(object):
receivers = attr.ib(factory=list) # type: typing.MutableSequence[str]
signalGroups = attr.ib(factory=list) # type: typing.MutableSequence[SignalGroup]

cycle_time = attr.ib(default=0) # type: int

is_j1939 = attr.ib(default=False) # type: bool
# ('cycleTime', '_cycleTime', int, None),
# ('sendType', '_sendType', str, None),
Expand Down Expand Up @@ -828,27 +833,30 @@ def source(self, value): # type: (int) -> None
self.arbitration_id.j1939_source = value


# @property
# def cycleTime(self):
# if self._cycleTime is None:
# self._cycleTime = self.attribute("GenMsgCycleTime")
# return self._cycleTime
#
@property
def effective_cycle_time(self):
"""Calculate effective cycle time for frame, depending on singal cycle times"""
min_cycle_time_list = [y for y in [x.cycle_time for x in self.signals] + [self.cycle_time] if y != 0]
if len(min_cycle_time_list) == 0:
return 0
elif len(min_cycle_time_list) == 1:
return min_cycle_time_list[0]
else:
gcd = fractions.gcd(min_cycle_time_list[0],min_cycle_time_list[1])
for i in range(2,len(min_cycle_time_list)):
gcd = fractions.gcd(gcd, min_cycle_time_list[i])
return gcd
# return min(min_cycle_time_list)

# @property
# def sendType(self, db = None):
# if self._sendType is None:
# self._sendType = self.attribute("GenMsgSendType")
# return self._sendType
#
# @cycleTime.setter
# def cycleTime(self, value):
# self._cycleTime = value
# self.attributes["GenMsgCycleTime"] = value
#
# @sendType.setter
# def sendType(self, value):
# self._sendType = value
# self.attributes["GenMsgCycleTime"] = value

def attribute(self, attribute_name, db=None, default=None):
# type: (str, typing.Optional[CanMatrix], typing.Any) -> typing.Any
Expand Down
4 changes: 2 additions & 2 deletions src/canmatrix/cli/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def get_formats():
@click.option('--deleteSignal', 'deleteSignal', help="delete Signal form databases. (comma separated list)\nSyntax: --deleteSignal=mySignal1,mySecondSignal")
@click.option('--renameSignal', 'renameSignal', help="rename Signal form databases. (comma separated list)\nSyntax: --renameSignal=myOldSignal:myNewSignal,mySecondSignal:mySecondNewSignal")
@click.option('--deleteZeroSignals/--no-deleteZeroSignals', 'deleteZeroSignals', default=False, help="delete zero length signals (signals with 0 bit length) from matrix\ndefault False")
@click.option('--deleteSignalAttributes', 'deleteSignalAttributes', help="delete attributes from all signals\nExample --deleteSignalAttributes GenMsgCycle,CycleTime")
@click.option('--deleteSignalAttributes', 'deleteSignalAttributes', help="delete attributes from all signals\nExample --deleteSignalAttributes GenMsgSomeVar,CycleTime")
@click.option('--deleteFrame', 'deleteFrame', help="delete Frame form databases. (comma separated list)\nSyntax: --deleteFrame=myFrame1,mySecondFrame")
@click.option('--renameFrame', 'renameFrame', help="increment each frame.id in database by increment\nSyntax: --frameIdIncrement=increment")
@click.option('--addFrameReceiver', 'addFrameReceiver', help="add receiver Ecu to frame(s) (comma separated list)\nSyntax: --addFrameReceiver=framename:myNewEcu,mySecondEcu:myNEWEcu")
Expand All @@ -69,7 +69,7 @@ def get_formats():
@click.option('--recalcDLC', 'recalcDLC', help="recalculate dlc; max: use maximum of stored and calculated dlc; force: force new calculated dlc")
@click.option('--skipLongDlc', 'skipLongDlc', help="skip all Frames with dlc bigger than given threshold")
@click.option('--cutLongFrames', 'cutLongFrames', help="cut all signals out of Frames with dlc bigger than given threshold")
@click.option('--deleteFrameAttributes', 'deleteFrameAttributes', help="delete attributes from all frames\nExample --deleteFrameAttributes GenMsgCycle,CycleTime")
@click.option('--deleteFrameAttributes', 'deleteFrameAttributes', help="delete attributes from all frames\nExample --deleteFrameAttributes GenMsgSomeVar,CycleTime")
@click.option('--ecus', help="Copy only given ECUs (comma separated list) to target matrix")
@click.option('--frames', help="Copy only given Frames (comma separated list) to target matrix")
@click.option('--signals', help="Copy only given Signals (comma separated list) to target matrix just as 'free' signals without containing frame")
Expand Down
5 changes: 2 additions & 3 deletions src/canmatrix/formats/arxml.py
Original file line number Diff line number Diff line change
Expand Up @@ -1316,11 +1316,11 @@ def store_frame_timings(target_frame, cyclic_timing, event_timing, minimum_delay

value = get_child(repeating_time, "VALUE", root_or_cache, ns)
if value is not None:
target_frame.add_attribute("GenMsgCycleTime", str(int(float_factory(value.text) * 1000)))
target_frame.cycle_time = int(float_factory(value.text) * 1000)
elif cyclic_timing is not None:
value = get_child(time_period, "VALUE", root_or_cache, ns)
if value is not None:
target_frame.add_attribute("GenMsgCycleTime", str(int(float_factory(value.text) * 1000)))
target_frame.cycle_time = int(float_factory(value.text) * 1000)


def get_frame(frame_triggering, root_or_cache, multiplex_translation, ns, float_factory):
Expand Down Expand Up @@ -1659,7 +1659,6 @@ def load(file, **options):
db.add_ecu_defines("NWM-Stationsadresse", 'HEX 0 63')
db.add_ecu_defines("NWM-Knoten", 'ENUM "nein","ja"')
db.add_signal_defines("LongName", 'STRING')
db.add_frame_defines("GenMsgCycleTime", 'INT 0 65535')
db.add_frame_defines("GenMsgDelayTime", 'INT 0 65535')
db.add_frame_defines("GenMsgNrOfRepetitions", 'INT 0 65535')
db.add_frame_defines("GenMsgStartValue", 'STRING')
Expand Down
22 changes: 21 additions & 1 deletion src/canmatrix/formats/dbc.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,12 @@ def dump(in_db, f, **options):

numbered_names = collections.OrderedDict() # type: ignore

if frame.cycle_time != 0:
frame.add_attribute("GenMsgCycleTime", frame.cycle_time)

for signal in frame.signals:
if signal.cycle_time != 0:
signal.add_attribute("GenSigCycleTime", signal.cycle_time)
name = normalized_names[signal]
if compatibility:
name = re.sub("[^A-Za-z0-9]", whitespace_replacement, name)
Expand All @@ -238,6 +243,13 @@ def dump(in_db, f, **options):
name += str(duplicate_signal_counter[name] - 1)
output_names[frame][signal] = name

if max([x.cycle_time for x in db.frames]) > 0:
db.add_frame_defines("GenMsgCycleTime", 'INT 0 65535')
if max([x.cycle_time for y in db.frames for x in y.signals]) > 0:
db.add_signal_defines("GenSigCycleTime", 'INT 0 65535')



# Frames
for frame in db.frames:
multiplex_written = False
Expand Down Expand Up @@ -905,6 +917,7 @@ def add_frame_by_id(new_frame): # type: (canmatrix.Frame) -> None
ecu.name = ecu.attributes.get("SystemNodeLongSymbol")[1:-1]
ecu.del_attribute("SystemNodeLongSymbol")
for frame in db.frames:
frame.cycle_time = int(frame.attributes.get("GenMsgCycleTime", 0))
if frame.attributes.get("SystemMessageLongSymbol", None) is not None:
frame.name = frame.attributes.get("SystemMessageLongSymbol")[1:-1]
frame.del_attribute("SystemMessageLongSymbol")
Expand All @@ -917,6 +930,7 @@ def add_frame_by_id(new_frame): # type: (canmatrix.Frame) -> None
# frame.extended = 1

for signal in frame.signals:
signal.cycle_time = int(signal.attributes.get("GenSigCycleTime", 0))
if signal.attribute("SystemSignalLongSymbol") is not None:
signal.name = signal.attribute("SystemSignalLongSymbol")[1:-1]
signal.del_attribute("SystemSignalLongSymbol")
Expand Down Expand Up @@ -947,9 +961,15 @@ def add_frame_by_id(new_frame): # type: (canmatrix.Frame) -> None
frame.is_fd = True
if "J1939PG" in frame.attributes.get("VFrameFormat", ""):
frame.is_j1939 = True

db.update_ecu_list()
db.del_ecu("Vector__XXX")
db.del_frame_attributes(["GenMsgCycleTime"])
db.del_signal_attributes(["GenSigCycleTime"])
if "GenMsgCycleTime" in db.frame_defines:
del (db.frame_defines["GenMsgCycleTime"])
if "GenSigCycleTime" in db.signal_defines:
del (db.signal_defines["GenSigCycleTime"])

free_signals_dummy_frame = db.frame_by_name("VECTOR__INDEPENDENT_SIG_MSG")
if free_signals_dummy_frame is not None and free_signals_dummy_frame.arbitration_id.id == 0x40000000:
db.signals = free_signals_dummy_frame.signals
Expand Down
11 changes: 4 additions & 7 deletions src/canmatrix/formats/kcd.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,11 +179,9 @@ def dump(dbs, f, **_options):

if frame.arbitration_id.extended == 1:
message.set("format", "extended")
if "GenMsgCycleTime" in db.frame_defines:
cycle_time = frame.attribute("GenMsgCycleTime", db=db)
if cycle_time is not None and int(cycle_time) > 0:
message.set("triggered", "true")
message.set("interval", "%d" % int(cycle_time))
if frame.effective_cycle_time != 0:
message.set("triggered", "true")
message.set("interval", "%d" % int(frame.effective_cycle_time))

comment_elem = lxml.etree.Element('Notes')
if frame.comment is not None:
Expand Down Expand Up @@ -357,7 +355,6 @@ def load(f, **options):
counter = 0
for bus in buses:
db = canmatrix.CanMatrix()
db.add_frame_defines("GenMsgCycleTime", 'INT 0 65535')
for node in nodes:
db.ecus.append(canmatrix.Ecu(node.get('name')))
node_list[node.get('id')] = node.get('name')
Expand All @@ -370,7 +367,7 @@ def load(f, **options):
new_frame = canmatrix.Frame(message.get('name'))

if 'triggered' in message.attrib:
new_frame.add_attribute("GenMsgCycleTime", message.get('interval'))
new_frame.cycle_time = int(message.get('interval'))

if 'length' in message.attrib:
dlc = int(message.get('length'))
Expand Down
17 changes: 5 additions & 12 deletions src/canmatrix/formats/sym.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,10 +258,8 @@ def send_receive(for_frame):
mux_out += id_type
first = 1
mux_out += "DLC=%d\n" % frame.size
if "GenMsgCycleTime" in db.frame_defines:
cycle_time = frame.attribute("GenMsgCycleTime", db=db)
if cycle_time is not None:
mux_out += "CycleTime=" + str(cycle_time) + "\n"
if frame.cycle_time != 0:
mux_out += "CycleTime=" + str(frame.effective_cycle_time) + "\n"

mux_name = frame.mux_names.get(i, mux_signal.name + "%d" % i)

Expand Down Expand Up @@ -299,10 +297,8 @@ def send_receive(for_frame):
output += name
output += id_type
output += "DLC=%d\n" % frame.size
if "GenMsgCycleTime" in db.frame_defines:
cycle_time = frame.attribute("GenMsgCycleTime", db=db)
if cycle_time is not None:
output += "CycleTime=" + str(cycle_time) + "\n"
if frame.cycle_time != 0:
output += "CycleTime=" + str(frame.effective_cycle_time) + "\n"
for signal in frame.signals:
output += create_signal(db, signal)
output += "\n"
Expand Down Expand Up @@ -330,7 +326,6 @@ class Mode(object):
frame = None

db = canmatrix.CanMatrix()
db.add_frame_defines("GenMsgCycleTime", 'INT 0 65535')
db.add_frame_defines("Receivable", 'BOOL False True')
db.add_frame_defines("Sendable", 'BOOL False True')
db.add_signal_defines("GenSigStartValue", 'FLOAT -3.4E+038 3.4E+038')
Expand Down Expand Up @@ -605,9 +600,7 @@ class Mode(object):
frame.size = int(line.split('=')[1])

elif line.startswith('CycleTime'):
frame.add_attribute(
"GenMsgCycleTime",
line.split('=')[1].strip())
frame.cycle_time = int(line.split('=')[1].strip())
# else:
# print line
# else:
Expand Down
3 changes: 1 addition & 2 deletions src/canmatrix/formats/xls.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,6 @@ def load(file, **options):
# Defines not imported...
# db.add_ecu_defines("NWM-Stationsadresse", 'HEX 0 63')
# db.add_ecu_defines("NWM-Knoten", 'ENUM "nein","ja"')
db.add_frame_defines("GenMsgCycleTime", 'INT 0 65535')
db.add_frame_defines("GenMsgDelayTime", 'INT 0 65535')
db.add_frame_defines("GenMsgCycleTimeActive", 'INT 0 65535')
db.add_frame_defines("GenMsgNrOfRepetitions", 'INT 0 65535')
Expand Down Expand Up @@ -452,7 +451,7 @@ def load(file, **options):
cycle_time = int(cycle_time)
except:
cycle_time = 0
new_frame.add_attribute("GenMsgCycleTime", str(int(cycle_time)))
new_frame.cycle_time = cycle_time

for additional_index in additional_inputs:
if "frame" in additional_inputs[additional_index]:
Expand Down
4 changes: 1 addition & 3 deletions src/canmatrix/formats/xls_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,7 @@ def get_frame_info(db, frame):
# frame-Name
ret_array.append(frame.name)

if "GenMsgCycleTime" in db.frame_defines:
# determine cycle-time
ret_array.append(frame.attribute("GenMsgCycleTime", db=db))
ret_array.append(frame.effective_cycle_time)

# determine send-type
if "GenMsgSendType" in db.frame_defines:
Expand Down
3 changes: 1 addition & 2 deletions src/canmatrix/formats/xlsx.py
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,6 @@ def load(filename, **options):
letter_index += ["%s%s" % (a, b) for a in all_letters for b in all_letters]

# Defines not imported...
db.add_frame_defines("GenMsgCycleTime", 'INT 0 65535')
db.add_frame_defines("GenMsgDelayTime", 'INT 0 65535')
db.add_frame_defines("GenMsgCycleTimeActive", 'INT 0 65535')
db.add_frame_defines("GenMsgNrOfRepetitions", 'INT 0 65535')
Expand Down Expand Up @@ -465,7 +464,7 @@ def load(filename, **options):
if launch_type not in launch_types:
launch_types.append(launch_type)

new_frame.add_attribute("GenMsgCycleTime", cycle_time)
new_frame.cycle_time = cycle_time

# new signal detected
if 'Signal Name' in row and row['Signal Name'] != signal_name:
Expand Down
24 changes: 24 additions & 0 deletions src/canmatrix/tests/test_canmatrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -985,3 +985,27 @@ def test_canmatrix_del_frame_by_instance(empty_matrix):
empty_matrix.del_frame(f1)
assert empty_matrix.frames == [f2]

def test_effective_cycle_time():
frame = canmatrix.Frame()
sig1 = canmatrix.Signal(name = "s1", cycle_time=1)
sig2 = canmatrix.Signal(name = "s2", cycle_time=0)
frame.add_signal(sig1)
frame.add_signal(sig2)
assert frame.effective_cycle_time == 1

sig2.cycle_time = 2
assert frame.effective_cycle_time == 1

sig1.cycle_time = 4
assert frame.effective_cycle_time == 2

sig1.cycle_time = 3
assert frame.effective_cycle_time == 1

frame.cycle_time = 1
assert frame.effective_cycle_time == 1

frame.cycle_time = 0
sig1.cycle_time = 0
sig2.cycle_time = 0
assert frame.effective_cycle_time == 0
2 changes: 1 addition & 1 deletion src/canmatrix/tests/test_cli_convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def create_dbc_with_special_char():

db = canmatrix.CanMatrix()
db.add_frame(myFrame)
db.add_frame_defines("GenMsgCycleTime", 'INT 0 65535')
db.add_frame_defines("SomeUnneededDefine", 'INT 0 65535')
canmatrix.formats.dumpp({"": db}, outFile, dbcExportEncoding='iso-8859-1',
dbcExportCommentEncoding='iso-8859-1')
return outFile
Expand Down
Loading