exponenta event banner

Передача CAN на основе событий в Simulink

В этом примере показано, как использовать передачу сообщений CAN на основе событий в Simulink with Vehicle Network Toolbox. Эта функция позволяет передавать сообщения CAN и CAN FD при обнаружении изменения данных с одного шага времени на следующий.

Опция конфигурации, доступная в блоках CAN и CAN FD Transmit, позволяет осуществлять передачу при изменении данных. Если этот параметр включен, сообщения с определенными идентификаторами CAN передаются только при изменении данных для этого идентификатора. Каждое сообщение независимо обрабатывается в каждом временном шаге на основе его идентификатора. При отключении работа блокировки и периодическая передача функционируют нормально. Кроме того, передача на основе событий может быть активизирована вместе с периодической передачей, чтобы обе они работали вместе одновременно.

Подготовка примерной модели

Включенная модель содержит два блока CAN Pack, сконфигурированных в один блок CAN Transmit. Данные одного сообщения являются константой, а другого - счетчиком, изменяющимся на каждом шаге времени.

Откройте пример модели.

open EventTransmit

Подготовка доступа к файлам базы данных CAN

Вы можете получить доступ к содержимому CAN DBC-файлов с помощью 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 в MATLAB для связи с моделью

Создайте канал 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)

Получение сообщений в MATLAB

Извлеките все сообщения из шины, сгенерированной моделью.

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);

Изучение полученных данных сообщений и сигналов

Количество полученных CAN ID показано ниже. Сообщение «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 только в том случае, если данные для этого CAN ID изменились по сравнению с ранее принятым сообщением.

Поскольку сигнал в сообщении «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 в MATLAB для связи с моделью

Создайте канал 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);

Получение сообщений в MATLAB

Извлеките все сообщения из шины, сгенерированной моделью.

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» изменяется на каждом шаге времени в сообщении «Counter_Msg,», оно принимается непрерывно из-за передачи, основанной на событии, и позже есть еще несколько передач, потому что периодическая передача разрешена.