## Documentation Center |

Calculate robust stability margins of uncertain multivariable system

[stabmarg,destabunc,report,info] = robuststab(sys) [stabmarg,destabunc,report,info] = robuststab(sys,opt)

A nominally stable uncertain system is generally unstable for
specific values of its uncertain elements. Determining the values
of the uncertain elements closest to their nominal values for which
instability occurs is a *robust stability* calculation.

If the uncertain system is stable for all values of uncertain
elements within their allowable ranges (ranges for `ureal`,
norm bound or positive-real constraint for `ultidyn`,
radius for `ucomplex`, weighted ball for `ucomplexm`),
the uncertain system is *robustly stable*. Conversely,
if there is a combination of element values that cause instability,
and all lie within their allowable ranges, then the uncertain system
is not robustly stable.

`robuststab` computes the margin of stability
robustness for an uncertain system. A stability robustness margin
greater than 1 means that the uncertain system is stable for all values
of its modeled uncertainty. A stability robustness margin less than
1 implies that certain allowable values of the uncertain elements,
within their specified ranges, lead to instability.

Numerically, a margin of 0.5 (for example) implies two things:
the uncertain system remains stable for all values of uncertain elements
that are less than 0.5 normalized units away from their nominal values
and, there is a collection of uncertain elements that are less than
or equal to 0.5 normalized units away from their nominal values that
results in instability. Similarly, a margin of 1.3 implies that the
uncertain system remains stable for all values of uncertain elements
up to 30% outside their modeled uncertain ranges. See `actual2normalized` for
converting between actual and normalized deviations from the nominal
value of an uncertain element.

As with other *uncertain-system* analysis
tools, only bounds on the exact stability margin are computed. The
exact robust stability margin is guaranteed to lie in between these
upper and lower bounds.

The computation used in `robuststab` is a frequency-domain
calculation, which determines whether poles can migrate (due to variability
of the uncertain atoms) across the stability boundary (imaginary axis
for continuous-time, unit circle for discrete-time). Coupled with
stability of the nominal system, determining that no migration occurs
constitutes robust stability. If the input system `sys` is
a `ufrd`, then the analysis is performed on the frequency
grid within the `ufrd`. Note that the stability of
the nominal system is not verified by the computation. If the input
system sys is a `uss`, then the stability of the
nominal system is first checked, an appropriate frequency grid is
generated (automatically), and the analysis performed on that frequency
grid. In all discussion that follows, *N* denotes the number of points in the
frequency grid.

Suppose `sys` is a `ufrd` or `uss` with *M* uncertain
elements. The results of

[stabmarg,destabunc,Report] = robuststab(sys)

are that `stabmarg` is a structure with the
following fields

`destabunc` is
a structure of values of uncertain elements, closest to
nominal, that cause instability. There are *M* field
names, which are the names of uncertain elements of `sys`.
The value of each field is the corresponding value of the uncertain
element, such that when jointly combined, lead to instability. The
command `pole(usubs(sys,destabunc))` shows the instability.
If `A` is
an uncertain element of sys, then

actual2normalized(destabunc.A,sys.Uncertainty.A)

will be less than or equal to `UpperBound`,
and for at least one uncertain element of `sys`,
this normalized distance will be equal to `UpperBound`,
proving that `UpperBound` is indeed an upper bound
on the robust stability margin.

`Report` is a text description of the arguments returned by `robuststab`.

If `sys` is
an array of uncertain models, the outputs are struct arrays whose
entries correspond to each model in the array.

Construct a feedback loop with a second-order plant and a PID
controller with approximate differentiation. The second-order plant
has frequency-dependent uncertainty, in the form of additive unmodeled
dynamics, introduced with an `ultidyn` object and
a shaping filter.

`robuststab` is used to compute the stability
margins of the closed-loop system with respect to the plant model
uncertainty.

P = tf(4,[1 .8 4]); delta = ultidyn('delta',[1 1],'SampleStateDim',5); Pu = P + 0.25*tf([1],[.15 1])*delta; C = tf([1 1],[.1 1]) + tf(2,[1 0]); S = feedback(1,Pu*C); [stabmarg,destabunc,report,info] = robuststab(S);

