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