Программно создайте модели Simulink для коммуникации CAN

В этом примере показано, как программно создать модель Simulink, чтобы ввести CAN или коммуникацию CAN FD с помощью файла DBC CAN. С add_block и set_param функциями Simulink, можно добавить и полностью сконфигурировать блоки Vehicle Network Toolbox, чтобы добавить сетевые коммуникации в основной алгоритм. Файл DBC содержит сообщения CAN и детали сигнала. Основное внимание должно программно сконфигурировать CAN и Пакет CAN FD и Распаковать параметры блоков. Это может значительно увеличить КПД типовой конструкции.

Модель алгоритма

Модель AlgorithmModel.slx в качестве примера содержит блок подсистемы под названием "Алгоритм". Этот блок представляет любой данный алгоритм приложения, разработанный в Simulink. Блок Gain со значением 2 в этой подсистеме в демонстрационных целях. Эта подсистема имеет вход сигнала CAN по имени "In1". Это входное значение масштабируется значением усиления. Масштабированное значение дано как выход этой подсистемы по имени "Out1". Для экспериментирования может быть изменено значение усиления, и блок Gain может быть заменен различным алгоритмом.

Доступ к файлу базы данных CAN

Можно получить доступ к содержимому файлов DBC CAN с canDatabase функция. Через эту функцию детали о сетевых узлах, сообщениях и сигналах доступны.

db = canDatabase("CANBus.dbc")
db = 
  Database with properties:

             Name: 'CANBus'
             Path: 'C:\Users\jpyle\Documents\MATLAB\Examples\vnt-ex60686316\CANBus.dbc'
            Nodes: {'ECU'}
         NodeInfo: [1×1 struct]
         Messages: {2×1 cell}
      MessageInfo: [2×1 struct]
       Attributes: {}
    AttributeInfo: [0×0 struct]
         UserData: []

Узел "ECU" задан в файле DBC CAN в качестве примера как показано ниже.

node = nodeInfo(db,"ECU")
node = struct with fields:
             Name: 'ECU'
          Comment: ''
       Attributes: {}
    AttributeInfo: [0×0 struct]

Узел получает сообщение CAN "AlgInput", содержащий сигнал "InitialValue". Сигнал "InitialValue" является входом к алгоритму.

messageInfo(db,"AlgInput")
ans = struct with fields:
             Name: 'AlgInput'
     ProtocolMode: 'CAN'
          Comment: ''
               ID: 100
         Extended: 0
            J1939: []
           Length: 1
              DLC: 1
              BRS: 0
          Signals: {'InitialValue'}
       SignalInfo: [1×1 struct]
          TxNodes: {0×1 cell}
       Attributes: {}
    AttributeInfo: [0×0 struct]

Узел передает сообщение CAN "AlgOutput", содержащий сигнал "ScaledValue". Сигналом "ScaledValue" является выход алгоритма.

messageInfo(db,"AlgOutput")
ans = struct with fields:
             Name: 'AlgOutput'
     ProtocolMode: 'CAN'
          Comment: ''
               ID: 200
         Extended: 0
            J1939: []
           Length: 2
              DLC: 2
              BRS: 0
          Signals: {'ScaledValue'}
       SignalInfo: [1×1 struct]
          TxNodes: {'ECU'}
       Attributes: {}
    AttributeInfo: [0×0 struct]

Программно создайте модель

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

Откройте модель в качестве примера, которая будет сконфигурирована.

open AlgorithmModel

Добавьте и сконфигурируйте блок Configuration CAN

Добавьте и расположите Блок Configuration CAN в модель.

add_block("canlib/CAN Configuration","AlgorithmModel/CAN Configuration")
set_param("AlgorithmModel/CAN Configuration","position",[50,330,250,410])

Установите параметр "Устройства" иметь использование модели MathWorks виртуальное устройство CAN.

set_param("AlgorithmModel/CAN Configuration","Device","MathWorks Virtual 1 (Channel 1)")

Добавьте и сконфигурируйте CAN, получают блок

Добавьте и расположите блок CAN Receive в модель.

add_block("canlib/CAN Receive","AlgorithmModel/CAN Receive")
set_param("AlgorithmModel/CAN Receive","position",[50,200,250,280])

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

add_block("simulink/Sinks/Terminator","AlgorithmModel/Terminator")
set_param("AlgorithmModel/Terminator","position",[310,210,330,230])

