%% CAN Message Reception Behavior in Simulink
% This example shows how to observe the message processing behaviors of the CAN Receive and CAN Unpack blocks in multiple modeling scenarios. This example demonstrates two cases, with and without using the function trigger f() port of the CAN Receive block. The outputs of the model indicate the number of CAN messages unpacked for downstream processing in each case. The example uses MathWorks virtual CAN channels to send CAN messages from MATLAB to the Simulink model. These modeling practices and behavior also apply to the CAN FD protocol using the Vehicle Network Toolbox CAN FD blocks.
%
%% Explore the Example Model
% The example model contains a CAN Receive block configured for Mathworks virtual channels sampling every 500 ms. The received CAN messages are unpacked in two ways:
% A CAN Unpack block inside a function-call subsystem, triggered by the function trigger f() port of the CAN Receive block.
% A CAN Unpack block connected directly to the CAN Msg output port.
% Scopes are placed to view the received signals in both cases. Also, the signal values from the output port of the CAN Unpack blocks are exported to the MATLAB workspace, and used to plot the results.
%

open CanReceiveModel

%
%% Prepare the CAN Messages for Transmission
% To demonstrate the operation of the model, CAN messages are sent from MATLAB. The messages are loaded from the provided MAT-file. A canChannel is created to transmit the data later in this example. The messages to send are timed periodically at 100 ms, and the contained signal data is incrementing linearly.

load canMessages.mat
txCh = canChannel("MathWorks","Virtual 1", 1);

%
%% Execute the Model and Replay CAN Messages from MATLAB
% Assign a finite simulation time and run the model.

simTime = 10;
set_param("CanReceiveModel","StopTime",num2str(simTime))
set_param("CanReceiveModel","SimulationCommand","start")

% Pause script execution until the model is recognized as fully started.

while strcmp(get_param("CanReceiveModel","SimulationStatus"),"stopped")
end

% Start the CAN channel and execute the replay of the loaded CAN messages.

start(txCh);
replay(txCh, canMessages);

% As the replay happens, the CAN Receive block in the model is receiving and processing the messages. You can view the signal values received in real time in the scopes placed inside and outside of the function-call subsystem. Wait until the model finishes simulation to continue.
%
%% Explore Received Data Handling Results
% The scopes provided in the model show the signal values from the messages received inside and outside the function-call subsystem as they are unpacked. The following views show the scopes after the model finishes simulation. Note these differences:
% Inside function-call subsystem: 4-6 messages with increasing signal values are received at every sample time. As such, all CAN messages from the replay were individually received, triggered to the subsystem, and processed by the CAN Unpack block inside the subsystem per sample time.
% Outside function-call subsystem: One message with a jump in signal value is received at every sample time. As such, only the latest CAN message from the replay per sample time was provided to and processed by the CAN Unpack block. The other intermediate messages are not processed.
%
%
% Using the exported model signal values from the output port of the CAN Unpack blocks, a plot compares both cases. The function used to plot the results, is included with this example and configured to execute in the Stop Function callback of the model, so that it is executed when the model stops simulation.
% The CAN message transmission occurred periodically every 100 ms, while the CAN Receive block sampled at 500 ms. So, in every sample there are 4-6 CAN messages. The following conclusions can be drawn from these waveforms:
%% Case 1: Unpacking the CAN messages using function trigger (inside function-call subsystem) unpacks all the messages received in each sample.
% Multiple signal values are observed at each sample time.
% The linearly increasing value of the signals indicates that all the messages in every sample time are unpacked.
% No data is suppressed this way, as the function-call subsystem is triggered for each message received and unpacking is done inside it.
%% Case 2: Unpacking the CAN messages without using function trigger (outside function-call subsystem) unpacks only the latest message in each sample.
% Only one signal value is observed at each sample time.
% Therefore only one CAN message is unpacked at each sample time.
% Only the latest message in the sample is unpacked at each sample time.
% All other messages, except the latest one, are suppressed in each sample.
% In summary, the function trigger port of the CAN Receive block is used to unpack all the messages received every sample time. If not used, then only the latest message is unpacked in each sample time. Choose the model behavior based on the requirement of your system and data processing needs.
% Copyright 2021 The MathWorks, Inc.