В этом примере показано, как использовать основанную на событии передачу сообщения 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: '\\central-bgl\home$\aragarwa\Documents\MATLAB\Examples\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: '\\central-bgl\home$\aragarwa\Documents\MATLAB\Examples\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
___________ __ ________ ________________ ___________ ______ ____________ _____ ______
0.26451 sec 10 false {'Constant_Msg'} {1×4 uint8} 4 {1×1 struct} false false
0.26452 sec 20 false {'Counter_Msg' } {1×4 uint8} 4 {1×1 struct} false false
0.26839 sec 20 false {'Counter_Msg' } {1×4 uint8} 4 {1×1 struct} false false
0.26841 sec 20 false {'Counter_Msg' } {1×4 uint8} 4 {1×1 struct} false false
0.26842 sec 20 false {'Counter_Msg' } {1×4 uint8} 4 {1×1 struct} false false
0.26843 sec 20 false {'Counter_Msg' } {1×4 uint8} 4 {1×1 struct} false false
0.26844 sec 20 false {'Counter_Msg' } {1×4 uint8} 4 {1×1 struct} false false
0.26845 sec 20 false {'Counter_Msg' } {1×4 uint8} 4 {1×1 struct} false false
0.26846 sec 20 false {'Counter_Msg' } {1×4 uint8} 4 {1×1 struct} false false
0.26847 sec 20 false {'Counter_Msg' } {1×4 uint8} 4 {1×1 struct} false false
0.26848 sec 20 false {'Counter_Msg' } {1×4 uint8} 4 {1×1 struct} false false
0.26849 sec 20 false {'Counter_Msg' } {1×4 uint8} 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=28×8 timetable
Time ID Extended Name Data Length Signals Error Remote
___________ __ ________ ________________ ___________ ______ ____________ _____ ______
0.29037 sec 10 false {'Constant_Msg'} {1×4 uint8} 4 {1×1 struct} false false
0.29037 sec 20 false {'Counter_Msg' } {1×4 uint8} 4 {1×1 struct} false false
0.29192 sec 20 false {'Counter_Msg' } {1×4 uint8} 4 {1×1 struct} false false
0.29194 sec 20 false {'Counter_Msg' } {1×4 uint8} 4 {1×1 struct} false false
0.29196 sec 20 false {'Counter_Msg' } {1×4 uint8} 4 {1×1 struct} false false
0.29197 sec 20 false {'Counter_Msg' } {1×4 uint8} 4 {1×1 struct} false false
0.29198 sec 20 false {'Counter_Msg' } {1×4 uint8} 4 {1×1 struct} false false
0.29199 sec 20 false {'Counter_Msg' } {1×4 uint8} 4 {1×1 struct} false false
0.292 sec 20 false {'Counter_Msg' } {1×4 uint8} 4 {1×1 struct} false false
0.29201 sec 20 false {'Counter_Msg' } {1×4 uint8} 4 {1×1 struct} false false
0.29202 sec 20 false {'Counter_Msg' } {1×4 uint8} 4 {1×1 struct} false false
0.29203 sec 20 false {'Counter_Msg' } {1×4 uint8} 4 {1×1 struct} false false
0.29204 sec 20 false {'Counter_Msg' } {1×4 uint8} 4 {1×1 struct} false false
0.29204 sec 20 false {'Counter_Msg' } {1×4 uint8} 4 {1×1 struct} false false
0.29205 sec 20 false {'Counter_Msg' } {1×4 uint8} 4 {1×1 struct} false false
0.29206 sec 20 false {'Counter_Msg' } {1×4 uint8} 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", это получается постоянно из-за основанной на событии передачи, и позже существует еще несколько передач, потому что периодическая передача включена.