-
Notifications
You must be signed in to change notification settings - Fork 34
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
canpy: First prototype of can communication handler implemented
- Loading branch information
Stefan Hölzl
committed
Jun 11, 2016
1 parent
e39358a
commit aae7b66
Showing
10 changed files
with
206 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
__author__ = "Stefan Hölzl" | ||
|
||
|
||
class CANCommunicationHandler(object): | ||
"""Takes care of sending and receiving CAN-Messages. | ||
class CANInterfaceProtocol(object): | ||
def __init__(self): | ||
def register_receiving_message(self, can_id): | ||
def register_receive_callback(self, callback): | ||
def initialize(self, speed): | ||
def send_message(self, can_id, data): | ||
""" | ||
def __init__(self, can_network, thread_register_callback): | ||
self._can_network = can_network | ||
self._thread_register_callback = thread_register_callback | ||
self._registered_messages = {} | ||
|
||
def initialize(self): | ||
msgs_by_cycle_time = {} | ||
for can_id in self._registered_messages: | ||
msg = self._can_network.get_message(can_id) | ||
if 'cyclic' in msg.attributes['GenMsgSendType'].value and msg.attributes['GenMsgCycleTime'].value > 0: | ||
cycle_time = msg.attributes['GenMsgCycleTime'].value | ||
if cycle_time not in msgs_by_cycle_time.keys(): | ||
msgs_by_cycle_time[cycle_time] = [] | ||
msgs_by_cycle_time[cycle_time].append(msg) | ||
for cycle_time, msgs in msgs_by_cycle_time.items(): | ||
callback = lambda m=msgs: self._send_messages(m) | ||
self._thread_register_callback(cycle_time, callback) | ||
|
||
def connect(self, node_names, can_interface): | ||
for node_name in node_names: | ||
node = self._can_network.nodes[node_name] | ||
for msg in node.messages.values(): | ||
self._registered_messages[msg.can_id] = can_interface | ||
for recv_msg in self._can_network.get_consumed_messages(node): | ||
can_interface.register_receiving_message(recv_msg.can_id) | ||
|
||
def _send_messages(self, msgs): | ||
for msg in msgs: | ||
can_interface = self._registered_messages[msg.can_id] | ||
if 'IfActive' not in msg.attributes['GenMsgSendType'].value: | ||
can_interface.send_message(msg.can_id, int(msg)) | ||
elif msg.is_active: | ||
can_interface.send_message(msg.can_id, int(msg)) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
__author__ = "Stefan Hölzl" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
VERSION "1.0" | ||
|
||
BU_: Node0 Node1 | ||
|
||
BS_: 500 | ||
|
||
BO_ 0 CANMessage0: 8 Node0 | ||
SG_ Signal0 : 0|32@1- (1,0) [0|0] "" Node1 | ||
SG_ Signal1 : 32|32@1+ (100,0) [0|100] "%" Node1 | ||
|
||
BO_ 1 CANMessage1: 8 Node0 | ||
SG_ Signal0 : 0|32@1- (1,0) [0|0] "" Node1 | ||
SG_ Signal1 : 32|32@1+ (100,0) [0|100] "%" Node1 | ||
|
||
BO_ 2 CANMessage2: 8 Node0 | ||
SG_ Signal0 : 0|32@1- (1,0) [0|0] "" Node1 | ||
SG_ Signal1 : 32|32@1+ (100,0) [0|100] "%" Node1 | ||
|
||
BO_ 3 CANMessage3: 8 Node0 | ||
SG_ Signal0 : 0|32@1- (1,0) [0|0] "" Node1 | ||
SG_ Signal1 : 32|32@1+ (100,0) [0|100] "%" Node1 | ||
|
||
BA_ "GenMsgSendType" BO_ 0 CANMessage0 0; | ||
BA_ "GenMsgCycleTime" BO_ 0 CANMessage0 10; | ||
|
||
BA_ "GenMsgSendType" BO_ 1 CANMessage1 4; | ||
BA_ "GenMsgCycleTime" BO_ 1 CANMessage1 100; | ||
|
||
BA_ "GenMsgSendType" BO_ 3 CANMessage3 4; | ||
BA_ "GenMsgCycleTime" BO_ 3 CANMessage3 100; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
__author__ = 'Stefan Hölzl' | ||
|
||
from canpy.can_communication_handler import CANCommunicationHandler | ||
from canpy.parser.dbc_parser import DBCParser | ||
|
||
|
||
class CANInterfaceStub(object): | ||
def __init__(self): | ||
self.registered_receiving_message_ids = [] | ||
self.sent_messages = [] | ||
|
||
def register_receiving_message(self, can_id): | ||
self.registered_receiving_message_ids.append(can_id) | ||
|
||
def initialize(self, speed): | ||
pass | ||
|
||
def send_message(self, can_id, data): | ||
self.sent_messages.append((can_id, data)) | ||
|
||
|
||
class TestCANCommunicationHandler(object): | ||
def test_connect_nodes_to_interface_sending_messages(self): | ||
ci = CANInterfaceStub() | ||
cn = DBCParser().parse_file('tests/test_communication_handler.dbc') | ||
cch = CANCommunicationHandler(cn, lambda c, t: None) | ||
cch.connect(['Node0'], ci) | ||
assert 0 in cch._registered_messages.keys() | ||
assert cch._registered_messages[0] == ci | ||
|
||
def test_connect_nodes_to_interface_receiving_messages(self): | ||
ci = CANInterfaceStub() | ||
cn = DBCParser().parse_file('tests/test_communication_handler.dbc') | ||
cch = CANCommunicationHandler(cn, lambda c, t: None) | ||
cch.connect(['Node1'], ci) | ||
assert 0 in ci.registered_receiving_message_ids | ||
|
||
def test_initialize_cyclic_messages(self): | ||
ci = CANInterfaceStub() | ||
cn = DBCParser().parse_file('tests/test_communication_handler.dbc') | ||
callback_cylce_times = [] | ||
|
||
def callback(c, t): | ||
nonlocal callback_cylce_times | ||
callback_cylce_times.append(c) | ||
|
||
cch = CANCommunicationHandler(cn, callback) | ||
cch.connect(['Node0'], ci) | ||
cch.initialize() | ||
assert 10 in callback_cylce_times | ||
assert 100 in callback_cylce_times | ||
|
||
def test_send_messages(self): | ||
ci = CANInterfaceStub() | ||
cn = DBCParser().parse_file('tests/test_communication_handler.dbc') | ||
callbacks = [] | ||
|
||
def callback(c, t): | ||
nonlocal callbacks | ||
callbacks.append(t) | ||
|
||
cch = CANCommunicationHandler(cn, callback) | ||
cch.connect(['Node0'], ci) | ||
cch.initialize() | ||
cn.get_message(1).is_active = False | ||
list(map(lambda cb: cb(), callbacks)) | ||
assert len(ci.sent_messages) == 2 | ||
|