Main Content

Log and Replay CAN FD Messages

This example shows you how to log and replay CAN FD messages using MathWorks® virtual CAN FD channels in Simulink®. You can update this model to connect to supported hardware on your system.

Load the saved CAN FD messages from the SourceFDMsgs.mat file from the examples folder. The file contains CAN FD messages representing a 90-second drive cycle around a test track.

load SourceFDMsgs.mat

Inspect the timetable containing the CAN FD messages. In particular, notice that the initial time stamp is not zero:

startTime = seconds(canFDMsgTimetable.Time(1)) %#ok<NOPTS>
startTime = 88.6176
stopTime = seconds(canFDMsgTimetable.Time(end)) %#ok<NOPTS>
stopTime = 177.2310

Convert these messages to a format compatible with the CAN FD Replay block and save them to a separate file.

canFDMsgs = canFDMessageReplayBlockStruct(canFDMsgTimetable);
save DriveReplayFD.mat canFDMsgs
whos
  Name                        Size               Bytes  Class        Attributes

  canFDMsgTimetable      100000x12            45411725  timetable              
  canFDMsgs                   1x1              8401848  struct                 
  startTime                   1x1                    8  double                 
  stopTime                    1x1                    8  double                 

CAN FD Replay Model

This model contains:

  • A CAN FD Replay block that transmits to MathWorks Virtual Channel 1.

  • A CAN FD Receive block that receives the messages on a CAN FD network, through MathWorks Virtual Channel 2.

The CAN FD Receive block is configured to block all extended IDs and allow only the WheelSpeed message with the standard ID 1200 to pass.

Configure the simulation start and stop time coherently with the initial and final timestamps of the messages timeseries. To this end, select the Modeling tab and click on Model Settings. Then, in the Configuration Parameters dialog box, set the simulation start and stop time using the variables startTime and stopTime previously defined. Click Apply and close the Configuration Parameters window.

Run the simulation by clicking on the button Run.

Notice the warning in the Diagnostic Viewer:

The model is configured to use a fixed-step solver, with a time step of 0.01 s. However, the values of the start and stop time, as obtained from the recorded timeseries, are not integer multiples of the simulation time step. The default behavior in Simulink is to round those values to make them compatible with the simulation time step; they could also be rounded in a MATLAB® script before simulation. More information about the automatic parameter selection of Simulink solvers can be found in the documentation page Choose a Solver (Simulink).

Wheel Speeds Subsystem

The Wheel Speeds subsystem unpacks the wheel speed information from the received CAN FD messages and plots them to a scope. The subsystem also logs the messages to a file.

Visualize Wheel Speed Information

The plot in the Scope shows the wheel speed for all wheels for the duration of the test drive.

Depending on the configuration of your computer, the signals in the scope after simulation may be zero. This result is normal: model simulation and message transmission are executed on different threads and are not synchronized. Simulink attempts to simulate the model as fast as possible, and since the timeseries is very short, it is very likely that the reception of the first message has not been finalized by the time the simulation has ended.

A more appropriate approach to replaying logged signals in Simulink is to use simulation pacing to execute the model in approximate real-time conditions. In this way, the simulation of the model runs approximately at the pace the signals have been recorded. To enable simulation pacing click on Run -> Simulation Pacing, and tick the checkbox Enable pacing to slow down simulation. Run the simulation again and inspect the Scope, which now shows the appropriate signals.

To learn more about simulation pacing, visit this page: Simulation Pacing Options (Simulink).

Load the Logged Message File

The CAN FD 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_123918.mat  WheelSpeeds_2023-Jun-20_151835.mat  
load WheelSpeeds_2023-Jun-20_123918.mat
whos
  Name                        Size               Bytes  Class        Attributes

  canFDMsgTimetable      100000x12            45411725  timetable              
  canFDMsgs                   1x1              8401848  struct                 
  outFDMsgs                   1x1              7845516  struct                 
  startTime                   1x1                    8  double                 
  stopTime                    1x1                    8  double                 

Convert Logged Messages

Use the startTime variable to offset the recorded timestamps from the CAN FD Log block.

outFDMsgs.Timestamp = startTime + outFDMsgs.Timestamp;

Use the function canFDMessageTimetable 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.

