Accelerating the pace of engineering and science

# Robust Control Toolbox

## Robust Control of an Active Suspension

This example shows how to use Robust Control Toolbox™ to design a robust controller for an active suspension system.

Quarter-Car Suspension Model

Conventional passive suspensions use a spring and damper between the car body and wheel assembly. The spring-damper characteristics are selected to emphasize one of several conflicting objectives such as passenger comfort, road handling, and suspension deflection. Active suspensions allow the designer to balance these objectives using a feedback-controller hydraulic actuator between the chassis and wheel assembly.

This example uses a quarter-car model of the active suspension system (see Figure 1). The mass represents the car chassis (body) and the mass represents the wheel assembly. The spring and damper represent the passive spring and shock absorber placed between the car body and the wheel assembly. The spring models the compressibility of the pneumatic tire. The variables , , and are the body travel, wheel travel, and road disturbance, respectively. The force applied between the body and wheel assembly is controlled by feedback and represents the active component of the suspension system.

Figure 1: Quarter-car model of active suspension.

With the notation , the linearized state-space equations for the quarter-car model are:

Construct a state-space model qcar representing these equations.

% Physical parameters
mb = 300;    % kg
mw = 60;     % kg
bs = 1000;   % N/m/s
ks = 16000 ; % N/m
kt = 190000; % N/m

% State matrices
A = [ 0 1 0 0; [-ks -bs ks bs]/mb ; ...
0 0 0 1; [ks bs -ks-kt -bs]/mw];
B = [ 0 0; 0 10000/mb ; 0 0 ; [kt -10000]/mw];
C = [1 0 0 0; 1 0 -1 0; A(2,:)];
D = [0 0; 0 0; B(2,:)];

qcar = ss(A,B,C,D);
qcar.StateName = {'body travel (m)';'body vel (m/s)';...
'wheel travel (m)';'wheel vel (m/s)'};
qcar.InputName = {'r';'fs'};
qcar.OutputName = {'xb';'sd';'ab'};


The transfer function from actuator to body travel and acceleration has an imaginary-axis zero with natural frequency 56.27 rad/s. This is called the tire-hop frequency.

tzero(qcar({'xb','ab'},'fs'))

ans =

-0.0000 +56.2731i
-0.0000 -56.2731i



Similarly, the transfer function from actuator to suspension deflection has an imaginary-axis zero with natural frequency 22.97 rad/s. This is called the rattlespace frequency.

zero(qcar('sd','fs'))

ans =

0.0000 +22.9734i
0.0000 -22.9734i



Road disturbances influence the motion of the car and suspension. Passenger comfort is associated with small body acceleration. The allowable suspension travel is constrained by limits on the actuator displacement. Plot the open-loop gain from road disturbance and actuator force to body acceleration and suspension displacement.

bodemag(qcar({'ab','sd'},'r'),'b',qcar({'ab','sd'},'fs'),'r',{1 100});
title(['Gain from road dist (r) and actuator force (fs) '...
'to body accel (ab) and suspension travel (sd)'])


Because of the imaginary-axis zeros, feedback control cannot improve the response from road disturbance to body acceleration at the tire-hop frequency, and from to suspension deflection at the rattlespace frequency. Moreover, because of the relationship and the fact that the wheel position roughly follows at low frequency (less than 5 rad/s), there is an inherent trade-off between passenger comfort and suspension deflection: any reduction of body travel at low frequency will result in an increase of suspension deflection.

Uncertain Actuator Model

The hydraulic actuator used for active suspension control is connected between the body mass and the wheel assembly mass . The nominal actuator dynamics are represented by the first-order transfer function with a maximum displacement of 0.05 m.

ActNom = tf(1,[1/60 1]);


This nominal model only approximates the physical actuator dynamics. We can use a family of actuator models to account for modeling errors and variability in the actuator and quarter-car models. This family consists of a nominal model with a frequency-dependent amount of uncertainty. At low frequency, below 3 rad/s, the model can vary up to 40% from its nominal value. Around 3 rad/s, the percentage variation starts to increase. The uncertainty crosses 100% at 15 rad/s and reaches 2000% at approximately 1000 rad/s. The weighting function is used to modulate the amount of uncertainty with frequency.

Wunc = makeweight(0.40,15,3);
unc = ultidyn('unc',[1 1],'SampleStateDim',5);
Act = ActNom*(1 + Wunc*unc);
Act.InputName = 'u';
Act.OutputName = 'fs';


The result Act is an uncertain state-space model of the actuator. Plot the Bode response of 20 sample values of Act and compare with the nominal value.

rng('default')
bode(Act,'b',Act.NominalValue,'r+',logspace(-1,3,120))


Design Setup