Установите параметр "Устройства" иметь использование модели MathWorks виртуальное устройство CAN.

set_param("AlgorithmModel/CAN Receive","Device","MathWorks Virtual 1 (Channel 1)")

Добавьте и сконфигурируйте CAN, распаковывают блок

Добавьте и расположите блок CAN Unpack в модель. По умолчанию блок находится в режиме "Raw Data".

add_block("canlib/CAN Unpack","AlgorithmModel/CAN Unpack")
set_param("AlgorithmModel/CAN Unpack","position",[350,220,600,300])

Установите следующие параметры в блоке CAN Unpack в одном вызове функции:

  • DataFormat

  • CANdbFile

  • MsgList

set_param("AlgorithmModel/CAN Unpack","DataFormat","CANdb specified signals","CANdbFile",db.Path,"MsgList","AlgInput")

Если "Формат данных" и параметры "CANdbFile" уже установлены на блоке, выбранное сообщение изменяемо только включая параметр "MsgList".

Добавьте и сконфигурируйте блок пакета CAN

Добавьте и расположите блок CAN Pack в модель.

add_block("canlib/CAN Pack","AlgorithmModel/CAN Pack")
set_param("AlgorithmModel/CAN Pack","position",[1000,220,1250,300])

Установите следующие параметры в блоке CAN Pack в одном вызове функции:

  • DataFormat

  • CANdbFile

  • MsgList

set_param("AlgorithmModel/CAN Pack","DataFormat","CANdb specified signals","CANdbFile",db.Path,"MsgList","AlgOutput")

Добавьте и сконфигурируйте блок передачи CAN

Добавьте и расположите блок CAN Transmit в модель.

add_block("canlib/CAN Transmit","AlgorithmModel/CAN Transmit")
set_param("AlgorithmModel/CAN Transmit","position",[1350,220,1550,300])

Установите параметр "Устройства" иметь использование модели MathWorks виртуальное устройство CAN. Кроме того, периодическая передача включена с синхронизацией по умолчанию.

set_param("AlgorithmModel/CAN Transmit","Device","MathWorks Virtual 1 (Channel 1)")
set_param("AlgorithmModel/CAN Transmit", "EnablePeriodicTransmit", "on")

Установите связи между блоками

Блоки CAN и блок алгоритма, добавленный в модели, должны теперь быть соединены. Координаты порта для всех блоков CAN требуются.

canRxPort = get_param("AlgorithmModel/CAN Receive","PortConnectivity");
canUnpackPort = get_param("AlgorithmModel/CAN Unpack","PortConnectivity");
subSystemPort = get_param("AlgorithmModel/Subsystem","PortConnectivity");
canPackPort = get_param("AlgorithmModel/CAN Pack","PortConnectivity");
canTxPort = get_param("AlgorithmModel/CAN Transmit","PortConnectivity");
terminatorPort = get_param("AlgorithmModel/Terminator","PortConnectivity");

[canRxPortFunc,canRxPortMsg] = canRxPort.Position;
[canUnpackPortIn,canUnpackPortOut] = canUnpackPort.Position;
[subSystemPortIn,subSystemPortOut] = subSystemPort.Position;
[canPackPortIn,canPackPortOut] = canPackPort.Position;
canTxPortMsg = canTxPort.Position;
terminatorPortIn = terminatorPort.Position;

Добавьте линии, чтобы соединить все блоки в соответствующем порядке.

add_line("AlgorithmModel",[canRxPortMsg ; canUnpackPortIn])
add_line("AlgorithmModel",[canUnpackPortOut ; subSystemPortIn])
add_line("AlgorithmModel",[subSystemPortOut ; canPackPortIn])
add_line("AlgorithmModel",[canPackPortOut ; canTxPortMsg])
add_line("AlgorithmModel",[canRxPortFunc ; terminatorPortIn])

Завершенная модель

Это - то, как модель заботится о конструкции и настройке.

Протестируйте созданную модель

Сконфигурируйте канал CAN в MATLAB для связи с моделью алгоритма

Создайте канал CAN в MATLAB с помощью канала 2 из MathWorks виртуальное устройство CAN. Это свяжется с каналом CAN в модели. Кроме того, присоедините базу данных CAN к каналу MATLAB, чтобы иметь его, автоматически декодируют входящие данные о CAN.