db = canDatabase('VehicleInfoFD.dbc');
wheelSpeedMsgTimetable = canFDMessageTimetable(outFDMsgs, db);
wheelSpeedMsgTimetable(1:15, :)
ans=15×12 timetable
       Time        ID     Extended         Name          ProtocolMode                 Data                 Length    DLC      Signals       Error    Remote     BRS      ESI 
    __________    ____    ________    _______________    ____________    ______________________________    ______    ___    ____________    _____    ______    _____    _____

    88.829 sec    1201     false      {0×0 char     }     {'CAN FD'}     {[           0 0 0 0 0 0 0 0]}      8        8     {0×0 struct}    false    false     true     false
    88.83 sec     1312     false      {0×0 char     }     {'CAN FD'}     {[            250 0 200 50 0]}      5        5     {0×0 struct}    false    false     true     false
    88.831 sec     512     false      {0×0 char     }     {'CAN FD'}     {[   2 1 1 250 1 231 129 255]}      8        8     {0×0 struct}    false    false     true     false
    88.832 sec     513     false      {0×0 char     }     {'CAN FD'}     {[12 103 255 255 39 16 1 255]}      8        8     {0×0 struct}    false    false     true     false
    88.832 sec     533     false      {0×0 char     }     {'CAN FD'}     {[        2 26 2 26 2 24 0 0]}      8        8     {0×0 struct}    false    false     true     false
    88.832 sec     561     false      {0×0 char     }     {'CAN FD'}     {[      15 4 255 255 0 0 0 0]}      8        8     {0×0 struct}    false    false     true     false
    88.832 sec     576     false      {0×0 char     }     {'CAN FD'}     {[             63 141 140 32]}      4        4     {0×0 struct}    false    false     true     false
    88.832 sec    1616     false      {0×0 char     }     {'CAN FD'}     {[                         0]}      1        1     {0×0 struct}    false    false     true     false
    88.836 sec    1200     false      {'WheelSpeeds'}     {'CAN FD'}     {[   39 16 39 16 39 16 39 16]}      8        8     {1×1 struct}    false    false     true     false
    88.836 sec    1201     false      {0×0 char     }     {'CAN FD'}     {[           0 0 0 0 0 0 0 0]}      8        8     {0×0 struct}    false    false     true     false
    88.836 sec    1216     false      {0×0 char     }     {'CAN FD'}     {[                       163]}      1        1     {0×0 struct}    false    false     true     false
    88.841 sec     512     false      {0×0 char     }     {'CAN FD'}     {[   2 1 1 250 1 231 129 255]}      8        8     {0×0 struct}    false    false     true     false
    88.842 sec     513     false      {0×0 char     }     {'CAN FD'}     {[12 103 255 255 39 16 1 255]}      8        8     {0×0 struct}    false    false     true     false
    88.842 sec     533     false      {0×0 char     }     {'CAN FD'}     {[        2 26 2 26 2 24 0 0]}      8        8     {0×0 struct}    false    false     true     false
    88.843 sec    1296     false      {0×0 char     }     {'CAN FD'}     {[                     0 0 1]}      3        3     {0×0 struct}    false    false     true     false

wheelSpeedSignals = canSignalTimetable(wheelSpeedMsgTimetable);
wheelSpeedSignals(end-14:end, :)
ans=15×4 timetable
       Time       RR_WSpeed    RF_WSpeed    LR_WSpeed    LF_WSpeed
    __________    _________    _________    _________    _________

    177.31 sec       57.4        57.37        57.27        57.35  
    177.32 sec      57.39        57.35         57.3        57.32  
    177.33 sec      57.36        57.39         57.4        57.31  
    177.33 sec      57.47        57.46        57.47        57.37  
    177.34 sec      57.56        57.41        57.45        57.39  
    177.35 sec      57.48        57.33        57.43         57.4  
    177.36 sec      57.37        57.35        57.41        57.41  
    177.37 sec      57.33        57.41        57.41        57.39  
    177.37 sec      57.37        57.44        57.44        57.36  
    177.38 sec      57.48        57.47        57.43        57.35  
    177.39 sec       57.5        57.43         57.4        57.33  
    177.4 sec       57.48        57.36        57.35        57.32  
    177.41 sec      57.43        57.35        57.28        57.33  
    177.42 sec      57.28         57.4        57.26        57.36  
    177.43 sec      57.27        57.46        57.23        57.35  

plot(wheelSpeedSignals.Time, wheelSpeedSignals{:,:});

MathWorks CAN FD virtual channels were used for this example. You can however connect your models to other supported hardware.

See Also

Tools

Related Topics