You can view the `stabmarg` variable.

stabmarg stabmarg = UpperBound: 0.8181 LowerBound: 0.8181 DestabilizingFrequency: 9.1321

As the margin is less than 1, the closed-loop system is not
stable for plant models covered by the uncertain model `Pu`.
There is a specific plant within the uncertain behavior modeled by `Pu` (actually
about 82% of the modeled uncertainty) that leads to closed-loop instability,
with the poles migrating across the stability boundary at 9.1 rads/s.

The `report` variable is specific, giving a
plain-language version of the conclusion.

report report = Uncertain System is NOT robustly stable to modeled uncertainty. -- It can tolerate up to 81.8% of modeled uncertainty. -- A destabilizing combination of 81.8% the modeled uncertainty exists, causing an instability at 9.13 rad/s. -- Sensitivity with respect to uncertain element ... 'delta' is 100%. Increasing 'delta' by 25% leads to a 25% decrease in the margin.

Because the problem has only one uncertain element, the stability margin is completely determined by this element, and hence the margin exhibits 100% sensitivity to this uncertain element.

You can verify that the destabilizing value of `delta` is
indeed about 0.82 normalized units from its nominal value.

actual2normalized(S.Uncertainty.delta,destabunc.delta) ans = 0.8181

Use `usubs` to substitute the specific value
into the closed-loop system. Verify that there is a closed-loop pole
near `j9.1`, and plot the unit-step response of the
nominal closed-loop system, as well as the unstable closed-loop system.

Sbad = usubs(S,destabunc); pole(Sbad) ans = 1.0e+002 * -3.2318 -0.2539 -0.0000 + 0.0913i -0.0000 - 0.0913i -0.0203 + 0.0211i -0.0203 - 0.0211i -0.0106 + 0.0116i -0.0106 - 0.0116i step(S.NominalValue,'r--',Sbad,'g',4);

Finally, as an ad-hoc test, set the gain bound on the uncertain `delta` to
0.81 (slightly less than the stability margin). Sample the closed-loop
system at 100 values, and compute the poles of all these systems.

S.Uncertainty.delta.Bound = 0.81; S100 = usample(S,100); p100 = pole(S100); max(real(p100(:))) ans = -6.4647e-007

As expected, all poles have negative real parts.

A fourth output argument yields more specialized information, including sensitivities and frequency-by-frequency information.

[StabMarg,Destabunc,Report,Info] = robuststab(sys)

In addition to the first 3 output arguments, described previously, `Info` is
a structure with the following fields

Use `robuststabOptions` to
specify additional options for the `robuststab` computation.
For example, you can control what is displayed during the computation,
turning the sensitivity computation on or off, set the step-size in
the sensitivity computation, or control the option argument used in
the underlying call to `mussv`. For instance, you
can turn the display on, and the sensitivity calculation off by executing

opt = robuststabOptions('Sensitivity','off','Display','on'); [StabMarg,Destabunc,Report,Info] = robuststab(sys,opt)

See the `robuststabOptions` reference
page for more information about available options.

Under most conditions, the robust stability margin at each frequency is a continuous function of the problem data at that frequency. Because the problem data, in turn, is a continuous function of frequency, it follows that finite frequency grids are usually adequate in correctly assessing robust stability bounds, assuming the frequency grid is dense enough.

Nevertheless, there are simple examples that violate this. In
some problems, the migration of poles from stable to unstable *only* occurs
at a finite collection of specific frequencies (generally unknown
to you). Any frequency grid that excludes these critical frequencies
(and almost every grid will exclude them) will result in undetected
migration and misleading results, namely stability margins of *∞*.

See Getting Reliable Estimates of Robustness MarginsGetting Reliable Estimates of Robustness Margins for more information about circumventing the problem in an engineering-relevant fashion.

`loopmargin` | `mussv` | `robustperf` | `robuststabOptions` | `wcgain` | `wcmargin` | `wcsens`

Was this topic helpful?