Этот пример показывает вам, как импортировать и декодировать данные J1939 из MDF-файлов в MATLAB для анализа. MDF-файл, используемый в этом примере, был сгенерирован от Векторного КАНОЭ с помощью "Конфигурации системы (J1939)" выборка. Этот пример также использует файл базы данных CAN, Powertrain_J1939_MDF.dbc
, предоставленный Векторную демонстрационную настройку.
Открытый доступ к MDF-файлу с помощью mdf
функция.
m = mdf("LoggingMDF_J1939.mf4")
m = MDF with properties: File Details Name: 'LoggingMDF_J1939.mf4' Path: 'C:\Users\michellw\OneDrive - MathWorks\Documents\MATLAB\Examples\vnt-ex76385747\LoggingMDF_J1939.mf4' Author: '' Department: '' Project: '' Subject: '' Comment: '' Version: '4.10' DataSize: 3743994 InitialTimestamp: 2021-04-21 14:05:13.232000000 Creator Details ProgramIdentifier: 'MDF4Lib' Creator: [1×1 struct] File Contents Attachment: [5×1 struct] ChannelNames: {43×1 cell} ChannelGroup: [1×43 struct] Options Conversion: Numeric
Согласно сопоставленному стандарту ASAM MDF для логгирования шины, типы событий, заданные для системы шины CAN, могут быть "CAN_DataFrame", "CAN_RemoteFrame", "CAN_ErrorFrame" или "CAN_OverloadFrame". J1939 является протоколом, созданным сверху протокола CAN. Группа параметра (PG) J1939 является набором параметров, принадлежащих той же теме и совместно использующих ту же скорость передачи. Например, PG Электронного контроллера Engine 1 (EEC1) содержит скорость вращения двигателя, процент спроса на крутящий момент механизма, фактический процент крутящего момента механизма, и т.д. Каждая группа параметра обращена через уникальный номер, названный номером группы параметра (PGN). PG J1939 передаются, когда CAN структурирует, и MDF-файл отражает, что J1939 PG регистрируется как "CAN_DataFrame".
Стандарт указывает, что названия канала структуры события должны быть снабжены префиксом именем типа события, например, "CAN_DataFrame". Обычно точка используется в качестве символа разделителя, чтобы задать каналы члена, например, "CAN_DataFrame.ID" или "CAN_DataFrame.DataLength".
Используйте channelList
функционируйте, чтобы отфильтровать на названиях канала, точно совпадающих с "CAN_DataFrame". Таблица с информацией о совпадающих каналах возвращена.
channelList(m, "CAN_DataFrame", "ExactMatch", true)
ans=2×9 table
ChannelName ChannelGroupNumber ChannelGroupNumSamples ChannelGroupAcquisitionName ChannelGroupComment ChannelDisplayName ChannelUnit ChannelComment ChannelDescription
_______________ __________________ ______________________ ___________________________ ___________________ __________________ ___________ ______________ __________________
"CAN_DataFrame" 13 26054 CAN2 <undefined> "" <undefined> bus event data "bus event data"
"CAN_DataFrame" 14 92720 CAN1 <undefined> "" <undefined> bus event data "bus event data"
Данные о трансмиссии J1939 интереса регистрировались от сети CAN 2. channelList
выведите выше показов, что данные из сети CAN 2 хранились в группе 13 канала MDF-файла. Посмотрите детали группы канала с помощью ChannelGroup
свойство.
m.ChannelGroup(13)
ans = struct with fields:
AcquisitionName: 'CAN2'
Comment: ''
NumSamples: 26054
DataSize: 703458
Sorted: 1
Channel: [14×1 struct]
Считывайте все данные от всех каналов в группе 13 канала в расписание с помощью read
функция. Расписание структурировано, чтобы следовать стандарту ASAM MDF логгирование формата. Каждая строка представляет одну необработанную систему координат CAN от шины, в то время как каждый столбец представляет канал в заданной группе канала. Каналы, такие как "CAN_DataFrame.Dir", называют, чтобы следовать стандарту логгирования шины. Однако, потому что имена столбцов расписания должны быть допустимыми именами переменной MATLAB, они не могут быть идентичны названиям канала. Большинство неподдерживаемых символов преобразовано в символы нижнего подчеркивания. Поскольку"." не поддерживается на имя переменной MATLAB, "CAN_DataFrame.Dir" изменен к "CAN_DataFrame_Dir" в таблице.
canData = read(m, 13, m.ChannelNames{13})
canData=26054×14 timetable
Time CAN_DataFrame_BusChannel CAN_DataFrame_Flags CAN_DataFrame_Dir CAN_DataFrame_SingleWire CAN_DataFrame_WakeUp CAN_DataFrame_ID CAN_DataFrame_IDE CAN_DataFrame_FrameDuration CAN_DataFrame_BitCount CAN_DataFrame_DLC CAN_DataFrame_DataLength CAN_DataFrame_DataBytes CAN_DataFrame t
____________ ________________________ ___________________ _________________ ________________________ ____________________ ________________ _________________ ___________________________ ______________________ _________________ ________________________ ___________________________________ _________________________________________________________________ ________
0.000568 sec 2 1 1 0 0 2565799910 1 0 0 8 8 {[ 105 52 169 232 0 131 0 16]} {[ 1 8 230 255 238 152 105 52 169 232 0 131 0 16 0 0 0 0 0]} 0.000568
0.27057 sec 2 1 1 0 0 2565866726 1 0 0 8 8 {[ 255 255 255 208 7 255 255 255]} {[ 1 8 230 4 240 152 255 255 255 208 7 255 255 255 0 0 0 0 0]} 0.27057
0.29057 sec 2 1 1 0 0 2565866726 1 0 0 8 8 {[ 255 255 255 208 7 255 255 255]} {[ 1 8 230 4 240 152 255 255 255 208 7 255 255 255 0 0 0 0 0]} 0.29057
0.30058 sec 2 1 1 0 0 2565866470 1 0 0 8 8 {[ 255 0 255 255 255 255 255 255]} {[ 1 8 230 3 240 152 255 0 255 255 255 255 255 255 0 0 0 0 0]} 0.30058
0.30116 sec 2 1 1 0 0 2566810854 1 0 0 8 8 {[255 255 255 255 255 255 255 255]} {[1 8 230 108 254 152 255 255 255 255 255 255 255 255 0 0 0 0 0]} 0.30116
0.31057 sec 2 1 1 0 0 2565866726 1 0 0 8 8 {[ 255 255 255 208 7 255 255 255]} {[ 1 8 230 4 240 152 255 255 255 208 7 255 255 255 0 0 0 0 0]} 0.31057
0.33057 sec 2 1 1 0 0 2565866726 1 0 0 8 8 {[ 255 255 255 208 7 255 255 255]} {[ 1 8 230 4 240 152 255 255 255 208 7 255 255 255 0 0 0 0 0]} 0.33057
0.35058 sec 2 1 1 0 0 2565866470 1 0 0 8 8 {[ 255 0 255 255 255 255 255 255]} {[ 1 8 230 3 240 152 255 0 255 255 255 255 255 255 0 0 0 0 0]} 0.35058
0.35115 sec 2 1 1 0 0 2565866726 1 0 0 8 8 {[ 255 255 255 208 7 255 255 255]} {[ 1 8 230 4 240 152 255 255 255 208 7 255 255 255 0 0 0 0 0]} 0.35115
0.35173 sec 2 1 1 0 0 2566810854 1 0 0 8 8 {[255 255 255 255 255 255 255 255]} {[1 8 230 108 254 152 255 255 255 255 255 255 255 255 0 0 0 0 0]} 0.35173
0.3523 sec 2 1 1 0 0 2566844902 1 0 0 8 8 {[ 255 0 0 12 255 255 224 255]} {[ 1 8 230 241 254 152 255 0 0 12 255 255 224 255 0 0 0 0 0]} 0.3523
0.37057 sec 2 1 1 0 0 2565866726 1 0 0 8 8 {[ 255 255 255 208 7 255 255 255]} {[ 1 8 230 4 240 152 255 255 255 208 7 255 255 255 0 0 0 0 0]} 0.37057
0.39057 sec 2 1 1 0 0 2565866726 1 0 0 8 8 {[ 255 255 255 208 7 255 255 255]} {[ 1 8 230 4 240 152 255 255 255 208 7 255 255 255 0 0 0 0 0]} 0.39057
0.40058 sec 2 1 1 0 0 2565866470 1 0 0 8 8 {[ 255 0 255 255 255 255 255 255]} {[ 1 8 230 3 240 152 255 0 255 255 255 255 255 255 0 0 0 0 0]} 0.40058
0.40116 sec 2 1 1 0 0 2566810854 1 0 0 8 8 {[255 255 255 255 255 255 255 255]} {[1 8 230 108 254 152 255 255 255 255 255 255 255 255 0 0 0 0 0]} 0.40116
0.41057 sec 2 1 1 0 0 2565866726 1 0 0 8 8 {[ 255 255 255 208 7 255 255 255]} {[ 1 8 230 4 240 152 255 255 255 208 7 255 255 255 0 0 0 0 0]} 0.41057
⋮
Откройте файл базы данных с помощью canDatabase
функция.
canDB = canDatabase("Powertrain_J1939_MDF.dbc")
canDB = Database with properties: Name: 'Powertrain_J1939_MDF' Path: 'C:\Users\michellw\OneDrive - MathWorks\Documents\MATLAB\Examples\vnt-ex76385747\Powertrain_J1939_MDF.dbc' Nodes: {12×1 cell} NodeInfo: [12×1 struct] Messages: {93×1 cell} MessageInfo: [93×1 struct] Attributes: {3×1 cell} AttributeInfo: [3×1 struct] UserData: []
j1939ParameterGroupTimetable
функционируйте использует базу данных, чтобы декодировать необработанные Данные о CAN в PG, PGNs и сигналы. Расписание стандартных данных о формате регистрации ASAM преобразовано в Vehicle Network Toolbox расписание группы параметра J1939.
j1939PGTimetable = j1939ParameterGroupTimetable(canData, canDB)
j1939PGTimetable=26030×8 timetable
Time Name PGN Priority PDUFormatType SourceAddress DestinationAddress Data Signals
____________ ________ _____ ________ _____________________ _____________ __________________ ___________________________________ ____________
0.000568 sec ACL 60928 6 Peer-to-Peer (Type 1) 230 255 {[ 105 52 169 232 0 131 0 16]} {1×1 struct}
0.27057 sec EEC1_EMS 61444 6 Broadcast (Type 2) 230 255 {[ 255 255 255 208 7 255 255 255]} {1×1 struct}
0.29057 sec EEC1_EMS 61444 6 Broadcast (Type 2) 230 255 {[ 255 255 255 208 7 255 255 255]} {1×1 struct}
0.30058 sec EEC2_EMS 61443 6 Broadcast (Type 2) 230 255 {[ 255 0 255 255 255 255 255 255]} {1×1 struct}
0.30116 sec TCO1_TCO 65132 6 Broadcast (Type 2) 230 255 {[255 255 255 255 255 255 255 255]} {1×1 struct}
0.31057 sec EEC1_EMS 61444 6 Broadcast (Type 2) 230 255 {[ 255 255 255 208 7 255 255 255]} {1×1 struct}
0.33057 sec EEC1_EMS 61444 6 Broadcast (Type 2) 230 255 {[ 255 255 255 208 7 255 255 255]} {1×1 struct}
0.35058 sec EEC2_EMS 61443 6 Broadcast (Type 2) 230 255 {[ 255 0 255 255 255 255 255 255]} {1×1 struct}
0.35115 sec EEC1_EMS 61444 6 Broadcast (Type 2) 230 255 {[ 255 255 255 208 7 255 255 255]} {1×1 struct}
0.35173 sec TCO1_TCO 65132 6 Broadcast (Type 2) 230 255 {[255 255 255 255 255 255 255 255]} {1×1 struct}
0.3523 sec CCVS_EMS 65265 6 Broadcast (Type 2) 230 255 {[ 255 0 0 12 255 255 224 255]} {1×1 struct}
0.37057 sec EEC1_EMS 61444 6 Broadcast (Type 2) 230 255 {[ 255 255 255 208 7 255 255 255]} {1×1 struct}
0.39057 sec EEC1_EMS 61444 6 Broadcast (Type 2) 230 255 {[ 255 255 255 208 7 255 255 255]} {1×1 struct}
0.40058 sec EEC2_EMS 61443 6 Broadcast (Type 2) 230 255 {[ 255 0 255 255 255 255 255 255]} {1×1 struct}
0.40116 sec TCO1_TCO 65132 6 Broadcast (Type 2) 230 255 {[255 255 255 255 255 255 255 255]} {1×1 struct}
0.41057 sec EEC1_EMS 61444 6 Broadcast (Type 2) 230 255 {[ 255 255 255 208 7 255 255 255]} {1×1 struct}
⋮
Просмотрите данные сигнала, сохраненные в третьем Пг расписания, которое является одним экземпляром Стр. "EEC1_EMS".
signalData = j1939PGTimetable.Signals{3}
signalData = struct with fields:
EngDemandPercentTorque: 130
EngStarterMode: 15
SrcAddrssOfCtrllngDvcForEngCtrl: 255
EngSpeed: 250
ActualEngPercentTorque: 130
DriversDemandEngPercentTorque: 130
EngTorqueMode: 15
Используйте j1939SignalTimetable
функционируйте, чтобы повторно группировать данные сигнала от каждого уникального PGN на шине в расписание сигнала. Этот пример создает два отдельных расписания сигнала для двух PG интереса, "EEC1_EMS" и "TCO1_TCO", из расписания J1939 PG.
signalTimetable1 = j1939SignalTimetable(j1939PGTimetable, "ParameterGroups", "EEC1_EMS")
signalTimetable1=12043×7 timetable
Time EngDemandPercentTorque EngStarterMode SrcAddrssOfCtrllngDvcForEngCtrl EngSpeed ActualEngPercentTorque DriversDemandEngPercentTorque EngTorqueMode
___________ ______________________ ______________ _______________________________ ________ ______________________ _____________________________ _____________
0.27057 sec 130 15 255 250 130 130 15
0.29057 sec 130 15 255 250 130 130 15
0.31057 sec 130 15 255 250 130 130 15
0.33057 sec 130 15 255 250 130 130 15
0.35115 sec 130 15 255 250 130 130 15
0.37057 sec 130 15 255 250 130 130 15
0.39057 sec 130 15 255 250 130 130 15
0.41057 sec 130 15 255 250 130 130 15
0.43057 sec 130 15 255 250 130 130 15
0.45115 sec 130 15 255 250 130 130 15
0.47057 sec 130 15 255 250 130 130 15
0.49057 sec 130 15 255 250 130 130 15
0.51057 sec 130 15 255 250 130 130 15
0.53057 sec 130 15 255 250 130 130 15
0.55115 sec 130 15 255 250 130 130 15
0.57057 sec 130 15 255 250 130 130 15
⋮
signalTimetable2 = j1939SignalTimetable(j1939PGTimetable, "ParameterGroups", "TCO1_TCO")
signalTimetable2=4817×14 timetable
Time TachographVehicleSpeed TachographOutputShaftSpeed DirectionIndicator TachographPerformance HandlingInformation SystemEvent DriverCardDriver2 Driver2TimeRelatedStates Overspeed DriverCardDriver1 Driver1TimeRelatedStates DriveRecognize Driver2WorkingState Driver1WorkingState
___________ ______________________ __________________________ __________________ _____________________ ___________________ ___________ _________________ ________________________ _________ _________________ ________________________ ______________ ___________________ ___________________
0.30116 sec 256 8191.9 3 3 3 3 3 15 3 3 15 3 7 7
0.35173 sec 256 8191.9 3 3 3 3 3 15 3 3 15 3 7 7
0.40116 sec 256 8191.9 3 3 3 3 3 15 3 3 15 3 7 7
0.45173 sec 256 8191.9 3 3 3 3 3 15 3 3 15 3 7 7
0.50116 sec 256 8191.9 3 3 3 3 3 15 3 3 15 3 7 7
0.55173 sec 256 8191.9 3 3 3 3 3 15 3 3 15 3 7 7
0.60116 sec 256 8191.9 3 3 3 3 3 15 3 3 15 3 7 7
0.65173 sec 256 8191.9 3 3 3 3 3 15 3 3 15 3 7 7
0.70116 sec 256 8191.9 3 3 3 3 3 15 3 3 15 3 7 7
0.75173 sec 256 8191.9 3 3 3 3 3 15 3 3 15 3 7 7
0.80116 sec 256 8191.9 3 3 3 3 3 15 3 3 15 3 7 7
0.85173 sec 256 8191.9 3 3 3 3 3 15 3 3 15 3 7 7
0.90116 sec 256 8191.9 3 3 3 3 3 15 3 3 15 3 7 7
0.95173 sec 256 8191.9 3 3 3 3 3 15 3 3 15 3 7 7
1.0012 sec 256 8191.9 3 3 3 3 3 15 3 3 15 3 7 7
1.0517 sec 256 8191.9 3 3 3 3 3 15 3 3 15 3 7 7
⋮
Можно альтернативно принять решение преобразовать целое расписание J1939 PG в struct, содержащий несколько расписаний сигнала J1939 для каждого отдельного PG и индекса в него, чтобы получить данные для конкретной Стр.
signalTimetables = j1939SignalTimetable(j1939PGTimetable)
signalTimetables = struct with fields:
ACL: [1×14 timetable]
CCVS_EMS: [2408×19 timetable]
DD: [240×5 timetable]
EEC1_EMS: [12043×7 timetable]
EEC2_EMS: [4817×10 timetable]
ET1_EMS: [240×6 timetable]
HOURS_EMS: [240×2 timetable]
LFC_EMS: [480×2 timetable]
SERV: [240×6 timetable]
TCO1_TCO: [4817×14 timetable]
VDHR_EMS: [240×2 timetable]
VI_EMS: [24×1 timetable]
VW_SSC: [240×4 timetable]
signalTimetables.EEC1_EMS
ans=12043×7 timetable
Time EngDemandPercentTorque EngStarterMode SrcAddrssOfCtrllngDvcForEngCtrl EngSpeed ActualEngPercentTorque DriversDemandEngPercentTorque EngTorqueMode
___________ ______________________ ______________ _______________________________ ________ ______________________ _____________________________ _____________
0.27057 sec 130 15 255 250 130 130 15
0.29057 sec 130 15 255 250 130 130 15
0.31057 sec 130 15 255 250 130 130 15
0.33057 sec 130 15 255 250 130 130 15
0.35115 sec 130 15 255 250 130 130 15
0.37057 sec 130 15 255 250 130 130 15
0.39057 sec 130 15 255 250 130 130 15
0.41057 sec 130 15 255 250 130 130 15
0.43057 sec 130 15 255 250 130 130 15
0.45115 sec 130 15 255 250 130 130 15
0.47057 sec 130 15 255 250 130 130 15
0.49057 sec 130 15 255 250 130 130 15
0.51057 sec 130 15 255 250 130 130 15
0.53057 sec 130 15 255 250 130 130 15
0.55115 sec 130 15 255 250 130 130 15
0.57057 sec 130 15 255 250 130 130 15
⋮
Чтобы визуализировать сигнал интереса, переменные из расписаний сигнала могут строиться в зависимости от времени для последующего анализа. В данном примере посмотрите на сигнал "EngineSpeed" из Стр. "EEC1_EMS".
plot(signalTimetable1.Time, signalTimetable1.EngSpeed, "r") title("{\itEngineSpeed} signal from {\itEEC1\_EMS} PG", "FontWeight", "bold") xlabel("Timestamp") ylabel("Engine Speed")
Закройте доступ к MDF-файлу и файлу DBC путем очищения их переменных из рабочей области.
clear m clear canDB