В этом примере показано, как программно создать модель Simulink, чтобы ввести CAN или коммуникацию CAN FD с помощью файла DBC CAN. С add_block и set_param функциями Simulink, можно добавить и полностью сконфигурировать блоки Vehicle Network Toolbox (VNT), чтобы взять основной алгоритм и добавить сетевые коммуникации. Файл DBC содержит сообщения CAN и детали сигнала. В первую очередь, особое внимание должно программно сконфигурировать CAN и Пакет CAN FD и Распаковать параметры блоков. Это может значительно увеличить КПД типовой конструкции.
Модель в качестве примера (AlgorithmModel.slx) содержит блок подсистемы под названием "Алгоритм". Этот блок представляет любой данный алгоритм приложения, разработанный в Simulink. Блок Gain со значением 2 является в этой подсистеме, например, целями. Эта подсистема имеет вход сигнала CAN по имени "In1". Это входное значение масштабируется значением усиления. Масштабированное значение дано как ouput этой подсистемы по имени "Out1". Значение усиления changable или блок Gain, замененный различным алгоритмом пользователя для экспериментирования.
К содержимому файлов DBC CAN получают доступ с функцией canDatabase. Через эту функцию детали о сетевых узлах, сообщениях и сигналах доступны.
db = canDatabase("CANBus.dbc")
db = Database with properties: Name: 'CANBus' Path: '/tmp/BR2019bd_1276998_130124/mlx_to_docbook1/tp5b9f827c/vnt-ex60686316/CANBus.dbc' Nodes: {'ECU'} NodeInfo: [1x1 struct] Messages: {2x1 cell} MessageInfo: [2x1 struct] Attributes: {} AttributeInfo: [0x0 struct] UserData: []
Узел "ECU" задан в файле DBC CAN в качестве примера как показано ниже.
node = nodeInfo(db,"ECU")
node = struct with fields:
Name: 'ECU'
Comment: ''
Attributes: {}
AttributeInfo: [0x0 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: [1x1 struct]
TxNodes: {0x1 cell}
Attributes: {}
AttributeInfo: [0x0 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: [1x1 struct]
TxNodes: {'ECU'}
Attributes: {}
AttributeInfo: [0x0 struct]
Откройте модель в качестве примера, которая будет сконфигурирована.
open AlgorithmModel
Добавьте и расположите Блок 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 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 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" уже установлены на блоке, выбранное сообщение changable только включая параметр "MsgList".
Добавьте и расположите блок 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 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 с помощью канала 2 из устройства MathWorks Virtual CAN. Это свяжется с каналом CAN в модели. Кроме того, присоедините базу данных CAN к каналу MATLAB, чтобы иметь его автоматически decoce входящие данные о 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
Запустите канал 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×9 timetable
Time ID Extended Name Data Length Signals Error Remote
____________ ___ ________ _____________ ___________ ______ ____________ _____ ______
0.01405 sec 100 false {'AlgInput' } {[ 1]} 1 {1x1 struct} false false
0.092436 sec 200 false {'AlgOutput'} {1x2 uint8} 2 {1x1 struct} false false
1.0246 sec 100 false {'AlgInput' } {[ 4]} 1 {1x1 struct} false false
1.0925 sec 200 false {'AlgOutput'} {1x2 uint8} 2 {1x1 struct} false false
2.0366 sec 100 false {'AlgInput' } {[ 9]} 1 {1x1 struct} false false
2.0925 sec 200 false {'AlgOutput'} {1x2 uint8} 2 {1x1 struct} false false
3.0437 sec 100 false {'AlgInput' } {[ 16]} 1 {1x1 struct} false false
3.0925 sec 200 false {'AlgOutput'} {1x2 uint8} 2 {1x1 struct} false false
4.066 sec 100 false {'AlgInput' } {[ 25]} 1 {1x1 struct} false false
4.0925 sec 200 false {'AlgOutput'} {1x2 uint8} 2 {1x1 struct} false false
Функция canSignalTimetable обеспечивает эффективный способ разделить и организовать значения сигналов сообщений CAN в отдельные расписания для каждого.
signalTimeTable = canSignalTimetable(msg)
signalTimeTable = struct with fields:
AlgInput: [5x1 timetable]
AlgOutput: [5x1 timetable]
signalTimeTable.AlgInput
ans=5×2 timetable
Time InitialValue
___________ ____________
0.01405 sec 1
1.0246 sec 4
2.0366 sec 9
3.0437 sec 16
4.066 sec 25
signalTimeTable.AlgOutput
ans=5×2 timetable
Time ScaledValue
____________ ___________
0.092436 sec 2
1.0925 sec 8
2.0925 sec 8
3.0925 sec 8
4.0925 sec 8
Остановите канал 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");