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