canCh = canChannel("MathWorks","Virtual 1",2);
canCh.Database = db;

Для передачи от MATLAB до модели используйте базу данных CAN, чтобы подготовить сообщение CAN, как введено к алгоритму.

algInputMsg = canMessage(canCh.Database,"AlgInput");

Запустите модель алгоритма

Присвойте время симуляции и запустите симуляцию

set_param("AlgorithmModel","StopTime","inf")
set_param("AlgorithmModel","SimulationCommand","start")

Сделайте паузу, пока симуляция полностью не запускается.

while strcmp(get_param("AlgorithmModel","SimulationStatus"),"stopped")
end

Запустите код MATLAB

Запустите канал CAN MATLAB.

start(canCh);

Передайте несколько сообщений CAN с различными данными сигнала, как введено к модели.

for value = 1:5
    algInputMsg.Signals.InitialValue = value*value;
    transmit(canCh,algInputMsg)
    pause(1)
end

Получите все сообщения от шины. Отметьте экземпляры сообщений "AlgInput" и "AlgOutput", их синхронизации и значений сигналов.

msg = receive(canCh,Inf,"OutputFormat","timetable")
msg=10×8 timetable
        Time        ID     Extended        Name            Data        Length      Signals       Error    Remote
    ____________    ___    ________    _____________    ___________    ______    ____________    _____    ______

    0.009728 sec    100     false      {'AlgInput' }    {[      1]}      1       {1×1 struct}    false    false 
    0.15737 sec     200     false      {'AlgOutput'}    {1×2 uint8}      2       {1×1 struct}    false    false 
    1.0121 sec      100     false      {'AlgInput' }    {[      4]}      1       {1×1 struct}    false    false 
    1.1574 sec      200     false      {'AlgOutput'}    {1×2 uint8}      2       {1×1 struct}    false    false 
    2.0146 sec      100     false      {'AlgInput' }    {[      9]}      1       {1×1 struct}    false    false 
    2.1574 sec      200     false      {'AlgOutput'}    {1×2 uint8}      2       {1×1 struct}    false    false 
    3.0177 sec      100     false      {'AlgInput' }    {[     16]}      1       {1×1 struct}    false    false 
    3.1574 sec      200     false      {'AlgOutput'}    {1×2 uint8}      2       {1×1 struct}    false    false 
    4.0219 sec      100     false      {'AlgInput' }    {[     25]}      1       {1×1 struct}    false    false 
    4.1574 sec      200     false      {'AlgOutput'}    {1×2 uint8}      2       {1×1 struct}    false    false 

canSignalTimetable функция обеспечивает эффективный способ разделить и организовать значения сигналов сообщений CAN в отдельные расписания для каждого.

signalTimeTable = canSignalTimetable(msg)
signalTimeTable = struct with fields:
     AlgInput: [5×1 timetable]
    AlgOutput: [5×1 timetable]

signalTimeTable.AlgInput
ans=5×1 timetable
        Time        InitialValue
    ____________    ____________

    0.009728 sec          1     
    1.0121 sec            4     
    2.0146 sec            9     
    3.0177 sec           16     
    4.0219 sec           25     

signalTimeTable.AlgOutput
ans=5×1 timetable
       Time        ScaledValue
    ___________    ___________

    0.15737 sec         2     
    1.1574 sec          8     
    2.1574 sec         18     
    3.1574 sec         32     
    4.1574 sec         50     

Остановите канал CAN.

stop(canCh)

Остановите модель алгоритма

set_param("AlgorithmModel","SimulationCommand","stop")

Постройте данные сигнала

Постройте начальные и масштабированные значения сигналов сообщений CAN против меток времени, когда они произошли на виртуальной шине. Обратите внимание на изменения в значениях, как передано MATLAB и масштабированием данных, как выполняется моделью.

plot(signalTimeTable.AlgInput.Time,signalTimeTable.AlgInput.InitialValue,"Marker","square","MarkerIndices",1:5)
hold on
plot(signalTimeTable.AlgOutput.Time,signalTimeTable.AlgOutput.ScaledValue,"Marker","square","MarkerIndices",1:5)
hold off
xlabel("TimeStamp");
ylabel("CAN Signal Value");
legend("Initial Value","Scaled Value","Location","northeastoutside");
legend("boxoff");