В этом примере показано, как использовать основанную на событии передачу сообщения CAN в Simulink с Vehicle Network Toolbox. Эта функция допускает CAN и передачу сообщения CAN FD, когда изменение в данных от одного временного шага до следующего обнаруживается.
Параметр конфигурации, доступный на CAN и блоках Передачи CAN FD, включает передачу на изменении данных. Когда включено, сообщения конкретных идентификаторов CAN передают только, когда данные изменяются для того ID. Каждое сообщение независимо обрабатывается в каждом временном шаге на основе его ID. Когда отключено, блочная операция и периодическая операция передачи обычно функционируют. Кроме того, основанная на событии передача может быть позволена наряду с периодической передачей иметь, оба работают совместно одновременно.
Включенная модель в качестве примера содержит два блока Пакета CAN, сконфигурированные в один блок CAN Transmit. Данные одного сообщения являются константой, в то время как другой счетчик, который изменяется на каждом временном шаге.
Откройте модель в качестве примера.
open EventTransmit
Можно получить доступ к содержимому файлов DBC CAN с canDatabase
функция. Через эту функцию детали о сетевых узлах, сообщениях и сигналах доступны. Этот файл DBC используется в модели и используется, чтобы декодировать информацию, отправленную от модели.
db = canDatabase("CANBusEvent.dbc")
db = Database with properties: Name: 'CANBusEvent' Path: 'C:\Users\jpyle\Documents\MATLAB\ExampleManager\jpyle.21bExampleBlitz\vnt-ex59902587\CANBusEvent.dbc' Nodes: {'ECU'} NodeInfo: [1×1 struct] Messages: {2×1 cell} MessageInfo: [2×1 struct] Attributes: {} AttributeInfo: [0×0 struct] UserData: []
Тестовый узел задан в файле DBC.
node = nodeInfo(db,"ECU")
node = struct with fields:
Name: 'ECU'
Comment: ''
Attributes: {}
AttributeInfo: [0×0 struct]
Узел передает два сообщения CAN.
messageInfo(db,"Constant_Msg")
ans = struct with fields:
Name: 'Constant_Msg'
ProtocolMode: 'CAN'
Comment: ''
ID: 10
Extended: 0
J1939: []
Length: 4
DLC: 4
BRS: 0
Signals: {'Constant'}
SignalInfo: [1×1 struct]
TxNodes: {'ECU'}
Attributes: {}
AttributeInfo: [0×0 struct]
messageInfo(db,"Counter_Msg")
ans = struct with fields:
Name: 'Counter_Msg'
ProtocolMode: 'CAN'
Comment: ''
ID: 20
Extended: 0
J1939: []
Length: 4
DLC: 4
BRS: 0
Signals: {'Counter'}
SignalInfo: [1×1 struct]
TxNodes: {'ECU'}
Attributes: {}
AttributeInfo: [0×0 struct]
Включите основанную на событии передачу в блоке CAN Transmit программно. Кроме того, отключите периодическую передачу.
db = canDatabase("CANBusEvent.dbc")
db = Database with properties: Name: 'CANBusEvent' Path: 'C:\Users\jpyle\Documents\MATLAB\ExampleManager\jpyle.21bExampleBlitz\vnt-ex59902587\CANBusEvent.dbc' Nodes: {'ECU'} NodeInfo: [1×1 struct] Messages: {2×1 cell} MessageInfo: [2×1 struct] Attributes: {} AttributeInfo: [0×0 struct] UserData: []
set_param('EventTransmit/CAN Transmit', 'EnableEventTransmit', 'on'); set_param('EventTransmit/CAN Transmit', 'EnablePeriodicTransmit', 'off');
Обратите внимание на то, что блок отображает изменения после применения настроек.
Создайте канал CAN с помощью коммуникации виртуального устройства, чтобы взаимодействовать через интерфейс с моделью Simulink. Кроме того, присоедините базу данных CAN к нему, чтобы автоматически декодировать входящие сообщения.
canCh = canChannel("Mathworks","Virtual 1",2)
canCh = Channel with properties: Device Information DeviceVendor: 'MathWorks' Device: 'Virtual 1' DeviceChannelIndex: 2 DeviceSerialNumber: 0 ProtocolMode: 'CAN' Status Information Running: 0 MessagesAvailable: 0 MessagesReceived: 0 MessagesTransmitted: 0 InitializationAccess: 1 InitialTimestamp: [0×0 datetime] FilterHistory: 'Standard ID Filter: Allow All | Extended ID Filter: Allow All' Channel Information BusStatus: 'N/A' SilentMode: 0 TransceiverName: 'N/A' TransceiverState: 'N/A' ReceiveErrorCount: 0 TransmitErrorCount: 0 BusSpeed: 500000 SJW: [] TSEG1: [] TSEG2: [] NumOfSamples: [] Other Information Database: [] UserData: []
canCh.Database = db;
Запустите канал CAN, чтобы пойти онлайн.
start(canCh);
Присвойте время выполнения симуляции и запустите модель.
t = "10"; set_param("EventTransmit","StopTime",t) set_param("EventTransmit","SimulationCommand","start");
Ожидайте, пока симуляция не запускается.
while strcmp(get_param("EventTransmit","SimulationStatus"),"stopped") end
Ожидайте, пока симуляция не заканчивается.
pause(2)
Получите все сообщения от шины, сгенерированной моделью.
msg = receive(canCh,inf,"OutputFormat","timetable")
msg=12×8 timetable
Time ID Extended Name Data Length Signals Error Remote
__________ __ ________ ________________ ____________ ______ ____________ _____ ______
5.204 sec 10 false {'Constant_Msg'} {[ 5 0 0 0]} 4 {1×1 struct} false false
5.204 sec 20 false {'Counter_Msg' } {[ 0 0 0 0]} 4 {1×1 struct} false false
5.206 sec 20 false {'Counter_Msg' } {[ 1 0 0 0]} 4 {1×1 struct} false false
5.206 sec 20 false {'Counter_Msg' } {[ 2 0 0 0]} 4 {1×1 struct} false false
5.206 sec 20 false {'Counter_Msg' } {[ 3 0 0 0]} 4 {1×1 struct} false false
5.206 sec 20 false {'Counter_Msg' } {[ 4 0 0 0]} 4 {1×1 struct} false false
5.206 sec 20 false {'Counter_Msg' } {[ 5 0 0 0]} 4 {1×1 struct} false false
5.206 sec 20 false {'Counter_Msg' } {[ 6 0 0 0]} 4 {1×1 struct} false false
5.206 sec 20 false {'Counter_Msg' } {[ 7 0 0 0]} 4 {1×1 struct} false false
5.206 sec 20 false {'Counter_Msg' } {[ 8 0 0 0]} 4 {1×1 struct} false false
5.206 sec 20 false {'Counter_Msg' } {[ 9 0 0 0]} 4 {1×1 struct} false false
5.2061 sec 20 false {'Counter_Msg' } {[10 0 0 0]} 4 {1×1 struct} false false
Остановите канал CAN в MATLAB.
stop(canCh);
Число раз ID CAN был получен, построено ниже. Сообщение "Constant_Msg" (CAN ID 10) получено только однажды, потому что его данные не изменяются после его начальной установки. Сообщение "Counter_Msg" (CAN ID 20) получено от каждого временного шага, потому что данные, изменяемые постоянно в нем как модель, запустились.
% Define X and Y axis. x = 1:length(msg.ID); y = msg.ID; % Plot the graph for both the CAN IDs received. stem(x,y,'filled') hold on; yMax = max(msg.ID)+5; ylim([0 yMax]) % Label the graph. xlabel("Number of CAN messages"); ylabel("CAN ID"); legend("CAN ID","Location","northeast"); legend("boxoff"); hold off;
Затем постройте сигналы, полученные в каждом сообщении по той же запущенной симуляции.
% Create a structure with signal details. signalTimeTable = canSignalTimetable(msg); % Plot the signal values of "Constant_Msg". x1 = 1:height(signalTimeTable.Constant_Msg); y1 = signalTimeTable.Constant_Msg.Constant; plot(x1, y1,"Marker","o"); hold on % Plot the signal values of "Counter_Msg". x2 = 1:height(signalTimeTable.Counter_Msg); y2 = signalTimeTable.Counter_Msg.Counter; plot(x2, y2,"Marker","o"); % Determine the maximum value for y-axis for scaling of graph. y1Max = max(signalTimeTable.Constant_Msg.Constant); y2Max = max(signalTimeTable.Counter_Msg.Counter); yMax = max(y1Max,y2Max)+5; ylim([0 yMax]); % Label the graph. xlabel("Number of Times Signals Received"); ylabel("CAN Signal Value"); legend("Constant","Counter","Location","northeastoutside"); legend("boxoff"); hold off
"Постоянный" сигнал (в сообщении "Constant_Msg") построен только однажды, в то время как "Счетчик" сигнала (в сообщении "Counter_Msg") построен для каждого временного шага. Это происходит из-за основанной на событии передачи, включаемой в блоке CAN Transmit, который передает сообщение CAN, только если данные изменились для того ID CAN по сравнению с ранее полученным сообщением.
Когда сигнал в сообщении "Counter_Msg" является счетчиком, который постепенно увеличивается 1 на каждом временном шаге, линейная кривая видна для него.
Каждый точки данных представляют передачу основанной на событии включенной передачей, следовательно сигнал "Счетчик", принят на каждом временном шаге, но "Постоянный" сигнал получен только однажды.
Включите передачу события в блоке CAN Transmit программно. Кроме того, включите периодическую передачу и установите период сообщения.
set_param('EventTransmit/CAN Transmit', 'EnableEventTransmit', 'on'); set_param('EventTransmit/CAN Transmit', 'EnablePeriodicTransmit', 'on'); set_param('EventTransmit/CAN Transmit', 'MessagePeriod', '0.1');
Обратите внимание на то, что блок отображает изменения после применения настроек.
Создайте канал CAN с помощью коммуникации виртуального устройства, чтобы взаимодействовать через интерфейс с моделью Simulink. Кроме того, присоедините базу данных CAN к нему, чтобы автоматически декодировать входящие сообщения.
canCh = canChannel("Mathworks","Virtual 1",2)
canCh = Channel with properties: Device Information DeviceVendor: 'MathWorks' Device: 'Virtual 1' DeviceChannelIndex: 2 DeviceSerialNumber: 0 ProtocolMode: 'CAN' Status Information Running: 0 MessagesAvailable: 0 MessagesReceived: 0 MessagesTransmitted: 0 InitializationAccess: 1 InitialTimestamp: [0×0 datetime] FilterHistory: 'Standard ID Filter: Allow All | Extended ID Filter: Allow All' Channel Information BusStatus: 'N/A' SilentMode: 0 TransceiverName: 'N/A' TransceiverState: 'N/A' ReceiveErrorCount: 0 TransmitErrorCount: 0 BusSpeed: 500000 SJW: [] TSEG1: [] TSEG2: [] NumOfSamples: [] Other Information Database: [] UserData: []
canCh.Database = db;
Запустите канал CAN, чтобы пойти онлайн.
start(canCh);
Присвойте время выполнения симуляции и запустите модель.
t = "20"; set_param("EventTransmit","StopTime",t) set_param("EventTransmit","SimulationCommand","start");
Ожидайте, пока симуляция не запускается.
while strcmp(get_param("EventTransmit","SimulationStatus"),"stopped") end
Ожидайте, пока симуляция не заканчивается.
pause(5);
Получите все сообщения от шины, сгенерированной моделью.
msg = receive(canCh,Inf,"OutputFormat","timetable")
msg=22×8 timetable
Time ID Extended Name Data Length Signals Error Remote
__________ __ ________ ________________ ____________ ______ ____________ _____ ______
4.598 sec 10 false {'Constant_Msg'} {[ 5 0 0 0]} 4 {1×1 struct} false false
4.598 sec 20 false {'Counter_Msg' } {[ 0 0 0 0]} 4 {1×1 struct} false false
4.5987 sec 20 false {'Counter_Msg' } {[ 1 0 0 0]} 4 {1×1 struct} false false
4.5987 sec 20 false {'Counter_Msg' } {[ 2 0 0 0]} 4 {1×1 struct} false false
4.5987 sec 20 false {'Counter_Msg' } {[ 3 0 0 0]} 4 {1×1 struct} false false
4.5987 sec 20 false {'Counter_Msg' } {[ 4 0 0 0]} 4 {1×1 struct} false false
4.5987 sec 20 false {'Counter_Msg' } {[ 5 0 0 0]} 4 {1×1 struct} false false
4.5987 sec 20 false {'Counter_Msg' } {[ 6 0 0 0]} 4 {1×1 struct} false false
4.5987 sec 20 false {'Counter_Msg' } {[ 7 0 0 0]} 4 {1×1 struct} false false
4.5987 sec 20 false {'Counter_Msg' } {[ 8 0 0 0]} 4 {1×1 struct} false false
4.5988 sec 20 false {'Counter_Msg' } {[ 9 0 0 0]} 4 {1×1 struct} false false
4.5988 sec 20 false {'Counter_Msg' } {[10 0 0 0]} 4 {1×1 struct} false false
4.5988 sec 20 false {'Counter_Msg' } {[11 0 0 0]} 4 {1×1 struct} false false
4.5988 sec 20 false {'Counter_Msg' } {[12 0 0 0]} 4 {1×1 struct} false false
4.5988 sec 20 false {'Counter_Msg' } {[13 0 0 0]} 4 {1×1 struct} false false
4.5988 sec 20 false {'Counter_Msg' } {[14 0 0 0]} 4 {1×1 struct} false false
⋮
Остановите канал CAN в MATLAB.
stop(canCh);
Отобразите на графике данные, полученные в каждом сообщении за тот же период.
% Create a structure with signal details. signalTimeTable = canSignalTimetable(msg); % Plot the signal values of "Constant_Msg". x3 = 1:height(signalTimeTable.Constant_Msg); y3 = signalTimeTable.Constant_Msg.Constant; plot(x3, y3,"Marker","o"); hold on % Plot the signal values of "Counter_Msg". x4 = 1:height(signalTimeTable.Counter_Msg); y4 = signalTimeTable.Counter_Msg.Counter; plot(x4, y4,"Marker","o"); % Determine the maximum value for y-axis for scaling of graph. y3Max = max(signalTimeTable.Constant_Msg.Constant); y4Max = max(signalTimeTable.Counter_Msg.Counter); yMax = max(y3Max,y4Max)+5; ylim([0 yMax]); % Label the graph. xlabel("Number of Times Signals Received"); ylabel("CAN Signal Value"); legend("Constant","Counter","Location","northeastoutside"); legend("boxoff"); hold off
График показывает, что сигнал, "Постоянный" в сообщении "Constant_Msg", получен только несколько раз; однажды в запуске из-за основанной на событии передачи, и позже из-за периодической природы передачи. Это вызвано тем, что входное значение к сигналу сохранено постоянным.
В то время как значение для "Счетчика" сигнала изменяет на каждом временном шаге в сообщении "Counter_Msg", это получается постоянно из-за основанной на событии передачи, и позже существует еще несколько передач, потому что периодическая передача включена.