Overview
This tutorial shows how to use the root locus design method for DC motor position control. This tutorial uses LabVIEW 8.2 with LabVIEW Control Design Toolkit.
These tutorials are based on the Control Tutorials developed by Professor Dawn Tilbury of the Mechanical Engineering department at the University of Michigan and Professor Bill Messner of the Department of Mechanical Engineering at Carnegie Mellon University and were developed with their permission.
Table of Contents
From the main problem, the dynamic equations in transfer function form are the following:
![]()
![]()

and the system schematic looks like:

For the original problem setup and the derivation of the above equations, please refer to the Modeling DC Motor Position page.
With a 1 rad/sec step reference, the design criteria are:
- Settling time less than 0.04 seconds
- Overshoot less than 16%
- No steady-state error to a reference
- No steady-state error due to a disturbance
Now let's design a controller using the root locus method.
Open the MathScript Window (Tools >> MathScript Window) and click on the Script tab to view the Script Editor. Type the following commands in the Script Editor:
J=3.2284E-6;
b=3.5077E-6;
K=0.0274;
R=4;
L=2.75E-6;
num=K;
den=[(J*L) ((J*R)+(L*b)) ((b*R)+K^2) 0];
motor=tf(num,den);
Drawing the Open-Loop Root Locus
The main idea of root locus design is to find the closed-loop response from the open-loop root locus plot. Then by adding zeros and/or poles to the original plant, the closed-loop response will be modified.
Let's first view the root locus for the plant. Add the following commands to your MathScript code in the Script Editor:
rlocus(motor)
sgrid on
Now, run your script by clicking on the button with a green arrow at the top of the Script Editor. You should see the root locus plot below:

Figure 1: Root Locus - P Control
If you look at the axis scales on this plot, one open-loop pole is very far to the left (further than -1x10^6). This pole does not affect the closed loop dynamics unless very large gains are used, where the system becomes unstable. We will ignore this pole by doing a model reduction.
Model Reduction
If you have a transfer function which has one (or more) poles to the far left of the dominant poles, you can neglect these poles and the closed-loop response for small gains will not be affected (for large gains, these poles will push the root locus to the right-half plane, causing instability).
The correct way to neglect these poles, keeping the DC gain of the transfer function constant, is as follows:

Let's see what the poles of the original transfer function are. Enter the following command in the Command Window (bottom left corner of the MathScript Window):
roots(den)
You should see the following output:
ans =
0
-59.226
-1.4545e+006
We want to neglect the pole at -1.45e6. This can be translated into MathScript code. Replace your code in the Script Editor with the following:
J=3.2284E-6;
b=3.5077E-6;
K=0.0274;
R=4;
L=2.75E-6;
num=K;
den=[(J*L) ((J*R)+(L*b)) ((b*R)+K^2) 0];
poles=roots(den);
den2=deconv(den,[1/max(abs(poles)) 1]);
motor=tf(num,den2);
Run this script. You can now check that the other poles have not been affected by entering the following code in the Command Window:
roots(den2)
Now we can draw the root locus of the reduced system. Add the following commands to the end of your code in the Script Editor and re-run it.
rlocus(motor)
sgrid on
axis([-400 100 -200 200])
You should obtain the following plot in which you can see that the closed-loop system will be stable for small gains:

Figure 2: Root Locus - P Control
We can see from this plot that the closed-loop poles are never fast enough to meet the settling time requirement (that is, they never move to the left of the sigma=100 vertical line). Also, recall that we need an integrator in the controller (not just in the system) to remove steady-state error due to a disturbance.
Integral Control
Now, let's try using integral control to remove steady-state error to a disturbance. Replace your code in the Script Editor with the following:
J=3.2284E-6;
b=3.5077E-6;
K=0.0274;
R=4;
L=2.75E-6;
num=K;
den=[(J*L) ((J*R)+(L*b)) ((b*R)+K^2) 0];
poles=roots(den);
den2=deconv(den,[1/max(abs(poles)) 1]);
motor=tf(num,den2);
contr=tf(1,[1 0]);
rlocus(contr*motor)
sgrid on
axis([-400 100 -200 200])
Note that this adds a 1/s term to the forward loop. Run this script, and you should see the following plot:

