Log and Replay CAN Messages
This example shows you how to log and replay CAN messages using MathWorks® Virtual CAN channels in Simulink®. You can update this model to connect to supported hardware on your system.
Load the saved CAN message from SourceMsgs.mat
file from the examples folder. The file contains CAN messages representing a 90 second drive cycle around a test track.
load SourceMsgs.mat
Alternatively, read the CAN messages from a BLF file using the blfread
function. Notice that the output is a scalar cell, therefore the timetable needs to be extracted from the cell.
canMsgTimetable = blfread("SourceMsgs.blf");
canMsgTimetable = canMsgTimetable{1};
A similar approach can be used to read from MDF files, using the mdfRead
function.
Notice that the initial time stamp of the recorded messages is not zero:
startTime = seconds(canMsgTimetable.Time(1))
startTime = 88.6176
stopTime = seconds(canMsgTimetable.Time(end))
stopTime = 177.2310
Define a simulation time step of 0.01 s, and round the values of startTime
and stopTime
to be compatible with it.
Ts = 0.01; startTime = round(startTime, 2); stopTime = round(stopTime, 2);
Convert the messages to a format compatible with the CAN Replay block and save them to a separate file.
canMsgs = canMessageReplayBlockStruct(canMsgTimetable); save DriveReplay.mat canMsgs whos
Name Size Bytes Class Attributes Ts 1x1 8 double canMsgTimetable 100000x8 38311075 timetable canMsgs 1x1 2400952 struct startTime 1x1 8 double stopTime 1x1 8 double
CAN Replay Model
This model contains:
A CAN Replay block that transmits to
MathWorks Virtual Channel 1
.A CAN Receive block that receives the messages on a CAN network, through
MathWorks Virtual Channel 2
.
The CAN Receive block is configured to block all extended IDs and allow only the WheelSpeed
message with the standard ID 1200
to pass.
Configure the model parameters for compatibility with the CAN messages timeseries. Click on the Modeling tab, then on Configuration Parameters. In the Solver pane, use the startTime
, stopTime
and Ts
variables in the appropriate edit fields as shown.
Click OK to apply changes and close the window.
Wheel Speeds Subsystem
The Wheel Speeds subsystem unpacks the wheel speed information from the received CAN messages and plots them to a scope. The subsystem also logs the messages to a file.
Visualize Wheel Speed Information
Click Run to run the simulation. Depending on you computer configuration, the output shown in the scope may be zero.
This result is expected: model simulation and message transmission are executed on separate threads, and are not synchronized. Simulink attempts to execute the simulation as fast as possible, and the provided time series is very short; it is therefore likely that transmission of the first message had not been initiated before the simulation was completed.
A better approach to replaying logged signals is to use simulation pacing, which slows down model execution to achieve an approximately real-time simulation. To activate simulation pacing, click on Run -> Simulation Pacing, then activate the option via the tick box. Run the simulation again, then visualize the wheel speed for all wheels for the duration of the test drive.
Load the Logged Message File
The CAN Log block creates a unique file each time you run the model. Use dir
in the MATLAB® Command Window to find the latest log file.
dir WheelSpeeds*.mat
WheelSpeeds_2023-Jun-20_150142.mat
load WheelSpeeds_2023-Jun-20_150142.mat
whos
Name Size Bytes Class Attributes Ts 1x1 8 double canMsgTimetable 100000x8 38311075 timetable canMsgs 1x1 2400952 struct outMsgs 1x1 240304 struct startTime 1x1 8 double stopTime 1x1 8 double
Convert Logged Messages
Offset the logged timestamps using the previously defined startTime
variable.
outMsgs.Timestamp = startTime + outMsgs.Timestamp;
Use canMessageTimetable
to convert messages logged during the simulation to a timetable that you can use in the command window.
To access message signals directly, use the appropriate database file in the conversion along with canSignalTimetable
.
Use then the plot function to visualize the signals, and compare them to the output of the simulation.
db = canDatabase('VehicleInfo.dbc');
wheelSpeedMsgTimetable = canMessageTimetable(outMsgs, db);
wheelSpeedMsgTimetable(1:15, :)
ans=15×8 timetable
Time ID Extended Name Data Length Signals Error Remote
__________ ____ ________ _______________ ___________________________ ______ ____________ _____ ______
88.912 sec 1200 false {'WheelSpeeds'} {[39 16 39 16 39 16 39 16]} 8 {1x1 struct} false false
88.92 sec 1200 false {'WheelSpeeds'} {[39 16 39 16 39 16 39 16]} 8 {1x1 struct} false false
88.929 sec 1200 false {'WheelSpeeds'} {[39 16 39 16 39 16 39 16]} 8 {1x1 struct} false false
88.939 sec 1200 false {'WheelSpeeds'} {[39 16 39 16 39 16 39 16]} 8 {1x1 struct} false false
88.947 sec 1200 false {'WheelSpeeds'} {[39 16 39 16 39 16 39 16]} 8 {1x1 struct} false false
88.957 sec 1200 false {'WheelSpeeds'} {[39 16 39 16 39 16 39 16]} 8 {1x1 struct} false false
88.965 sec 1200 false {'WheelSpeeds'} {[39 16 39 16 39 16 39 16]} 8 {1x1 struct} false false
88.974 sec 1200 false {'WheelSpeeds'} {[39 16 39 16 39 16 39 16]} 8 {1x1 struct} false false
88.982 sec 1200 false {'WheelSpeeds'} {[39 16 39 16 39 16 39 16]} 8 {1x1 struct} false false
88.99 sec 1200 false {'WheelSpeeds'} {[39 16 39 16 39 16 39 16]} 8 {1x1 struct} false false
88.999 sec 1200 false {'WheelSpeeds'} {[39 16 39 16 39 16 39 16]} 8 {1x1 struct} false false
89.007 sec 1200 false {'WheelSpeeds'} {[39 16 39 16 39 16 39 16]} 8 {1x1 struct} false false
89.016 sec 1200 false {'WheelSpeeds'} {[39 16 39 16 39 16 39 16]} 8 {1x1 struct} false false
89.024 sec 1200 false {'WheelSpeeds'} {[39 16 39 16 39 16 39 16]} 8 {1x1 struct} false false
89.033 sec 1200 false {'WheelSpeeds'} {[39 16 39 16 39 16 39 16]} 8 {1x1 struct} false false
wheelSpeedSignals = canSignalTimetable(wheelSpeedMsgTimetable); wheelSpeedSignals(end-14:end, :)
ans=15×4 timetable
Time LR_WSpeed RR_WSpeed RF_WSpeed LF_WSpeed
__________ _________ _________ _________ _________
177.38 sec 56.73 56.73 56.61 56.65
177.39 sec 56.76 56.69 56.64 56.66
177.4 sec 56.74 56.66 56.62 56.65
177.41 sec 56.72 56.73 56.56 56.64
177.42 sec 56.76 56.76 56.57 56.66
177.43 sec 56.78 56.69 56.66 56.72
177.44 sec 56.82 56.74 56.72 56.74
177.45 sec 56.85 56.81 56.77 56.72
177.45 sec 56.79 56.81 56.79 56.69
177.46 sec 56.76 56.83 56.78 56.66
177.47 sec 56.74 56.79 56.74 56.66
177.48 sec 56.7 56.74 56.68 56.69
177.49 sec 56.76 56.77 56.69 56.72
177.5 sec 56.76 56.81 56.72 56.77
177.51 sec 56.65 56.83 56.68 56.77
plot(wheelSpeedSignals.Time, wheelSpeedSignals{:,:});
MathWorks CAN Virtual channels were used for this example. You can however connect your models to other supported hardware.
See Also
Tools
- Simulation Pacing Options (Simulink)