Add CAN inputs for drivetrain display values with DBC and bench evidence
This commit is contained in:
+36
-6
@@ -11,6 +11,7 @@ import re
|
||||
|
||||
import cantools
|
||||
from export_dbc_docs import can2_dbc_text
|
||||
from send_drivetrain_can import build_payload
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
@@ -36,6 +37,7 @@ def verify_bit_timing():
|
||||
|
||||
assert value('ClockDivider') == 'FDCAN_CLOCK_DIV1'
|
||||
assert value('FrameFormat') == 'FDCAN_FRAME_CLASSIC'
|
||||
assert int(value('StdFiltersNbr')) == int(ioc[f'FDCAN{port}.StdFiltersNbr']) == 4
|
||||
prescaler, seg1, seg2, sjw = (int(value(field)) for field in
|
||||
('NominalPrescaler', 'NominalTimeSeg1',
|
||||
'NominalTimeSeg2', 'NominalSyncJumpWidth'))
|
||||
@@ -70,23 +72,24 @@ def main():
|
||||
header = (ROOT / 'firmware/Core/Inc/ami_protocol.h').read_text(encoding='utf-8')
|
||||
identifiers = {int(value, 16) for value in re.findall(
|
||||
r'^#define\s+AMI_CAN_ID_\w+\s+(0x[\dA-Fa-f]+)', header, re.MULTILINE)}
|
||||
expected = {0x300:(False,8), 0x6A0:(False,8), 0x6A1:(False,2),
|
||||
expected = {0x182:(False,8), 0x300:(False,8), 0x6A0:(False,8), 0x6A1:(False,2),
|
||||
0x6A2:(False,8), 0x6A4:(False,4), 0x6A6:(False,8),
|
||||
0x140:(False,8), 0x156:(False,8),
|
||||
0x186040F3:(True,8), 0x186140F3:(True,8)}
|
||||
actual = {m.frame_id:(m.is_extended_frame,m.length) for m in db.messages}
|
||||
assert actual == expected, actual
|
||||
assert set(actual) == identifiers, (actual, identifiers)
|
||||
assert len(db.messages) == 10
|
||||
assert sum(len(m.signals) for m in db.messages) == 33
|
||||
assert len(db.messages) == 11
|
||||
assert sum(len(m.signals) for m in db.messages) == 40
|
||||
for m in db.messages:
|
||||
if m.frame_id == 0x300:
|
||||
assert m.senders == ['AMI'] and m.receivers == {'VCU'}
|
||||
else:
|
||||
assert m.receivers == {'AMI'}
|
||||
assert m.senders == (['SDC_ACQ_DAC'] if 0x6A0 <= m.frame_id <= 0x6A6 else ['BMS'])
|
||||
assert m.senders == (['VCU'] if m.frame_id == 0x182 else
|
||||
['SDC_ACQ_DAC'] if 0x6A0 <= m.frame_id <= 0x6A6 else ['BMS'])
|
||||
assert db.dbc.attributes['Baudrate'].value == 500000
|
||||
for ident, cycle in [(0x6A0,100), (0x6A1,500), (0x6A2,20)]:
|
||||
for ident, cycle in [(0x182,100), (0x6A0,100), (0x6A1,500), (0x6A2,20)]:
|
||||
assert db.get_message_by_frame_id(ident).cycle_time == cycle
|
||||
for ident in [0x300,0x6A4,0x6A6,0x140,0x156,0x186040F3,0x186140F3]:
|
||||
assert db.get_message_by_frame_id(ident).cycle_time in (None,0)
|
||||
@@ -96,6 +99,32 @@ def main():
|
||||
checks.append({'id':hex(ident),'data':data})
|
||||
return db.decode_message(ident, bytes.fromhex(data), decode_choices=False)
|
||||
|
||||
display = db.get_message_by_frame_id(0x182)
|
||||
for raw, torque, motor, mcu, flags in [
|
||||
('F4 01 C2 01 90 01 07 01',500,45,40,7),
|
||||
('0C FE 9B FF 33 FF 07 01',-500,-10.1,-20.5,7),
|
||||
('18 FC 00 80 FF 7F 05 01',-1000,-3276.8,3276.7,5),
|
||||
('E8 03 00 00 00 00 00 01',1000,0,0,0)]:
|
||||
values = decode(0x182,raw)
|
||||
assert values['Torque_Permille'] == torque
|
||||
near(values['Motor_Temperature'],motor)
|
||||
near(values['MCU_Temperature'],mcu)
|
||||
for bit, name in enumerate(('Torque_Valid','Motor_Temperature_Valid','MCU_Temperature_Valid')):
|
||||
assert values[name] == ((flags >> bit) & 1)
|
||||
assert values['Protocol_Version'] == 1
|
||||
assert display.encode(values) == bytes.fromhex(raw)
|
||||
assert build_payload(torque,str(motor),str(mcu),flags) == bytes.fromhex(raw)
|
||||
assert all(display.get_signal_by_name(name).is_signed for name in
|
||||
('Torque_Permille','Motor_Temperature','MCU_Temperature'))
|
||||
for arguments in ((1001,'45','40',7), (0,'3276.8','40',7),
|
||||
(0,'45.01','40',7), (0,'45','40',8), (0,'nan','40',7)):
|
||||
try:
|
||||
build_payload(*arguments)
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
raise AssertionError(f'Invalid sender arguments accepted: {arguments}')
|
||||
|
||||
# Canonical request at 1000 ms, first sequence, task 2; all six task enums.
|
||||
task = decode(0x300,'01 02 00 01 E8 03 00 00')
|
||||
assert task == {'Protocol_Version':1,'Task_ID':2,'Request_Sequence':0,
|
||||
@@ -189,11 +218,12 @@ def main():
|
||||
for decode_choices in (False, True):
|
||||
assert db.decode_message(ident, payload, decode_choices=decode_choices) == \
|
||||
db2.decode_message(ident, payload, decode_choices=decode_choices)
|
||||
print(json.dumps({'result':'passed','messages':len(db.messages),'signals':33,
|
||||
print(json.dumps({'result':'passed','messages':len(db.messages),'signals':40,
|
||||
'known_payload_checks':len(checks),'all_task_ids_and_counter_edges':True,
|
||||
'ports_bitrate':bitrates,'both_dbc_layouts_and_payloads_match':True,
|
||||
'firmware_and_ioc_bit_timing_match':True,
|
||||
'firmware_ids_match':True,'sdc_source_layout_match':source_check,
|
||||
'display_sender_known_bytes_and_argument_rejection':True,
|
||||
'cantools_version':cantools.__version__},indent=2))
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user