The main control objectives are formulated in terms of passenger comfort and road handling, which relate to body acceleration and suspension travel . Other factors that influence the control design include the characteristics of the road disturbance, the quality of the sensor measurements for feedback, and the limits on the available control force. To use synthesis algorithms, we must express these objectives as a single cost function to be minimized. This can be done as indicated Figure 2.

Figure 2: Disturbance rejection formulation.

The feedback controller uses measurements of the suspension travel and body acceleration to compute the control signal driving the hydraulic actuator. There are three external sources of disturbance:

• The road disturbance , modeled as a normalized signal shaped by a weighting function . To model broadband road deflections of magnitude seven centimeters, we use the constant weight

• Sensor noise on both measurements, modeled as normalized signals and shaped by weighting functions and . We use and to model broadband sensor noise of intensity 0.01 and 0.5, respectively. In a more realistic design, these weights would be frequency dependent to model the noise spectrum of the displacement and acceleration sensors.

The control objectives can be reinterpreted as a disturbance rejection goal: Minimize the impact of the disturbances on a weighted combination of control effort , suspension travel , and body acceleration . When using the norm (peak gain) to measure "impact", this amounts to designing a controller that minimizes the norm from disturbance inputs to error signals .

Create the weighting functions of Figure 2 and label their I/O channels to facilitate interconnection. Use a high-pass filter for to penalize high-frequency content of the control signal and thus limit the control bandwidth.

Wroad = ss(0.07);  Wroad.u = 'd1';   Wroad.y = 'r';
Wact = 8*tf([1 50],[1 500]);  Wact.u = 'u';  Wact.y = 'e1';
Wd2 = ss(0.01);  Wd2.u = 'd2';   Wd2.y = 'Wd2';
Wd3 = ss(0.5);   Wd3.u = 'd3';   Wd3.y = 'Wd3';


Specify closed-loop targets for the gain from road disturbance to suspension deflection (handling) and body acceleration (comfort). Because of the actuator uncertainty and imaginary-axis zeros, only seek to attenuate disturbances below 10 rad/s.

HandlingTarget = 0.04 * tf([1/8 1],[1/80 1]);
ComfortTarget = 0.4 * tf([1/0.45 1],[1/150 1]);

Targets = [HandlingTarget ; ComfortTarget];
legend('Open-loop','Closed-loop target')


The corresponding performance weights are the reciprocals of these comfort and handling targets. To investigate the trade-off between passenger comfort and road handling, construct three sets of weights corresponding to three different trade-offs: comfort ( ), balanced ( ), and handling ( ).

% Three design points
beta = reshape([0.01 0.5 0.99],[1 1 3]);
Wsd = beta / HandlingTarget;
Wsd.u = 'sd';  Wsd.y = 'e3';
Wab = (1-beta) / ComfortTarget;
Wab.u = 'ab';  Wab.y = 'e2';


Finally, use connect to construct a model qcaric of the block diagram of Figure 2. Note that qcaric is an array of three models, one for each design point . Also, qcaric is an uncertain model since it contains the uncertain actuator model Act.

sdmeas  = sumblk('y1 = sd+Wd2');
abmeas = sumblk('y2 = ab+Wd3');
ICinputs = {'d1';'d2';'d3';'u'};
ICoutputs = {'e1';'e2';'e3';'y1';'y2'};
sdmeas,abmeas,ICinputs,ICoutputs)

qcaric =

3x1 array of uncertain continuous-time state-space models.
Each model has 5 outputs, 4 inputs, 9 states, and the following uncertain blocks:
unc: Uncertain 1x1 LTI, peak gain = 1, 1 occurrences

Type "qcaric.NominalValue" to see the nominal value, "get(qcaric)" to see all properties, and "qcaric.Uncertainty" to interact with the uncertain elements.



Nominal H-infinity Design

Use hinfsyn to compute an controller for each value of the blending factor .

ncont = 1; % one control signal, u
nmeas = 2; % two measurement signals, sd and ab
K = ss(zeros(ncont,nmeas,3));
gamma = zeros(3,1);
for i=1:3
[K(:,:,i),~,gamma(i)] = hinfsyn(qcaric(:,:,i),nmeas,ncont);
end

gamma

gamma =

0.9410
0.6724
0.8877



The three controllers achieve closed-loop norms of 0.94, 0.67 and 0.89, respectively. Construct the corresponding closed-loop models and compare the gains from road disturbance to for the passive and active suspensions. Observe that all three controllers reduce suspension deflection and body acceleration below the rattlespace frequency (23 rad/s).

% Closed-loop models
K.u = {'sd','ab'};  K.y = 'u';
CL = connect(qcar,Act.Nominal,K,'r',{'xb';'sd';'ab'});

