From 617c5d7ac9cac615da45088103f808f97cd527e6 Mon Sep 17 00:00:00 2001 From: alejopm03 Date: Fri, 28 Oct 2022 20:22:11 -0300 Subject: [PATCH 1/8] Add can load computation --- can.py | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 92 insertions(+), 9 deletions(-) diff --git a/can.py b/can.py index 75eedf0..0a5b815 100755 --- a/can.py +++ b/can.py @@ -40,7 +40,7 @@ def validate_bit(bit: int) -> bool: return True class topic: - def __init__(self, msg: str, id: int, description: str): + def __init__(self, msg: str, id: int,frequency: int, description: str): self.name = Can.convert_string(msg) if not isinstance(id, int): @@ -53,6 +53,10 @@ def __init__(self, msg: str, id: int, description: str): self.bytes = [None] * 8 + self.frequency = frequency + + self.frame_length = 47 + self.describe_byte( "signature", 0, "Senders signature", "uint8_t", "") @@ -61,7 +65,9 @@ def get(self) -> dict: "name": str(self.name), "description": self.description, "id": self.id, - "bytes": self.bytes + "bytes": self.bytes, + "frequency": self.frequency, + "frame_length": self.frame_length } def __str__(self) -> str: @@ -99,6 +105,12 @@ def validate_bit_name(self, byte: int, name: str): for bit in filter(None, self.bytes[byte].get('bits')): if bit == Can.convert_string(name): raise ValueError("bit field `name` must be unique!") + + def get_length(self): + return len(list(filter(lambda x: x is not None, self.bytes))) + + def get_frame_length(self): + return 44 + 8 * self.get_length() def describe_byte(self, name: str, @@ -120,6 +132,8 @@ def describe_byte(self, name = Can.convert_string(name) + self.frame_length += 8 + self.bytes[byte] = { "name": name, "description": description, @@ -172,6 +186,12 @@ def get(self) -> dict: "topics": self.topics } + def get_total_load(self, bitrate): + load = 0 + for topic in self.topics: + load += topic.get_load(bitrate) + return load + def __str__(self) -> str: return json.dumps(self.get(), indent=4) @@ -182,14 +202,16 @@ def add_topic(self, topic): self.topics.append(topic.get()) - def __init__(self, version: str): + def __init__(self, version: str, bitrate: int): self.version = version self.modules = [] + self.bitrate = bitrate def get(self) -> dict: return { "version": self.version, "modules": self.modules, + "bitrate": self.bitrate, } def __str__(self) -> str: @@ -228,26 +250,87 @@ def export_c_library(self, filename: str = "can_ids.h"): self.export_h("can_ids.h") self.export_h("can_parser_types.h") + def get_can_load_by_topic(self): + load = {} + for module in self.modules: + for topic in module["topics"]: + if not topic["id"] in load.keys(): + load[topic["id"]] = [] + load[topic["id"]].append(self.get_topic_load(topic)) + return load + + + def get_can_load(self): + load = 0 + for module in self.modules: + for topic in module["topics"]: + load += self.get_topic_load(topic) + return load + + def get_topic_load(self, topic: dict): + frame_length = topic["frame_length"] + frame_period = (1/self.bitrate) * frame_length + return frame_period * topic["frequency"] * 100 + # load = period for 1 msg * frequency * 100% + # Reference: + # https://support.vector.com/kb?id=kb_article_view&sysparm_article=KB0012332&sys_kb_id=99354e281b2614148e9a535c2e4bcb6d&spa=1 + + def plot_load(self): + import matplotlib.pyplot as plt + import numpy as np + from matplotlib.ticker import StrMethodFormatter + fig, ax = plt.subplots(figsize=(9, 6)) + plt.figtext(.5, .9, "Can Load ", fontsize=15, ha='center') + + load = [] + id = [] + for module in self.modules: + for topic in module["topics"]: + load.append(self.get_topic_load(topic)) + id.append(topic["id"]) + + ax.barh(id, load, align='center', color='royalblue') + + ax.set(title='Ids') + ax.invert_xaxis() + ax.grid() + plt.show() + + + if __name__ == '__main__': - t1 = Can.topic("motor", 9, "Motor controller parameters") + t1 = Can.topic("motor", 9, 100, "Motor controller parameters") t1.describe_byte("motor", 1, "Switches and states", "bitfield", "") t1.describe_bit("motor on", 1, 0) t1.describe_byte("D raw", 2, "Motor Duty Cycle", "uint8_t", "%") t1.describe_byte("I raw", 3, "Motor Soft Start", "uint8_t", "%") + t2 = Can.topic("motor2", 19, 10, "Motor controller parameters") + t2.describe_byte("motor", 1, "Switches and states", "bitfield", "") + t2.describe_bit("motor on", 1, 0) + t2.describe_byte("D raw", 2, "Motor Duty Cycle", "uint8_t", "%") + t2.describe_byte("I raw", 3, "Motor Soft Start", "uint8_t", "%") # print(t1) m1 = Can.module("mic17", 10, "Modulo de Interface de Controle") m1.add_topic(t1) + m1.add_topic(t2) + m2 = Can.module("mam21", 10, "Mamm") + # print(m1) - c1 = Can() + c1 = Can("0.0.0", 500e3) c1.add_module(m1) # print(c1) c1.export_json("sample.json") + print(c1.get_can_load()) + print(c1.get_topic_load(t1.get())) + c1.plot_load() + + # c2 = Can() + # c2.import_json("sample.json") + # print(c2) - c2 = Can() - c2.import_json("sample.json") - print(c2) + # c2.export_ids_h("sample.h") - c2.export_ids_h("sample.h") + From 0f6f3e76e14e1feb25300f3bc6bf1a2664bc18b7 Mon Sep 17 00:00:00 2001 From: alejopm03 Date: Fri, 28 Oct 2022 20:22:48 -0300 Subject: [PATCH 2/8] Add topics frequency in the generator --- can_ids_generator.py | 99 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 79 insertions(+), 20 deletions(-) diff --git a/can_ids_generator.py b/can_ids_generator.py index dba6065..9a6852d 100644 --- a/can_ids_generator.py +++ b/can_ids_generator.py @@ -11,7 +11,7 @@ raise FileNotFoundError( f"File {SEMVER_FILENAME} not found. It should contain the version in semver standard.") -can = Can(version=f"{version}") +can = Can(version=f"{version}", bitrate=500e3) ################################################################################ ### MODULE: GENERIC @@ -24,6 +24,7 @@ topic_state = can.topic( msg="state", id=0b1000, + frequency=0, description="Module state report" ) topic_state.describe_byte( @@ -44,6 +45,7 @@ topic_generic = can.topic( msg="generic", id=0, + frequency=0, description="Generic topic" ) @@ -62,7 +64,8 @@ topic_state = can.topic( msg="state", id=0b1000, - description="Module state report" + description="Module state report", + frequency = 78/40, ) topic_state.describe_byte( name="state", @@ -82,7 +85,8 @@ topic_motor = can.topic( msg="motor", id=0b1001, - description="Motor controller parameters" + description="Motor controller parameters", + frequency = 78 ) topic_motor.describe_byte( name="motor", @@ -124,7 +128,8 @@ topic_pumps = can.topic( msg="pumps", id=0b1010, - description="Pumps controller parameters" + frequency = 78, + description="Pumps controller parameters", ) topic_pumps.describe_byte( name="pumps", @@ -152,7 +157,8 @@ topic_mppts = can.topic( msg="mppts", id=0b1011, - description="Mppts controller parameters" + frequency = 0, + description="Mppts controller parameters", ) topic_mppts.describe_byte( name="mppts on", @@ -177,7 +183,8 @@ topic_mcs = can.topic( msg="mcs", id=0b1100, - description="MCS controller parameters" + frequency = 78, + description="MCS controller parameters", ) topic_mcs.describe_byte( name="boat on", @@ -195,7 +202,8 @@ topic_mde = can.topic( msg="mde", id=0b1101, - description="Steereing wheel controls" + frequency = 78/4, + description="Steereing wheel controls", ) topic_mde.describe_byte( name="position_l", @@ -231,6 +239,7 @@ topic_state = can.topic( msg="state", id=0b100000, + frequency=100/40, description="Module state report" ) topic_state.describe_byte( @@ -251,6 +260,7 @@ topic_measurements = can.topic( msg="steeringbat_measurements", id=0b100001, + frequency=100/4, description="Auxiliar Battery Voltage" ) topic_measurements.describe_byte( @@ -311,6 +321,7 @@ topic_state = can.topic( msg="state", id=0b100000, + frequency=120/40, description="Module state report" ) topic_state.describe_byte( @@ -341,6 +352,7 @@ ### TOPIC: STATE topic_state = can.topic( msg="state", + frequency=120/40, id=0b100000, description="Module state report" ) @@ -374,6 +386,7 @@ topic_state = can.topic( msg="state", id=0b10000, + frequency=10, description="Module state report" ) topic_state.describe_byte( @@ -427,6 +440,7 @@ topic_measurements = can.topic( msg="measurements", id=0b10001, + frequency=120, description="All measurements from the converter" ) topic_measurements.describe_byte( @@ -495,7 +509,8 @@ topic_state = can.topic( msg="state", id=0b10000, - description="Module state report" + frequency=10, + description="Module state report", ) topic_state.describe_byte( name="state", @@ -548,6 +563,7 @@ topic_measurements = can.topic( msg="measurements", id=0b10001, + frequency=120, description="All measurements from the converter" ) topic_measurements.describe_byte( @@ -616,6 +632,7 @@ topic_state = can.topic( msg="state", id=0b10000, + frequency=10, description="Module state report" ) topic_state.describe_byte( @@ -669,6 +686,7 @@ topic_measurements = can.topic( msg="measurements", id=0b10001, + frequency=120, description="All measurements from the converter" ) topic_measurements.describe_byte( @@ -737,7 +755,8 @@ topic_state = can.topic( msg="state", id=0b10000, - description="Module state report" + frequency=10, + description="Module state report", ) topic_state.describe_byte( name="state", @@ -790,6 +809,7 @@ topic_measurements = can.topic( msg="measurements", id=0b10001, + frequency=120, description="All measurements from the converter" ) topic_measurements.describe_byte( @@ -857,6 +877,7 @@ topic_state = can.topic( msg="state", id=0b10000, + frequency=10, description="Module state report" ) topic_state.describe_byte( @@ -910,6 +931,7 @@ topic_measurements = can.topic( msg="measurements", id=0b10001, + frequency=120, description="All measurements from the converter" ) topic_measurements.describe_byte( @@ -977,6 +999,7 @@ topic_state = can.topic( msg="state", id=0b10000, + frequency=10, description="Module state report" ) topic_state.describe_byte( @@ -1030,6 +1053,7 @@ topic_measurements = can.topic( msg="measurements", id=0b10001, + frequency=120, description="All measurements from the converter" ) topic_measurements.describe_byte( @@ -1097,6 +1121,7 @@ topic_state = can.topic( msg="state", id=0b10000, + frequency=100/40, description="Module state report" ) topic_state.describe_byte( @@ -1150,6 +1175,7 @@ topic_measurements = can.topic( msg="measurements", id=0b10001, + frequency=100/4, description="All measurements from the converter" ) topic_measurements.describe_byte( @@ -1217,6 +1243,7 @@ topic_state = can.topic( msg="state", id=0b10000, + frequency=100/40, description="Module state report" ) topic_state.describe_byte( @@ -1270,6 +1297,7 @@ topic_measurements = can.topic( msg="measurements", id=0b10001, + frequency=100/4, description="All measurements from the converter" ) topic_measurements.describe_byte( @@ -1337,7 +1365,8 @@ topic_state = can.topic( msg="state", id=0b10000, - description="Module state report" + frequency=100/10, + description="Module state report", ) topic_state.describe_byte( name="state", @@ -1357,7 +1386,8 @@ topic_contactor = can.topic( msg="contactor", id=0b10001, - description="Contactor task response" + frequency=100/100, + description="Contactor task response", ) topic_contactor.describe_byte( name="response", @@ -1383,6 +1413,7 @@ topic_state = can.topic( msg="state", id=0b10000, + frequency=50, description="Module state report" ) topic_state.describe_byte( @@ -1403,6 +1434,7 @@ topic_motor = can.topic( msg="motor", id=0b10001, + frequency=100, description="Motor controller parameters" ) topic_motor.describe_byte( @@ -1423,6 +1455,7 @@ topic_contactor = can.topic( msg="contactor", id=0b10010, + frequency=5, description="Contactor requests" ) topic_contactor.describe_byte( @@ -1451,6 +1484,7 @@ topic_state = can.topic( msg="state", id=0b1000000, + frequency=0, description="Module state report" ) topic_state.describe_byte( @@ -1472,7 +1506,8 @@ topic_pumps = can.topic( msg="pumps", id=0b1000001, - description="Pumps state" + frequency=0, + description="Pumps state", ) topic_pumps.describe_byte( name="pumps", @@ -1513,6 +1548,7 @@ topic_state = can.topic( msg="state", id=0b100000, + frequency=100/40, description="Module state report" ) topic_state.describe_byte( @@ -1533,6 +1569,7 @@ topic_adc = can.topic( msg="ADC", id=0b100001, + frequency=100/4, description="Voltage measurements" ) topic_adc.describe_byte( @@ -1594,6 +1631,7 @@ topic_state = can.topic( msg="state", id=0b100000, + frequency=100/40, description="Module state report" ) topic_state.describe_byte( @@ -1614,6 +1652,7 @@ topic_adc = can.topic( msg="ADC", id=0b100001, + frequency=100/4, description="Voltage measurements" ) topic_adc.describe_byte( @@ -1675,6 +1714,7 @@ topic_state = can.topic( msg="state", id=0b100000, + frequency=100/40, description="Module state report" ) topic_state.describe_byte( @@ -1695,6 +1735,7 @@ topic_adc = can.topic( msg="ADC", id=0b100001, + frequency=100/4, description="Voltage measurements" ) topic_adc.describe_byte( @@ -1756,6 +1797,7 @@ topic_state = can.topic( msg="state", id=0b100000, + frequency=100/40, description="Module state report" ) topic_state.describe_byte( @@ -1776,6 +1818,7 @@ topic_adc = can.topic( msg="ADC", id=0b100001, + frequency=100/4, description="Current measurements" ) topic_adc.describe_byte( @@ -1837,6 +1880,7 @@ topic_state = can.topic( msg="state", id=0b100000, + frequency=100/40, description="Module state report" ) topic_state.describe_byte( @@ -1857,6 +1901,7 @@ topic_adc = can.topic( msg="ADC", id=0b100001, + frequency=100/4, description="Current measurements" ) topic_adc.describe_byte( @@ -1918,7 +1963,8 @@ topic_state = can.topic( msg="state", id=0b00100000000, - description="Module state report" + frequency=40/40, + description="Module state report", ) topic_state.describe_byte( name="state", @@ -1939,6 +1985,7 @@ topic_start_stages = can.topic( msg="start_stages", id=0b001000000100, + frequency=40/15, description="Boat charging // Boat on" ) topic_start_stages.describe_byte( @@ -1971,6 +2018,7 @@ topic_bat = can.topic( msg="BAT", id=0b00100000010, + frequency=40/15, description="battery voltage values" ) topic_bat.describe_byte( @@ -2020,6 +2068,7 @@ topic_cap = can.topic( msg="CAP", id=0b00100000011, + frequency=40/15, description="capacitor bank voltage values" ) topic_cap.describe_byte( @@ -2084,7 +2133,8 @@ topic_state = can.topic( msg="state", id=0b00000100000, - description="Module state report" + description="Module state report", + frequency = 0 ) topic_state.describe_byte( name="state", @@ -2105,7 +2155,8 @@ topic_rpm = can.topic( msg="RPM", id=0b00000100001, - description="RPM motor values" + description="RPM motor values", + frequency = 0 ) topic_rpm.describe_byte( name="AVG_L", @@ -2138,7 +2189,8 @@ topic_state = can.topic( msg="state", id=0b1000, - description="Module state report" + description="Module state report", + frequency = 25/40 ) topic_state.describe_byte( name="state", @@ -2158,7 +2210,8 @@ topic_motor = can.topic( msg="motor", id=0b1001, - description="Motor controller parameters" + description="Motor controller parameters", + frequency = 25/4 ) topic_motor.describe_byte( name="motor", @@ -2195,7 +2248,8 @@ topic_pumps = can.topic( msg="pumps", id=0b1010, - description="Pumps controller parameters" + description="Pumps controller parameters", + frequency = 0 ) topic_pumps.describe_byte( name="pumps", @@ -2223,7 +2277,8 @@ topic_mppts = can.topic( msg="mppts", id=0b1011, - description="Mppts controller parameters" + description="Mppts controller parameters", + frequency = 0 ) topic_mppts.describe_byte( name="mppts on", @@ -2248,7 +2303,8 @@ topic_mcs = can.topic( msg="mcs", id=0b1100, - description="MCS controller parameters" + description="MCS controller parameters", + frequency = 25/10 ) topic_mcs.describe_byte( name="boat on", @@ -2269,3 +2325,6 @@ module_mswi19.add_topic(topic_mppts) module_mswi19.add_topic(topic_mcs) can.add_module(module_mswi19) +print(can.get_can_load()) +print(can.get_can_load_by_topic()) +#can.plot_load() \ No newline at end of file From 1b71201b11a8f3d12583144123482a8489efc019 Mon Sep 17 00:00:00 2001 From: alejopm03 Date: Fri, 28 Oct 2022 20:40:06 -0300 Subject: [PATCH 3/8] fix some tests and print load better --- can_ids_generator.py | 8 +++++--- test/test.json | 3 ++- test/test_can.py | 26 +++++++++++++++----------- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/can_ids_generator.py b/can_ids_generator.py index 9a6852d..3cef455 100644 --- a/can_ids_generator.py +++ b/can_ids_generator.py @@ -2325,6 +2325,8 @@ module_mswi19.add_topic(topic_mppts) module_mswi19.add_topic(topic_mcs) can.add_module(module_mswi19) -print(can.get_can_load()) -print(can.get_can_load_by_topic()) -#can.plot_load() \ No newline at end of file +loads = can.get_can_load_by_topic() +for id in loads: + print("Id: ", id, "load:", loads[id]) +print("Total load:", can.get_can_load()) +can.plot_load() \ No newline at end of file diff --git a/test/test.json b/test/test.json index 83dd572..5b5d79e 100644 --- a/test/test.json +++ b/test/test.json @@ -7,5 +7,6 @@ "signature": 10, "topics": [] } - ] + ], + "bitrate": 500000.0 } \ No newline at end of file diff --git a/test/test_can.py b/test/test_can.py index 79e0ffb..fceafd5 100644 --- a/test/test_can.py +++ b/test/test_can.py @@ -9,11 +9,13 @@ def setUp(self): self.can = Can def test_topic(self): - t = self.can.topic("motor", 9, "topic description text here") + t = self.can.topic("motor", 9, 100, "topic description text here") expected = { "name": "MOTOR", "description": "topic description text here", "id": 9, + "frequency": 100, + "frame_length": 55, "bytes": [ { "name": "SIGNATURE", @@ -31,27 +33,27 @@ def test_topic(self): ) def test_validate_byte(self): - t = self.can.topic("motor", 9, "topic description text here") + t = self.can.topic("motor", 9, 100, "topic description text here") # Trying to add using wrong type on the byte should raise TypeError: with self.assertRaises(TypeError): - t.describe_byte("some byte", "1", + t.describe_byte("some byte", "1", 100, "byte description text here", 'u8') # Trying to add byte with a value less than zero should raise ValueError: with self.assertRaises(ValueError): - t.describe_byte("some byte", -1, + t.describe_byte("some byte", -1, 100, "byte description text here", 'u8') # Trying to add byte with a value greater than 7 should raise ValueError: with self.assertRaises(ValueError): - t.describe_byte("some byte", 8, "byte description text here", 'u8') + t.describe_byte("some byte", 8, 100, "byte description text here", 'u8') # But using the correct type and range should run with no errors: - t.describe_byte("some byte", 1, "byte description text here", 'u8') + t.describe_byte("some byte", 1, 100, "byte description text here", 'u8') def test_validate_bit(self): - t = self.can.topic("motor", 9, "topic description text here") + t = self.can.topic("motor", 9, 100, "topic description text here") t.describe_byte("some byte", 1, "byte description text here", 'bitfield') @@ -192,7 +194,7 @@ def test_module(self): def test_add_topic(self): m = self.can.module("mic17", 10, "module description text here") - t = self.can.topic("motor", 9, "topic description text here") + t = self.can.topic("motor", 9, 100, "topic description text here") m.add_topic(t) @@ -205,6 +207,7 @@ def test_add_topic(self): "name": "MOTOR", "description": "topic description text here", "id": 9, + "frequency": 100, "bytes": [ { "name": "SIGNATURE", @@ -234,11 +237,12 @@ def setUp(self): def test_add_module(self): m = self.can.module("mic17", 10, "module description text here") - c = Can(version="0.0.0") + c = Can(version="0.0.0", bitrate=500e3) c.add_module(m) expected = { "version": "0.0.0", + "bitrate": 500e3, "modules": [ { "name": "MIC17", @@ -260,11 +264,11 @@ def test_add_module(self): def test_export_and_import_json(self): m = self.can.module("mic17", 10, "module description text here") - c1 = Can(version="0.0.0") + c1 = Can(version="0.0.0", bitrate=500e3) c1.add_module(m) c1.export_json("test/test.json") - c2 = Can(version="0.0.0") + c2 = Can(version="0.0.0", bitrate=500e3) c2.import_json("test/test.json") self.assertEqual( From 5047e18183874ebbe0518f79ee7a7aa54ee9de3c Mon Sep 17 00:00:00 2001 From: alejopm03 Date: Fri, 28 Oct 2022 23:21:31 -0300 Subject: [PATCH 4/8] add frequency and frame length to test cases --- test/test_can.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/test/test_can.py b/test/test_can.py index fceafd5..3790e0a 100644 --- a/test/test_can.py +++ b/test/test_can.py @@ -37,20 +37,20 @@ def test_validate_byte(self): # Trying to add using wrong type on the byte should raise TypeError: with self.assertRaises(TypeError): - t.describe_byte("some byte", "1", 100, + t.describe_byte("some byte", "1", "byte description text here", 'u8') # Trying to add byte with a value less than zero should raise ValueError: with self.assertRaises(ValueError): - t.describe_byte("some byte", -1, 100, + t.describe_byte("some byte", -1, "byte description text here", 'u8') # Trying to add byte with a value greater than 7 should raise ValueError: with self.assertRaises(ValueError): - t.describe_byte("some byte", 8, 100, "byte description text here", 'u8') + t.describe_byte("some byte", 8,"byte description text here", 'u8') # But using the correct type and range should run with no errors: - t.describe_byte("some byte", 1, 100, "byte description text here", 'u8') + t.describe_byte("some byte", 1,"byte description text here", 'u8') def test_validate_bit(self): t = self.can.topic("motor", 9, 100, "topic description text here") @@ -73,7 +73,7 @@ def test_validate_bit(self): t.describe_bit("some bit", 1, 0) def test_validate_byte_name(self): - t = self.can.topic("motor", 9, "topic description text here") + t = self.can.topic("motor", 9, 100, "topic description text here") # Trying to add using wrong type on the name should raise TypeError: with self.assertRaises(TypeError): @@ -86,7 +86,7 @@ def test_validate_byte_name(self): t.describe_byte("some byte", 1, "byte description text here", 'u8') def test_validate_bit_name(self): - t = self.can.topic("motor", 9, "topic description text here") + t = self.can.topic("motor", 9, 100, "topic description text here") t.describe_byte("some byte", 1, "byte description text here", 'bitfield') @@ -101,7 +101,7 @@ def test_validate_bit_name(self): t.describe_bit("some bit", 1, 1) def test_describe_byte(self): - t = self.can.topic("motor", 9, "topic description text here") + t = self.can.topic("motor", 9, 100, "topic description text here") t.describe_byte( "motor", 1, "byte description text here", "bitfield", "") @@ -109,6 +109,8 @@ def test_describe_byte(self): "name": "MOTOR", "description": "topic description text here", "id": 9, + "frequency": 100, + "frame_length": 63, "bytes": [ { "name": "SIGNATURE", @@ -133,7 +135,8 @@ def test_describe_byte(self): ) def test_describe_bit(self): - t = self.can.topic("motor", 9, "topic description text here") + self.maxDiff = None + t = self.can.topic("motor", 9, 100, "topic description text here") t.describe_byte( "motor", 1, "byte description text here", "bitfield", "") t.describe_bit("motor on", 1, 0) @@ -142,6 +145,8 @@ def test_describe_bit(self): "name": "MOTOR", "description": "topic description text here", "id": 9, + "frequency": 100, + "frame_length": 63, "bytes": [ { "name": "SIGNATURE", @@ -208,6 +213,7 @@ def test_add_topic(self): "description": "topic description text here", "id": 9, "frequency": 100, + "frame_length": 55, "bytes": [ { "name": "SIGNATURE", From 26a6ec98fccd78e235bbebfb897b1e9646410c08 Mon Sep 17 00:00:00 2001 From: alejopm03 Date: Sat, 29 Oct 2022 01:42:31 -0300 Subject: [PATCH 5/8] plot can bus load --- can.py | 61 +++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 52 insertions(+), 9 deletions(-) diff --git a/can.py b/can.py index 0a5b815..524bb6c 100755 --- a/can.py +++ b/can.py @@ -278,22 +278,65 @@ def get_topic_load(self, topic: dict): def plot_load(self): import matplotlib.pyplot as plt import numpy as np - from matplotlib.ticker import StrMethodFormatter - fig, ax = plt.subplots(figsize=(9, 6)) + fig, axes = plt.subplots(nrows= 2, ncols=2,figsize=(9, 6)) plt.figtext(.5, .9, "Can Load ", fontsize=15, ha='center') + ### Ids x Load + ids = {} + for module in self.modules: + for topic in module["topics"]: + if not topic["id"] in ids.keys(): + ids[topic["id"]] = 0 + ids[topic["id"]] += self.get_topic_load(topic) + + id = list(ids.keys()) + id.sort() + load = [] - id = [] + for i in id: + load.append(ids[i]) + + axes[0][0].bar(range(0, len(id)), load, align='center', color='royalblue') + axes[0][0].set_xticks(range(0, len(id))) + axes[0][0].set_xticklabels(list(id), fontsize = 9, rotation = 90) + axes[0][0].set_title("Load x Id") + axes[0][0].set_ylabel("Load [%]") + axes[0][0].set_xlabel("Ids") + axes[0][0].invert_xaxis() + axes[0][0].grid() + + id.append("free") + load.append(100 - sum(load)) + cmap = plt.cm.prism + colors = cmap(np.linspace(0.2, 0.8, len(id))) + axes[0][1].set_title("Load x Id") + axes[0][1].pie(load, labels=id, + textprops={'size': 'smaller'}, radius=1.5,colors=colors, labeldistance=1.1, startangle=-45) + + #### Modules X Load + load = [] + modules = {} for module in self.modules: for topic in module["topics"]: - load.append(self.get_topic_load(topic)) - id.append(topic["id"]) + if not module["name"] in modules.keys(): + modules[module["name"]] = 0 + modules[module["name"]] += self.get_topic_load(topic) + load = list(modules.values()) + modules = list(modules.keys()) + axes[1][0].set_title("Load x Module") + axes[1][0].bar(range(0, len(modules)), load) + axes[1][0].set_xticks(range(0,len(modules))) + axes[1][0].set_xticklabels(modules, fontsize = 9, rotation=90) + axes[1][0].set_ylabel("Load [%]") + + modules.append("free") + load.append(100.0 - sum(load)) + axes[1][1].set_title("Load x Module") + axes[1][1].pie(load, labels=modules, + textprops={'size': 'smaller'}, radius=1.5, labeldistance=1.1,startangle=-45) + - ax.barh(id, load, align='center', color='royalblue') - ax.set(title='Ids') - ax.invert_xaxis() - ax.grid() plt.show() From 95c5f5eafa0a0ba649d0dad31110c7c65e323ca7 Mon Sep 17 00:00:00 2001 From: alejopm03 Date: Sat, 29 Oct 2022 01:44:11 -0300 Subject: [PATCH 6/8] add plot dependecies to requeriments --- requirements.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/requirements.txt b/requirements.txt index 56b91bf..2152826 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,5 @@ Mako==1.1.6 MarkupSafe==2.0.1 semver==2.13.0 +matplotlib==3.6.1 +numpy==1.23.4 From c6c0f49d2a8e70244f28b1dfd1c20c365b6896fe Mon Sep 17 00:00:00 2001 From: alejopm03 Date: Sat, 29 Oct 2022 15:43:55 -0300 Subject: [PATCH 7/8] Export can ids information to csv --- can.py | 40 +++++++++++++++++++++++++++++++++++++++- can_ids_generator.py | 5 ----- main.py | 8 ++++++++ 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/can.py b/can.py index 524bb6c..7372832 100755 --- a/can.py +++ b/can.py @@ -1,5 +1,6 @@ #!/bin/python +from operator import mod from unicodedata import normalize import json import re @@ -250,6 +251,43 @@ def export_c_library(self, filename: str = "can_ids.h"): self.export_h("can_ids.h") self.export_h("can_parser_types.h") + def export_csv(self, filename: str): + import pandas as pd + + modules = [] + signature = [] + ids = [] + names = [] + frequency = [] + load = [] + frame_length = [] + description = [] + + for module in self.modules: + for topic in module["topics"]: + modules.append(module["name"]) + signature.append(module["signature"]) + ids.append(topic["id"]) + names.append(topic["name"]) + frequency.append(round(topic["frequency"],3)) + load.append(round(self.get_topic_load(topic),3)) + frame_length.append(topic["frame_length"]) + description.append(topic["description"]) + + df = pd.DataFrame({ + "modules":modules, + "signature": signature, + "name": names, + "ids": ids, + "frequency": frequency, + "load": load, + "frame_length": frame_length, + "description": description, + }) + + df.to_csv(filename) + + def get_can_load_by_topic(self): load = {} for module in self.modules: @@ -369,7 +407,7 @@ def plot_load(self): print(c1.get_can_load()) print(c1.get_topic_load(t1.get())) c1.plot_load() - + c1.export_csv("a") # c2 = Can() # c2.import_json("sample.json") # print(c2) diff --git a/can_ids_generator.py b/can_ids_generator.py index 3cef455..3eef7bc 100644 --- a/can_ids_generator.py +++ b/can_ids_generator.py @@ -2325,8 +2325,3 @@ module_mswi19.add_topic(topic_mppts) module_mswi19.add_topic(topic_mcs) can.add_module(module_mswi19) -loads = can.get_can_load_by_topic() -for id in loads: - print("Id: ", id, "load:", loads[id]) -print("Total load:", can.get_can_load()) -can.plot_load() \ No newline at end of file diff --git a/main.py b/main.py index 1027a59..dde5caf 100755 --- a/main.py +++ b/main.py @@ -6,3 +6,11 @@ can.export_json() can.export_c_library() + can.export_csv("can_ids.csv") + loads = can.get_can_load_by_topic() + ids = list(loads.keys()) + ids.sort() + for id in ids: + print("Id: ", id, "load:", loads[id]) + print("Total load:", round(can.get_can_load(),3), "%") + can.plot_load() \ No newline at end of file From fd0613d3131d3f55099adcf1b3196e20fe52799b Mon Sep 17 00:00:00 2001 From: alejopm03 Date: Sat, 29 Oct 2022 16:52:02 -0300 Subject: [PATCH 8/8] fix requeriments --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 2152826..adbac88 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ Mako==1.1.6 MarkupSafe==2.0.1 semver==2.13.0 -matplotlib==3.6.1 -numpy==1.23.4 +matplotlib +numpy