Fundamentals of Linear Control
Mauricio de Oliveira
Supplemental material for Chapter 1
Before You Start
In this script you will mostly be plotting data and performing basic calculations. The following MATLAB commands will be used:
- load, to import data saved in a file;
- plot, to produce a two-dimensional graph of the data;
- fit, to fit a model to the data;
- /, to solve a least-squares problem;
- fsolve, to numerically solve a nonlinear algebraic equation.
You will also use the following auxiliary commands to make plots look prettier:
- figure,title, xlabel, ylabel, xlim, ylim, grid, legend
and
- round, to round up numbers;
- linspace, to create a vector with evenly spaced numbers in a interval;
- @, to declare a function on the fly;
- num2str, to convert numbers to strings;
- printmat, to print a matrix with row and columns labels.
In some calculations you will use a basic for loop;
1.1 Models and Experiments
Start by reading a file containing data of the terminal velocity of a car travelling in a straight line in response to changes in the pedal excursion:
% load data for static car model
load CarModel
then plot using MATLAB's plot:
% Fig. 1.4:
figure()
plot(us, vs, 'x')
xlabel('pedal excursion (in)')
ylabel('velocity (mph)')
ylim([0 120])
grid
Perform a simple least-square nonlinear model fitting using MATLAB's fit:
% perform a nonlinear least-square fit
f = fit(us', vs', 'alpha*atan(beta*x)', 'StartPoint', [80,1])
% round to one digit
alpha = round(f.alpha,1)
beta = round(f.beta,1)
and plot the resulting curve plot along with the data:
% plot fitted data
u = linspace(0,3,100);
v = alpha*atan(beta*u);
% Fig. 1.5:
figure()
plot(u, v, '-', us, vs, 'x');
xlabel('pedal excursion (in)')
ylabel('velocity (mph)')
title(['y = ' num2str(alpha,3) ' atan(' num2str(beta,2) ' u)'])
ylim([0 120])
grid
Next perform a linear least-square fit using the slash operator (/):
% perform a linear fit
g1 = vs / us;
g1 = round(g1,1) % round to one digit
One could also have used MATLAB's fit for that:
f = fit(us', vs', 'gamma*x', 'StartPoint', 10)
round(f.gamma,1)
Calculate also a linear model by linearizing the model obtained above about the origin:
% linearized nonlinear model
g2 = alpha*beta;
g2 = round(g2,1) % round to one digit
We plot both models along with the data and the nonlinear model:
% Fig. 1.6:
figure()
plot(u, v, '-', u, g1*u, '--', u, g2*u, '--', us, vs, 'x');
xlabel('pedal excursion (in)')
ylabel('velocity (mph)')
ylim([0 120])
title(['y = ' num2str(alpha,3) ' atan(' num2str(beta,2) ' u), ' ...
'y = ' num2str(g1,3) ' u, ' ...
'y = ' num2str(g2,4) ' u ' ...
])
grid
1.5 Solution with Feedback
Calculate the closed-loop gains:
for the two linear models obtained above, g1 and g2, and also by picking up a third linear coefficient between those two values:
% pick extra point in the middle
g3 = 73.3
Store the closed-loop transfer-functions in an array:
% build table of closed loop gains
ks = [0.02 0.05 0.5 1 3];
ks = [0.02 0.05 1 3];
mat = [
g1 * ks ./ ( 1 + g1 * ks);
g3 * ks ./ ( 1 + g3 * ks);
g2 * ks ./ ( 1 + g2 * ks);
];
% Table 1.1:
printmat(mat, 'Table 1.1', num2str([g1,g3,g2]), num2str(ks))
Calculate the nonlinear closed-loop gains using MATLAB's fsolve to solve the nonlinear equation:
for the value of y. For one value of this can be done as follows:
k = 0.05;
ybar = 60;
f = @(y) y - alpha*atan(beta*k*(ybar-y)); % @ creates function on the fly
y0 = ybar; % initial guess
fsolve(f, y0)
Repeat for various values of :
% closed loop nonlinear gains
u = linspace(0,3,100);
ybars = 40 : 5 : 100;
i = 1;
H = [];
for k = ks
l = 1;
for ybar = ybars
f = @(y) y - alpha*atan(beta*k*(ybar-y));
H(i,l) = fsolve(f, ybar, optimoptions('fsolve','Display','off')) / ybar;
l = l + 1;
end
i = i + 1;
end
and plot the result as a function of the reference :
% Fig. 1.9:
figure()
plot(ybars, H, [40 100], [1 1], 'k--')
xlabel('velocity (mph)')
ylabel('velocity/target')
leg = [char(ones(4, 1) * double('K = ')) num2str(ks','%3.2f') char(ones(4, 1)) * ' '];
legend(leg, 'Location', 'SouthWest');
ylim([0.5 1.02])
grid