bodemag(qcar(:,'r'),'b', CL(:,:,1),'r-.', ...
CL(:,:,2),'m-.', CL(:,:,3),'k-.',{1,140}), grid
legend('Open-loop','Comfort','Balanced','Handling','location','SouthEast')
title('Body travel, suspension deflection, and body acceleration due to road')


Time-Domain Evaluation

To further evaluate the three designs, perform time-domain simulations using a road disturbance signal representing a road bump of height 5 cm.

% Road disturbance
t = 0:0.005:1;

% Closed-loop model
SIMK = connect(qcar,Act.Nominal,K,'r',{'xb';'sd';'ab';'fs'});

% Simulate

% Plot results
subplot(231)
title('Body travel'), ylabel('x_b (m)')
subplot(232)
title('Body acceleration'), ylabel('a_b (m/s^2)')
subplot(234)
title('Suspension deflection'), xlabel('Time (s)'), ylabel('s_d (m)')
subplot(235)
title('Control force'), xlabel('Time (s)'), ylabel('f_s (N)')


Observe that the body acceleration is smallest for the controller emphasizing passenger comfort and largest for the controller emphasizing suspension deflection. The "balanced" design achieves a good compromise between body acceleration and suspension deflection.

Robust Mu Design

So far you have designed controllers that meet the performance objectives for the nominal actuator model. As discussed earlier, this model is only an approximation of the true actuator and you need to make sure that the controller performance is maintained in the face of model errors and uncertainty. This is called robust performance.

Next use -synthesis to design a controller that achieves robust performance for the entire family of actuator models. The robust controller is synthesized with the dksyn function using the uncertain model qcaric(:,:,2) corresponding to "balanced" performance ( ).

[Krob,~,RPmuval] = dksyn(qcaric(:,:,2),nmeas,ncont);

RPmuval

RPmuval =

0.9082



Simulate the nominal response to a road bump with the robust controller Krob. The responses are similar to those obtained with the "balanced" controller.

% Closed-loop model (nominal)
Krob.u = {'sd','ab'};
Krob.y = 'u';
SIMKrob = connect(qcar,Act.Nominal,Krob,'r',{'xb';'sd';'ab';'fs'});

% Simulate

% Plot results
clf, subplot(221)
title('Body travel'), ylabel('x_b (m)')
subplot(222)
plot(t,p1(:,3),'b',t,y1(:,3),'r')
title('Body acceleration'), ylabel('a_b (m/s^2)')
subplot(223)
plot(t,p1(:,2),'b',t,y1(:,2),'r')
title('Suspension deflection'), xlabel('Time (s)'), ylabel('s_d (m)')
subplot(224)
plot(t,zeros(size(t)),'b',t,y1(:,4),'r')
title('Control force'), xlabel('Time (s)'), ylabel('f_s (N)')
legend('Open-loop','Robust design','location','SouthEast')


Next simulate the response to a road bump for 100 actuator models randomly selected from the uncertain model set Act.

rng('default'), nsamp = 100;  clf

% Uncertain closed-loop model with balanced H-infinity controller
CLU = connect(qcar,Act,K(:,:,2),'r',{'xb','sd','ab'});
title('Nominal "balanced" design')
legend('Perturbed','Nominal','location','SouthEast')


% Uncertain closed-loop model with balanced robust controller
CLU = connect(qcar,Act,Krob,'r',{'xb','sd','ab'});
title('Robust "balanced" design')
legend('Perturbed','Nominal','location','SouthEast')


The robust controller Krob reduces variability due to model uncertainty and delivers more consistent performance.

Controller Simplification

The robust controller Krob has eleven states. It is often the case that controllers synthesized with dksyn have high order. You can use the model reduction functions to find a lower-order controller that achieves the same level of robust performance. Use reduce to generate approximations of various orders, and use robustperf to compute the robust performance margin for each reduced-order approximation.

% Create array of reduced-order controllers
NS = order(Krob);
StateOrders = 1:NS;
Kred = reduce(Krob,StateOrders);

% Compute robust performance margin for each reduced controller
CLP = lft(qcaric(:,:,2),Kred);
ropt = robustperfOptions('Sensitivity','off','Display','off','Mussv','a');
PM = robustperf(CLP,ropt);

% Compare robust performance of reduced- and full-order controllers
plot(StateOrders,[PM.LowerBound],'b-o',...
StateOrders,repmat(1/RPmuval,[1 NS]),'r');
title('Robust performance as a function of controller order')
legend('Reduced order','Full order')


There is no significant difference in robust performance between the 8th- and 11th-order controllers so you can safely replace Krob by its 8th-order approximation.

Krob8 = Kred(:,:,8);