Figure 3: Root Locus - I Control
From this root locus, we can see that the closed-loop system under integral control is never stable, and another controller must be used.
Proportional and Integral Control
Now, let's modify the integral controller to a PI controller. Using PI instead of I control adds a zero to the open-loop system. We'll place this zero at s=-20. The zero must lie between the open-loop poles of the system in this case so that the closed-loop will be stable.
Change the line defining the controller in your script to the following.
contr=tf([1 20],[1 0]);
Re-run your script, and you should see the following plot:

Figure 4: Root Locus - PI Control
Now, we have managed to stabilize the system with zero steady-state error to a disturbance, but the system will still not be fast enough.
Proportional, Integral, and Derivative Control
In order to pull the root locus further to the left, to make it faster, we need to place a second open-loop zero, resulting in a PID controller. After some experimentation, we can place the two PID zeros at s=-60 and s=-70.
Change the line defining the controller in your script to the following:
numc=conv([1 60],[1 70]);
denc=[1 0];
contr=tf(numc,denc);
Re-run your script, and you should obtain the following plot.

Figure 5: Root Locus - PID Control
Now, we can see that two of the closed-loop poles loop around well within both the settling time and percent overshoot requirements. The third closed-loop pole moves from the open-loop pole at s=-59.2 to the open loop zero at s=-60. This closed-loop pole nearly cancels with the zero (which remains in the closed loop transfer function) because it is so close. Therefore, we can ignore its effect.
However, the other open-loop zero also remains in the closed-loop, and will affect the response, slowing it down, and adding overshoot. Therefore, we have to be conservative in picking where on the root locus we want the closed-loop poles to lie.
Finding the Gain
If you recall, we need the settling time and the overshoot to be as small as possible, particularly because of the effect of the extra zero. Large damping corresponds to points on the root locus near the real axis. A fast response corresponds to points on the root locus far to the left of the imaginary axis.
To find the gain corresponding to a point on the root locus, we can use the rlocfind command. We can find the gain and plot the step response using this gain all at once.
To do this, enter the following command in the Command Window:
[k,poles] = rlocfind(contr*motor)
A window titled Interactive Root Locus should appear. In this window, drag either the Gain slider or the red x marks, so that the roots on the loop end up close to the real axis, as shown below. This will ensure that the response will be as fast as possible with as little overshoot as possible. These pole locations would indicate that the response would have almost no overshoot, but you must remember that the zero will add some overshoot.

Figure 6: Interactive Root Locus Window
When you are satisfied with the pole locations you have chosen, click OK. After doing this, you should see the following output in the Output Window section of the MathScript Window.
k =
0.13263
poles =
-140.53 - 9.4686i
-140.53 + 9.4686i
-59.576 + 0i
Note that the values returned in your MathScript Output Window may not be exactly the same, but should at least have the same order of magnitude.
Next, add the following code to the end of your script, and run it.
sys_cl=feedback(k*contr*motor,1);
t=0:0.001:.1;
step(sys_cl,t)
You should get the following step response plot:

Figure 7: Response to Step Input with PID
As you can see, the system has an overshoot of approximately 15%, a settling time of approximately 0.04 seconds, and no steady-state error.
Let's now look at the disturbance response by computing the closed-loop disturbance transfer function and plotting its step response. Add the following lines to the end of your script:
dist_cl=feedback(motor,k*contr);
step(dist_cl,t)
Re-run your script, and you should get the following plot:

Figure 8: Response to Step Disturbance with PID
You can see that the response to a step disturbance reaches a steady-state value of zero, and in fact, stays within 0.02 (or 2%) after 0.04 seconds. Therefore, all the design requirements have been met.
In this example, we placed zeros on the root locus to shape it the way we wanted. While some trial-and error is necessary to place the zeros, it is helpful to understand how the root locus is drawn, and LabVIEW MathScript is used to verify and refine the placement.
Reader Comments | Submit a comment »
Legal
This tutorial (this "tutorial") was developed by National Instruments ("NI"). Although technical support of this tutorial may be made available by National Instruments, the content in this tutorial may not be completely tested and verified, and NI does not guarantee its quality in any way or that NI will continue to support this content with each new revision of related products and drivers. THIS TUTORIAL IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND AND SUBJECT TO CERTAIN RESTRICTIONS AS MORE SPECIFICALLY SET FORTH IN NI.COM'S TERMS OF USE (http://ni.com/legal/termsofuse/unitedstates/us/).
