Основанное на событии поведение передачи сообщения 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: '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 в 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
    __________    __    ________    ________________    ____________    ______    ____________    _____    ______

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