I understand the error message from frestimate in MATLAB Simulink can be
confusing, especially when it refers to io(1) and in. Let’s clarify what these
terms mean and how to identify them in your Simulink model, particularly in the
context of PID tuning. I’ll keep it straightforward and guide you step-by-step to
resolve the sample time issue.
Clarifying io(1) and in
• in: This is the input signal used by frestimate to excite the system for
frequency response estimation. It’s typically a test signal, such as a sine
wave, chirp signal, or another waveform generated by a block like a Sine
Wave, Chirp Signal, or Signal Builder block in your Simulink model.
The in argument is passed to the frestimate function and has a specific
sample time (e.g., continuous with Ts = 0 or discrete with Ts = 0.01).
• io(1): This refers to the first linearization input/output (I/O) point
defined in the io array, which you pass to frestimate. The io array
specifies the points in your Simulink model where inputs and outputs are
measured for linearization (e.g., the input to a PID controller or the output
of a plant). Each entry in io is created using the linio function, and
io(1) is the first entry in this array.
The error indicates that the signal at the location of io(1) (e.g., a specific
block or signal line in your model) has a sample time that doesn’t match the
requirements: it must be either continuous (or fixed in minor time step) or have
the same sample time as in.
Steps to Identify io(1) and in
Here’s how to find and fix the issue in your Simulink model:
1. Identify the Input Signal in
• What is in?: In your MATLAB script or command, in is the input signal
you defined for frestimate. It’s typically created using a function like
frest.sinestream or frest.Chirp. For example:
• in = frest.sinestream('Frequency', logspace(0,2,50), 'Amplitude',
0.1);
This creates a sine wave signal with a specific sample time.
• Check the Sample Time of in:
– If you created in programmatically, check its sample time using:
– disp(in.Ts);
∗ Ts = 0 means continuous.
∗ Ts = 0.01 (or another value) means discrete with that sample
period.
– If in is generated by a Simulink block (e.g., a Sine Wave block), locate
the block in your model:
1
∗ Open your Simulink model.
∗ Find the block generating the input signal (e.g., Sine Wave,
Chirp Signal, or Signal Builder).
∗ Right-click the block, select Block Parameters, and check the
Sample Time field.
∗ Alternatively, enable Sample Time Display in Simulink:
· Go to Display > Sample Time > All (or press Ctrl+J).
· The block and its output signal will be color-coded (e.g.,
red for continuous, black for discrete with the sample time
shown).
• Example: If in is from a Sine Wave block with Sample Time set to
0.01, then in has a discrete sample time of 0.01 seconds.
2. Identify io(1)
• What is io(1)?: The io array is a list of linearization I/O points defined
using the linio function. For example:
• io = [linio('modelname/PID Controller/1', 1, 'openloop');
... % Input to PID Controller
linio('modelname/Plant/1', 2, 'openloop')]; % Output of
Plant
Here, io(1) is the first entry, which corresponds to the input to the PID
Controller block (port 1, type = input).
• Locate io(1) in Your Code:
– Look at your MATLAB script where you defined the io array.
– The first entry, io(1), will look something like:
– io(1) = linio('modelname/blockname/portnumber', type,
'openloop');
∗ modelname: The name of your Simulink model (e.g., 'myModel').
∗ blockname: The path to the block in the model (e.g., 'PID
Controller', 'Plant', or a subsystem like 'Subsystem1/In1').
∗ portnumber: The port number of the block (e.g., 1 for the first
input or output).
∗ type: 1 for an input point, 2 for an output point.
– Example: If io(1) = linio('myModel/PID Controller/1', 1),
then io(1) refers to the input signal to the PID Controller block.
• Locate io(1) in Your Simulink Model:
– Open your Simulink model (e.g., myModel.slx).
– Navigate to the block specified in io(1) (e.g., the PID Controller
block or an Inport block).
– The signal at io(1) is the signal connected to the specified port of
that block. For example:
∗ If io(1) is the input to the PID Controller, it’s the signal
feeding into the controller (e.g., the error signal from a summing
2
junction).
∗ If io(1) is an Inport block, it’s the signal connected to that
Inport.
3. Check the Sample Time of the Signal at io(1)
• In Simulink, go to the block associated with io(1) (e.g., the PID Con-
troller or an Inport).
• Check the sample time of the signal connected to the specified port:
– Enable Sample Time Display (Display > Sample Time > All).
– The signal line connected to the block will show its sample time (e.g.,
[0.01] for discrete or red color for continuous).
– Alternatively, right-click the block, select Block Parameters, and
check the Sample Time field (if applicable).
• Trace the signal to its source if necessary. For example, if io(1) is the
input to the PID Controller, check the block generating that input signal
(e.g., a Sum block or Inport).
• Compare the sample time of the signal at io(1) with the sample time of
in:
– They must match (e.g., both 0.01 for discrete or both 0 for continu-
ous).
– Alternatively, the signal at io(1) can be continuous (or fixed in minor
time step) if in is continuous.
4. Fix the Sample Time Mismatch The error occurs because the sample
time of the signal at io(1) doesn’t satisfy the requirements. Here’s how to fix it:
Option 1: Make the Signal at io(1) Continuous
• If in is continuous (Ts = 0) or you want to work in continuous time
(common for PID tuning), set the signal at io(1) to continuous:
– Go to the block associated with io(1) (e.g., PID Controller, Inport,
or a block feeding the signal).
– Set the Sample Time to 0 (continuous) or -1 (inherited, which will
resolve to continuous if the system is continuous).
– For a PID Controller block:
∗ Open the block parameters.
∗ Set Time Domain to Continuous-time.
– For an Inport or Outport block:
∗ Set Sample Time to 0.
– For other blocks (e.g., Gain, Transfer Fcn), ensure they are config-
ured for continuous time (usually the default).
• If the signal at io(1) is driven by another block (e.g., a Sum block),
ensure all upstream blocks are continuous.
Option 2: Match the Sample Time of io(1) to in
3
• If in is discrete (e.g., Ts = 0.01), set the signal at io(1) to the same
sample time:
– Go to the block associated with io(1).
– Set its Sample Time to match in (e.g., 0.01).
– For a PID Controller block:
∗ Set Time Domain to Discrete-time and Sample Time to
0.01.
– For an Inport or Outport block:
∗ Set Sample Time to 0.01.
– Ensure upstream blocks (e.g., a Sum block feeding the PID Controller)
have the same sample time.
Option 3: Adjust the Sample Time of in
• If you cannot change the sample time of the signal at io(1) (e.g., due to
model constraints), modify the sample time of in to match io(1):
– If in is generated by a Simulink block (e.g., Sine Wave):
∗ Open the block parameters.
∗ Set Sample Time to match the sample time of the signal at
io(1) (e.g., 0 for continuous or 0.02 for discrete).
– If in is created programmatically (e.g., frest.sinestream):
∗ Modify the sample time when creating in. For example:
∗ in = frest.sinestream('Frequency', logspace(0,2,50),
'Amplitude', 0.1, 'Ts', 0.02);
Here, set 'Ts' to match the sample time of io(1).
5. Verify Model Solver Settings
• Ensure the Simulink model’s solver supports the desired sample times:
– Go to Configuration Parameters (Ctrl+E).
– Under Solver:
∗ For continuous signals, use a Variable-step solver (e.g., ode45)
or a Fixed-step solver with a small step size (e.g., 0.001) and
set blocks to continuous (0).
∗ For discrete signals, use a Fixed-step solver and set the Fixed-
step size to match the sample time (e.g., 0.01).
• Check for blocks like Rate Transition or Zero-Order Hold that might
introduce sample time mismatches. Remove or adjust them if they affect
io(1) or in.
6. Example for PID Tuning Since you’re working with PID tuning, let’s
assume a typical Simulink model with:
• A Sine Wave block generating the input signal in.
• A PID Controller block controlling a Plant (e.g., a Transfer Fcn
block).
• A Sum block computing the error signal (reference minus plant output).
4
Suppose your frestimate call looks like:
modelname = 'myModel';
io = [linio('myModel/PID Controller/1', 1, 'openloop'); ... %
Input to PID
linio('myModel/Plant/1', 2, 'openloop')]; % Output of Plant
in = frest.sinestream('Frequency', logspace(0,2,50), 'Amplitude',
0.1, 'Ts', 0.01);
op = operpoint(modelname);
sys = frestimate(modelname, op, io, in);
• Identify in: The input signal is the sine stream with Ts = 0.01 (discrete).
If it’s from a Sine Wave block in the model, check that block’s Sample
Time (e.g., 0.01).
• Identify io(1): Here, io(1) is the input to the PID Controller block
(the error signal from the Sum block).
• Check Sample Times:
– Go to the PID Controller block in Simulink.
– Check the Time Domain and Sample Time. If it’s set to
Continuous-time, the signal is continuous (Ts = 0), which
mismatches with in (Ts = 0.01).
– Check the Sum block or Inport feeding the PID Controller to confirm
its sample time.
• Fix the Mismatch:
– Option 1: Set the PID Controller to Discrete-time with Sample
Time = 0.01 to match in.
– Option 2: Set the Sine Wave block (or in) to continuous (Ts = 0)
to match the PID Controller.
– Option 3: Ensure all blocks in the signal path (e.g., Sum, Inport)
have matching sample times (e.g., 0.01).
7. Re-run frestimate
• After adjusting the sample times, re-run:
• sys = frestimate(modelname, op, io, in);
• If successful, use the result for PID tuning:
• pid_controller = pidtune(sys, 'PID');
8. Debugging Tips
• Sample Time Display: Use Display > Sample Time > All to visually
confirm sample times. The signal at io(1) and in should have the same
color (e.g., both red for continuous or both black with the same sample
time).
5
• Trace the Signal Path: If io(1) is an input to a block, trace the signal
back to its source (e.g., a Sum block, Inport, or other block) to find
where the sample time is set.
• Check for Rate Transitions: Blocks like Rate Transition or Zero-
Order Hold can cause sample time mismatches. Look for these in the
signal path to io(1).
• Model Explorer: Use the Simulink Model Explorer to inspect block
properties and sample times systematically.
Example Fix
Suppose:
• in is a sine stream with Ts = 0.01 (discrete).
• io(1) is the input to the PID Controller, but the PID Controller is set
to Continuous-time.
Solution:
1. Open the PID Controller block in Simulink.
2. Set Time Domain to Discrete-time and Sample Time to 0.01.
3. Check the Sum block feeding the PID Controller. Set its Sample Time
to 0.01 if needed.
4. Re-run frestimate.
Alternatively, if you want to keep the PID Controller continuous:
1. Modify in to be continuous:
• in = frest.sinestream('Frequency', logspace(0,2,50), 'Amplitude',
0.1, 'Ts', 0);
2. Or, if in is from a Sine Wave block, set its Sample Time to 0.
Final Answer
• in: The input signal for frestimate, typically a sine or chirp signal (check
its Ts property or the Sample Time of the generating block, e.g., Sine
Wave).
• io(1): The first linearization I/O point in the io array, defined via linio
(e.g., the input to the PID Controller or an Inport). Locate it by
checking your io definition and finding the corresponding block/port in
Simulink.
• Fix the Error: Ensure the signal at io(1) has the same sample time as
in (e.g., both 0.01 for discrete or 0 for continuous). Adjust the Sample
Time of the block at io(1) (e.g., PID Controller, Inport) or in (e.g.,
Sine Wave block). Use Sample Time Display to verify. For PID tuning,
set the PID Controller to the same time domain as in (continuous or
discrete). Re-run frestimate after adjustments.
6
If you share your io definition or model details, I can help pinpoint the exact
blocks to check!