Guy and Seth on Simulink

Using Discrete Data as an input to your Simulink model 3

Posted by Guy Rouleau,

Today I want to look at a problem that often frustrates Simulink users who have discrete inputs to their model.

The Problem

I create a simple model with just an Inport block connected directly to an Outport block, both configured to execute at a sample time of 0.001 second.

Simplest Possible Model

I configure the model to import data from the workspace:

Configuring a model to Imprt data from workspace

I simulate the model and compare the input with the output using this code:

ts = 0.001;
t = (0:ts:10)';
u = (1:length(t))';
simOut = sim('exampleModel');
stem(abs(u-simOut.get('y').signals.values))

For some samples, the output does not match the input.

Comparing input and Output

The explanation

To understand what is happening here, it is important to compare the time vector of the input data and the time vector used by Simulink.

Comparing time vectors

As we can see in this image, the steps taken by the Simulink solver are different from the ones specified in the input time vector. As explained in technical solution 1-1ITHX9, Simulink computes time using the following equation:

time = stepSize * [0:N]'

While these two methods look similar, they can give different results due to floating point round-off. As you can image, if the input data is slightly behind or before the step taken by the solver, a data point can be skipped or repeated.

The Solution

To avoid such problem, it is recommended to NOT provide the time vector when inputting discrete data into a simulation. For example, modifying the code to use a structure without time will allow the Inport to take the next sample from the vector at each step. Here is some code to create a signal structure without time, update the model to use this structure, and verify that the input and output are equal.

inputStruct.time = [];
inputStruct.signals.dimensions = 1;
inputStruct.signals.values = u;
set_param('exampleModel','ExternalInput','inputStruct')
simOut = sim('exampleModel');
norm(u-simOut.get('y').signals.values)

ans =

0

Now it's your turn

Look at the doc section Guidelines for Specifying Time and Signal Values for Imported Data for more details more this topic.

Let us know how you import data into your models by leaving a comment here.

3 CommentsOldest to Newest

While this solution works for a simple situation like this, often I am faced with a more complex scenario.

* A model which executes at a given sample rate, say 0.01 seconds.
* Data recorded at a slower sample rate, say 0.1 seconds.

I need to run a simulation using the data I have which requires me to provide time along with the input signals since it differs from the sample rate of the model itself.

I need a mechanism to provide a reasonable set of input data and have Simulink use it appropriately, perhaps through some rounding of the time vector to the nearest model sample time.

@Guy, I’m guessing this post not apply to importation of time series objects? Could you comment on this?
@Ross, there are numerous solutions to your situation. Why not read in the data at your sampled rate, then pass the input through a Simulink rate conversion block, specifying linear interpolation etcettera? It goes without saying that I presume your external input data is sampled at a rate slower than the base rate.
If you have variable sampling times, outliers, bad data or other nasties, I would strongly suggest pre-processing your data in ‘tstool’ then saving to the working directory as a timeseries file in MAT -v7.3 format. Now you can use file import block instead of your normal inport block. However this is getting a bit off track from the ethos of the original post.

Add A Comment

What is 6 + 8?

Preview: hide

These postings are the author's and don't necessarily represent the opinions of MathWorks.