从 Vector ASC 文件解码 J1939 数据
此示例说明如何在 MATLAB® 中从 Vector ASC 文件中导入和解码 J1939 数据进行分析。此示例中使用的 ASC 日志和 CAN 数据库文件与从 BLF 文件解码 J1939 数据示例中使用的文件类似。
J1939 是基于 CAN 协议构建的协议。参数组 (PG) 是属于同一主题并共享相同传输速率的一组参数,例如 ET1_EMS PG 的 EngCoolantTemp、EngFuelTemp、EngTurboOilTemp 等(请参阅下面的 signalTimetables 中的 ET1_EMS PG)。每个参数组都通过一个称为参数组编号 (PGN) 的唯一编号进行寻址。J1939 PG 是作为 CAN 帧传输的。
ASC 文件包含 ChannelID 值为 1 和 2 的数据,但感兴趣的 J1939 动力总成数据是从 CAN2 网络记录的,因此此示例将重点放在 ChannelID 2 上。
从 ASC 文件中读取 J1939 CAN 数据帧
使用 canMessageImport 函数将来自通道 2 的所有数据读入一个时间表。该时间表的每行均表示来自总线的一个原始 CAN 帧。
canData = canMessageImport("LoggingASC_J1939.asc", "Vector", ChannelID=2, OutputFormat="timetable")
canData=26054×8 timetable
Time ID Extended Name Data Length Signals Error Remote
___________ _________ ________ __________ ___________________________________ ______ ____________ _____ ______
0.12205 sec 418316262 true {0×0 char} {[ 105 52 169 232 0 131 0 16]} 8 {0×0 struct} false false
0.39045 sec 418383078 true {0×0 char} {[ 255 255 255 208 7 255 255 255]} 8 {0×0 struct} false false
0.41035 sec 418383078 true {0×0 char} {[ 255 255 255 208 7 255 255 255]} 8 {0×0 struct} false false
0.4203 sec 418382822 true {0×0 char} {[ 255 0 255 255 255 255 255 255]} 8 {0×0 struct} false false
0.42119 sec 419327206 true {0×0 char} {[255 255 255 255 255 255 255 255]} 8 {0×0 struct} false false
0.43023 sec 418383078 true {0×0 char} {[ 255 255 255 208 7 255 255 255]} 8 {0×0 struct} false false
0.45003 sec 418383078 true {0×0 char} {[ 255 255 255 208 7 255 255 255]} 8 {0×0 struct} false false
0.46988 sec 418382822 true {0×0 char} {[ 255 0 255 255 255 255 255 255]} 8 {0×0 struct} false false
0.47079 sec 418383078 true {0×0 char} {[ 255 255 255 208 7 255 255 255]} 8 {0×0 struct} false false
0.47084 sec 419327206 true {0×0 char} {[255 255 255 255 255 255 255 255]} 8 {0×0 struct} false false
0.47182 sec 419361254 true {0×0 char} {[ 255 0 0 12 255 255 224 255]} 8 {0×0 struct} false false
0.48968 sec 418383078 true {0×0 char} {[ 255 255 255 208 7 255 255 255]} 8 {0×0 struct} false false
0.50949 sec 418383078 true {0×0 char} {[ 255 255 255 208 7 255 255 255]} 8 {0×0 struct} false false
0.51948 sec 418382822 true {0×0 char} {[ 255 0 255 255 255 255 255 255]} 8 {0×0 struct} false false
0.52037 sec 419327206 true {0×0 char} {[255 255 255 255 255 255 255 255]} 8 {0×0 struct} false false
0.52939 sec 418383078 true {0×0 char} {[ 255 255 255 208 7 255 255 255]} 8 {0×0 struct} false false
⋮
使用 DBC 文件解码 J1939 参数组
使用 canDatabase 函数打开数据库文件。
canDB = canDatabase("Powertrain_J1939_ASC.dbc")canDB =
Database with properties:
Name: 'Powertrain_J1939_ASC'
Path: '/tmp/Bdoc26a_3233028_2210314/tp94d33388/vnt-ex98460381/Powertrain_J1939_ASC.dbc'
UTF8_File: '/tmp/Bdoc26a_3233028_2210314/tpa369c5d0_9aa6_4ac9_8b0e_361d636f8c76'
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、PGN 和信号。将二进制记录格式数据的时间表转换为 Vehicle Network Toolbox™ J1939 参数组时间表。
j1939PGTimetable = j1939ParameterGroupTimetable(canData, canDB)
j1939PGTimetable=26054×8 timetable
Time Name PGN Priority PDUFormatType SourceAddress DestinationAddress Data Signals
___________ ________ _____ ________ _____________________ _____________ __________________ ___________________________________ ____________
0.12205 sec ACL 60928 6 Peer-to-Peer (Type 1) 230 255 {[ 105 52 169 232 0 131 0 16]} {1×1 struct}
0.39045 sec EEC1_EMS 61444 6 Broadcast (Type 2) 230 255 {[ 255 255 255 208 7 255 255 255]} {1×1 struct}
0.41035 sec EEC1_EMS 61444 6 Broadcast (Type 2) 230 255 {[ 255 255 255 208 7 255 255 255]} {1×1 struct}
0.4203 sec EEC2_EMS 61443 6 Broadcast (Type 2) 230 255 {[ 255 0 255 255 255 255 255 255]} {1×1 struct}
0.42119 sec TCO1_TCO 65132 6 Broadcast (Type 2) 230 255 {[255 255 255 255 255 255 255 255]} {1×1 struct}
0.43023 sec EEC1_EMS 61444 6 Broadcast (Type 2) 230 255 {[ 255 255 255 208 7 255 255 255]} {1×1 struct}
0.45003 sec EEC1_EMS 61444 6 Broadcast (Type 2) 230 255 {[ 255 255 255 208 7 255 255 255]} {1×1 struct}
0.46988 sec EEC2_EMS 61443 6 Broadcast (Type 2) 230 255 {[ 255 0 255 255 255 255 255 255]} {1×1 struct}
0.47079 sec EEC1_EMS 61444 6 Broadcast (Type 2) 230 255 {[ 255 255 255 208 7 255 255 255]} {1×1 struct}
0.47084 sec TCO1_TCO 65132 6 Broadcast (Type 2) 230 255 {[255 255 255 255 255 255 255 255]} {1×1 struct}
0.47182 sec CCVS_EMS 65265 6 Broadcast (Type 2) 230 255 {[ 255 0 0 12 255 255 224 255]} {1×1 struct}
0.48968 sec EEC1_EMS 61444 6 Broadcast (Type 2) 230 255 {[ 255 255 255 208 7 255 255 255]} {1×1 struct}
0.50949 sec EEC1_EMS 61444 6 Broadcast (Type 2) 230 255 {[ 255 255 255 208 7 255 255 255]} {1×1 struct}
0.51948 sec EEC2_EMS 61443 6 Broadcast (Type 2) 230 255 {[ 255 0 255 255 255 255 255 255]} {1×1 struct}
0.52037 sec TCO1_TCO 65132 6 Broadcast (Type 2) 230 255 {[255 255 255 255 255 255 255 255]} {1×1 struct}
0.52939 sec EEC1_EMS 61444 6 Broadcast (Type 2) 230 255 {[ 255 255 255 208 7 255 255 255]} {1×1 struct}
⋮
查看时间表的第三个 PG 中存储的信号数据,这是“EEC1_EMS”PG 的一个实例。
signalData = j1939PGTimetable.Signals{3}signalData = struct with fields:
EngDemandPercentTorque: 130
EngStarterMode: 15
SrcAddrssOfCtrllngDvcForEngCtrl: 255
EngSpeed: 250
ActualEngPercentTorque: 130
DriversDemandEngPercentTorque: 130
EngTorqueMode: 15
重新打包并可视化感兴趣的信号值
使用 j1939SignalTimetable 函数将来自总线上每个唯一 PGN 的信号数据重新打包到一个信号时间表中。此示例根据 J1939 PG 时间表为两个感兴趣的 PG(“EEC1_EMS”和“TCO1_TCO”)创建两个单独的信号时间表。
signalTimetable1 = j1939SignalTimetable(j1939PGTimetable, ParameterGroups="EEC1_EMS")signalTimetable1=12043×7 timetable
Time EngDemandPercentTorque EngStarterMode SrcAddrssOfCtrllngDvcForEngCtrl EngSpeed ActualEngPercentTorque DriversDemandEngPercentTorque EngTorqueMode
___________ ______________________ ______________ _______________________________ ________ ______________________ _____________________________ _____________
0.39045 sec 130 15 255 250 130 130 15
0.41035 sec 130 15 255 250 130 130 15
0.43023 sec 130 15 255 250 130 130 15
0.45003 sec 130 15 255 250 130 130 15
0.47079 sec 130 15 255 250 130 130 15
0.48968 sec 130 15 255 250 130 130 15
0.50949 sec 130 15 255 250 130 130 15
0.52939 sec 130 15 255 250 130 130 15
0.54922 sec 130 15 255 250 130 130 15
0.56999 sec 130 15 255 250 130 130 15
0.5888 sec 130 15 255 250 130 130 15
0.60868 sec 130 15 255 250 130 130 15
0.6285 sec 130 15 255 250 130 130 15
0.64833 sec 130 15 255 250 130 130 15
0.66918 sec 130 15 255 250 130 130 15
0.68804 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.42119 sec 256 8191.9 3 3 3 3 3 15 3 3 15 3 7 7
0.47084 sec 256 8191.9 3 3 3 3 3 15 3 3 15 3 7 7
0.52037 sec 256 8191.9 3 3 3 3 3 15 3 3 15 3 7 7
0.57008 sec 256 8191.9 3 3 3 3 3 15 3 3 15 3 7 7
0.61952 sec 256 8191.9 3 3 3 3 3 15 3 3 15 3 7 7
0.66922 sec 256 8191.9 3 3 3 3 3 15 3 3 15 3 7 7
0.71886 sec 256 8191.9 3 3 3 3 3 15 3 3 15 3 7 7
0.76874 sec 256 8191.9 3 3 3 3 3 15 3 3 15 3 7 7
0.81827 sec 256 8191.9 3 3 3 3 3 15 3 3 15 3 7 7
0.86808 sec 256 8191.9 3 3 3 3 3 15 3 3 15 3 7 7
0.91762 sec 256 8191.9 3 3 3 3 3 15 3 3 15 3 7 7
0.96737 sec 256 8191.9 3 3 3 3 3 15 3 3 15 3 7 7
1.0169 sec 256 8191.9 3 3 3 3 3 15 3 3 15 3 7 7
1.0667 sec 256 8191.9 3 3 3 3 3 15 3 3 15 3 7 7
1.116 sec 256 8191.9 3 3 3 3 3 15 3 3 15 3 7 7
1.1656 sec 256 8191.9 3 3 3 3 3 15 3 3 15 3 7 7
⋮
您也可以选择将整个 J1939 PG 时间表转换为一个结构体,该结构体包含每个单独 PG 的多个 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.39045 sec 130 15 255 250 130 130 15
0.41035 sec 130 15 255 250 130 130 15
0.43023 sec 130 15 255 250 130 130 15
0.45003 sec 130 15 255 250 130 130 15
0.47079 sec 130 15 255 250 130 130 15
0.48968 sec 130 15 255 250 130 130 15
0.50949 sec 130 15 255 250 130 130 15
0.52939 sec 130 15 255 250 130 130 15
0.54922 sec 130 15 255 250 130 130 15
0.56999 sec 130 15 255 250 130 130 15
0.5888 sec 130 15 255 250 130 130 15
0.60868 sec 130 15 255 250 130 130 15
0.6285 sec 130 15 255 250 130 130 15
0.64833 sec 130 15 255 250 130 130 15
0.66918 sec 130 15 255 250 130 130 15
0.68804 sec 130 15 255 250 130 130 15
⋮
为了可视化感兴趣的信号,可以绘制信号时间表中的变量随时间变化的图,以便进一步分析。对于此示例,请查看来自 EEC1_EMS PG 的 EngineSpeed 信号。
plot(signalTimetable1.Time, signalTimetable1.EngSpeed, "r") title("{\itEngineSpeed} signal from {\itEEC1\_EMS} PG", FontWeight="bold") xlabel("Timestamp") ylabel("Engine Speed")

