Основанная на событии передача CAN в Simulink

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

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

Подготовьте модель в качестве примера

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

Откройте модель в качестве примера.

open EventTransmit

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

Можно получить доступ к содержимому файлов 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 в 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);

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

Число раз 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 в 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_Msg", это получается постоянно из-за основанной на событии передачи, и позже существует еще несколько передач, потому что периодическая передача включена.