%% Decode CAN Data from MDF-Files
% This example shows you how to import and decode CAN data from MDF-files in MATLAB for analysis. The MDF-file used in this example was generated from Vector CANoe™ using the "CAN - General System Configuration (CAN)" sample. This example also uses the CAN database file, PowerTrain.dbc, provided with the Vector sample configuration.
%
%% Open the MDF-File
% Open access to the MDF-file using the mdf function.

m = mdf("Logging_MDF.mf4")

%
%% Identify CAN Data Frames
% According to the ASAM MDF associated standard for bus logging, the event types defined for a CAN bus system can be "CAN_DataFrame", "CAN_RemoteFrame", "CAN_ErrorFrame" or "CAN_OverloadFrame". This example focuses on extracting the CAN data frames, so the bus logging standard will be discussed using "CAN_DataFrame" event type as example. Additionally, note that a standard CAN data frame has up to 8 bytes for its payload and is used to transfer signal values.
% The standard specifies that the channel names of the event structure should be prefixed by the event type name, for instance, "CAN_DataFrame". Typically a dot is used as separator character to specify the member channels, for instance, "CAN_DataFrame.ID" or "CAN_DataFrame.DataLength".
% Use the channelList function to filter on channel names exactly matching "CAN_DataFrame". A table with information on matched channels is returned.

channelList(m, "CAN_DataFrame", "ExactMatch", true)

% The powetrain data of interest was logged from the CAN 2 network. The channelList output above shows that the data from CAN 2 network has been stored in channel group 29 of the MDF-file. View the channel group details using the ChannelGroup property.

m.ChannelGroup(29)

% Within a channel group, details about each channel are stored. View details about channel 2 within channel group 29.

m.ChannelGroup(29).Channel(2)

%
%% Read CAN Data Frames From the MDF-File
% Read all data from all channels in channel group 29 into a timetable using the read function. The timetable is structured to follow the ASAM MDF standard logging format. Every row represents one raw CAN frame from the bus, while each column represents a channel within the specified channel group. The channels, such as "CAN_DataFrame.Dir", are named to follow the bus logging standard. However, because timetable column names must be valid MATLAB variable names, they may not be identical to the channel names. Most unsupported characters are converted to underscores. Since "." is not supported in a MATLAB variable name, "CAN_DataFrame.Dir" is altered to "CAN_DataFrame_Dir" in the table.

canData = read(m, 29, m.ChannelNames{29})

%
%% Decode CAN Messages Using the DBC-File
% Open the database file using the canDatabase function.

canDB = canDatabase("PowerTrain_MDF.dbc")

% The canMessageTimetable function uses the database to decode the message names and signals. The timetable of ASAM standard logging format data is converted into a Vehicle Network Toolbox™ CAN message timetable.

msgTimetable = canMessageTimetable(canData, canDB)

% View the signals stored in the "EngineData" message.

msgTimetable.Signals{3}

%
%% Repackage and Visualize Signal Values of Interest
% Use the canSignalTimetable function to repackage signal data from each unique message on the bus into a signal timetable. This example creates three individual signal timetables for the three messages of interest, "ABSdata", "EngineData" and "GearBoxInfo", from the CAN message timetable.

signalTimetable1 = canSignalTimetable(msgTimetable, "ABSdata")
signalTimetable2 = canSignalTimetable(msgTimetable, "EngineData")
signalTimetable3 = canSignalTimetable(msgTimetable, "GearBoxInfo")

% To visualize the signals of interest, columns from the signal timetables can be plotted over time for further analysis.

subplot(3, 1, 1)
plot(signalTimetable1.Time, signalTimetable1.CarSpeed, "r")
title("{\itCarSpeed} Signal from {\itABSdata} Message", "FontWeight", "bold")
xlabel("Timestamp")
ylabel("Car Speed")
subplot(3, 1, 2)
plot(signalTimetable2.Time, signalTimetable2.EngSpeed, "b")
title("{\itEngSpeed} Signal from {\itEngineData} Message", "FontWeight", "bold")
xlabel("Timestamp")
ylabel("Engine Speed")
subplot(3, 1, 3)
plot(signalTimetable3.Time, signalTimetable3.Gear, "y")
title("{\itGear} Signal from {\itGearBoxInfo} Message", "FontWeight", "bold")
xlabel("Timestamp")
ylabel("Gear")

%
%% Close the Files
% Close access to the MDF-file and the DBC-file by clearing their variables from the workspace.

clear m
clear canDB

%
% Copyright 2020-2021 The MathWorks, Inc.