读取和解码的替代方法
可以使用函数 j1939ParameterGroupImport 代替 canMessageImport 和 j1939ParameterGroupTimetable 来一步完成从 ASC 文件读取和解码 J1939 数据。
j1939PGTimetable = j1939ParameterGroupImport("LoggingASC_J1939.asc", "Vector", canDB, ChannelID=2)
j1939PGTimetable=26054×8 timetable
Time Name PGN Priority PDUFormatType SourceAddress DestinationAddress Data Signals
___________ ________ _____ ________ _____________________ _____________ __________________ ___________________________________ ____________
0.12205 sec ACL 60928 6 Peer-to-Peer (Type 1) 230 255 {[ 105 52 169 232 0 131 0 16]} {1×1 struct}
0.39045 sec EEC1_EMS 61444 6 Broadcast (Type 2) 230 255 {[ 255 255 255 208 7 255 255 255]} {1×1 struct}
0.41035 sec EEC1_EMS 61444 6 Broadcast (Type 2) 230 255 {[ 255 255 255 208 7 255 255 255]} {1×1 struct}
0.4203 sec EEC2_EMS 61443 6 Broadcast (Type 2) 230 255 {[ 255 0 255 255 255 255 255 255]} {1×1 struct}
0.42119 sec TCO1_TCO 65132 6 Broadcast (Type 2) 230 255 {[255 255 255 255 255 255 255 255]} {1×1 struct}
0.43023 sec EEC1_EMS 61444 6 Broadcast (Type 2) 230 255 {[ 255 255 255 208 7 255 255 255]} {1×1 struct}
0.45003 sec EEC1_EMS 61444 6 Broadcast (Type 2) 230 255 {[ 255 255 255 208 7 255 255 255]} {1×1 struct}
0.46988 sec EEC2_EMS 61443 6 Broadcast (Type 2) 230 255 {[ 255 0 255 255 255 255 255 255]} {1×1 struct}
0.47079 sec EEC1_EMS 61444 6 Broadcast (Type 2) 230 255 {[ 255 255 255 208 7 255 255 255]} {1×1 struct}
0.47084 sec TCO1_TCO 65132 6 Broadcast (Type 2) 230 255 {[255 255 255 255 255 255 255 255]} {1×1 struct}
0.47182 sec CCVS_EMS 65265 6 Broadcast (Type 2) 230 255 {[ 255 0 0 12 255 255 224 255]} {1×1 struct}
0.48968 sec EEC1_EMS 61444 6 Broadcast (Type 2) 230 255 {[ 255 255 255 208 7 255 255 255]} {1×1 struct}
0.50949 sec EEC1_EMS 61444 6 Broadcast (Type 2) 230 255 {[ 255 255 255 208 7 255 255 255]} {1×1 struct}
0.51948 sec EEC2_EMS 61443 6 Broadcast (Type 2) 230 255 {[ 255 0 255 255 255 255 255 255]} {1×1 struct}
0.52037 sec TCO1_TCO 65132 6 Broadcast (Type 2) 230 255 {[255 255 255 255 255 255 255 255]} {1×1 struct}
0.52939 sec EEC1_EMS 61444 6 Broadcast (Type 2) 230 255 {[ 255 255 255 208 7 255 255 255]} {1×1 struct}
⋮
此时间表中的信号可以像上面一样重新打包和可视化。