Chapter 21: Loop Shaping and Servo Design

Lesson 5: Servo System Design Case Studies Using Loop Shaping

This lesson applies the loop-shaping philosophy developed in previous lessons to concrete servo system designs. We work through case studies for position control of a servo axis, formulate frequency-domain specifications, and synthesize controllers using integral and lead/lag elements. We then implement the resulting controllers in Python, C++, Java, MATLAB/Simulink, and Wolfram Mathematica, emphasizing connections to robotic motion control.

1. Servo Loop Shaping Overview

We consider a standard unity-feedback servo configuration with plant \( P(s) \) and controller \( C(s) \). The open-loop transfer function is \( L(s) = C(s)\,P(s) \). The closed-loop transfer function from reference \( r(t) \) to output \( y(t) \) is

\[ T(s) = \frac{Y(s)}{R(s)} = \frac{C(s)P(s)}{1 + C(s)P(s)} = \frac{L(s)}{1 + L(s)}. \]

The error signal \( e(t) = r(t) - y(t) \) has Laplace transform

\[ E(s) = \frac{1}{1 + C(s)P(s)}\,R(s) = \frac{1}{1 + L(s)}\,R(s). \]

Loop shaping means selecting the magnitude and phase of \( L(j\omega) \) over frequency so that:

  • low frequencies: large \( |L(j\omega)| \) for accurate tracking,
  • around crossover: appropriate phase for stability and transient behavior,
  • high frequencies: small \( |L(j\omega)| \) to attenuate noise and protect actuators.

In servo systems (e.g., robot joint position control), specifications are usually expressed as bounds on steady-state error, rise time, overshoot, and bandwidth, which we map into desired loop shapes.

flowchart TD
  A["Plant model P(s)"] --> B["Initial open-loop L(s) = C(s) P(s)"]
  B --> C["Specify servo targets: bandwidth, overshoot, error"]
  C --> D["Shape low freq: add integrator(s) for tracking"]
  D --> E["Shape mid freq: lead/lag to meet phase margin"]
  E --> F["Shape high freq: roll-off to limit noise/actuator effort"]
  F --> G["Check time response: step/ramp, disturbance"]
  G --> H["Adjust design iteratively and re-validate"]
        

2. Frequency-Domain Servo Specifications

For unity feedback, the static position error constant is

\[ K_p = \lim_{s \to 0} C(s)P(s), \]

and the steady-state error for a unit step is

\[ e_{\text{ss, step}} = \lim_{t \to \infty} e(t) = \lim_{s \to 0} s\,E(s) = \frac{1}{1 + K_p}. \]

For ramp tracking, the velocity error constant is

\[ K_v = \lim_{s \to 0} s\,C(s)P(s), \]

and the steady-state error for unit ramp input is \( e_{\text{ss, ramp}} = 1 / K_v \) (when the limit exists and is finite).

From earlier chapters, a dominant second-order approximation with natural frequency \( \omega_n \) and damping ratio \( \zeta \) has

\[ M_p \approx \exp\!\left( -\frac{\pi \zeta}{\sqrt{1 - \zeta^2}} \right),\qquad T_s(\text{2%}) \approx \frac{4}{\zeta\,\omega_n}, \]

where \( M_p \) is the step overshoot and \( T_s \) is the 2% settling time. In loop-shaping practice, the closed-loop bandwidth \( \omega_b \) is often chosen so that \( \omega_b \approx \omega_n \), and a phase margin around \( 45^\circ \)\( 60^\circ \) yields acceptable damping for many servo applications.

Hence a typical specification set for a servo axis might be:

  • Tracking: \( e_{\text{ss, step}} \) negligible, ramp error bounded.
  • Dynamics: \( M_p \leq 10\% \), \( T_s \leq 0.5 \) s.
  • Bandwidth: \( \omega_b \) around a few tens of rad/s.
  • Robustness: adequate phase and gain margins.

In the case studies below, we translate such specifications into explicit loop shapes and controller parameters.

3. Case Study 1 — Position Servo with PI + Lead

Consider a rotary position servo axis driven by a DC motor with reduction gearing. A widely used linearized model (after suitable scaling) is

\[ P_1(s) = \frac{1}{s(s + 1)}, \]

which is a second-order plant with one integrator (position is the integral of velocity). We assume unity feedback and want to design \( C_1(s) \) for:

  • zero steady-state error to step reference,
  • \( M_p \approx 10\% \) and \( T_s \approx 0.8 \) s,
  • phase margin around \( 55^\circ \).

We choose a PI plus phase-lead controller

\[ C_1(s) = K_c \underbrace{\frac{s + z_i}{s}}_{\text{integral action}} \underbrace{\frac{s + z_\ell}{s + p_\ell}}_{\text{lead network}}, \]

with controller parameters \( K_c \), \( z_i > 0 \), and \( 0 < p_\ell < z_\ell \). The integral term ensures effective low-frequency gain (improving steady-state tracking), while the lead network provides phase advance near the crossover frequency to meet transient and robustness specifications.

4. Analytical Loop-Shaping Design for Case Study 1

4.1. Selecting target bandwidth and damping

From the settling-time relation \( T_s \approx 4 / (\zeta\,\omega_n) \), we can select \( \zeta \approx 0.6 \) (corresponding roughly to \( M_p \approx 10\% \)) and solve

\[ \omega_n \approx \frac{4}{\zeta\,T_s} \approx \frac{4}{0.6 \cdot 0.8} \approx 8.3\ \text{rad/s}. \]

We therefore target a loop crossover frequency \( \omega_c \approx 8 \) rad/s, so that the closed-loop bandwidth is in the desired range.

4.2. Integral zero placement

To maintain phase at crossover, the integral zero \( z_i \) is placed at a lower frequency, typically one decade below \( \omega_c \), e.g.

\[ z_i \approx \frac{\omega_c}{10} \approx 0.8\ \text{rad/s}. \]

This preserves high low-frequency gain for tracking while avoiding excessive phase lag at \( \omega_c \).

4.3. Lead network synthesis

A standard phase-lead element has the form

\[ C_\ell(s) = \frac{s + z_\ell}{s + p_\ell} = \frac{T s + 1}{\alpha T s + 1}, \quad 0 < \alpha < 1,\quad z_\ell = \frac{1}{T},\quad p_\ell = \frac{1}{\alpha T}. \]

Its maximum phase lead is

\[ \phi_{\max} = \sin^{-1}\!\left(\frac{1 - \alpha}{1 + \alpha}\right), \]

which occurs at frequency \( \omega_m = 1 / (T\sqrt{\alpha}) \). To support the desired phase margin, we first compute the approximate phase of the plant with PI at \( \omega_c \), then choose \( \phi_{\max} \) such that

\[ \phi_{\text{margin}} \approx 180^\circ + \angle L(j\omega_c) \approx 55^\circ. \]

This yields the required phase contribution from the lead network. After choosing a convenient \( \alpha \) (e.g., \( \alpha = 0.2 \) for relatively strong lead), we set \( \omega_m \approx \omega_c \) and solve for \( T \), hence for \( z_\ell \) and \( p_\ell \).

4.4. Gain selection from the magnitude condition

With structural choices fixed, the overall open-loop transfer function is

\[ L_1(s) = C_1(s) P_1(s) = K_c\,\frac{s + z_i}{s}\,\frac{s + z_\ell}{s + p_\ell}\, \frac{1}{s(s + 1)}. \]

The crossover condition is \( |L_1(j\omega_c)| = 1 \), which gives

\[ K_c = \frac{1}{ \left| \dfrac{j\omega_c + z_i}{j\omega_c} \right| \left| \dfrac{j\omega_c + z_\ell}{j\omega_c + p_\ell} \right| \left| \dfrac{1}{j\omega_c(j\omega_c + 1)} \right| }. \]

In practice, this is evaluated numerically (e.g., using Bode plots) and then fine-tuned by simulation. The resulting \( C_1(s) \) is a classical servo controller combining integral action and lead compensation.

5. Software Implementations for Case Study 1

We now implement the controller \( C_1(s) \) for the plant \( P_1(s) = 1/(s(s+1)) \) in several environments. Numerical values are chosen for illustration, e.g. \( z_i = 0.8 \), \( z_\ell = 6 \), \( p_\ell = 1.5 \), and \( K_c = 12 \).

5.1 Python (with python-control and robotics context)


import numpy as np
import control as ctrl   # python-control library
# In robotics, see also: roboticstoolbox-python for multi-joint models.

# Plant P1(s) = 1 / (s (s + 1))
s = ctrl.tf([1, 0], [1])        # Laplace variable s
P1 = 1 / (s * (s + 1))

# Controller parameters (example numbers)
Kc  = 12.0
zi  = 0.8    # integral zero
zl  = 6.0    # lead zero
pl  = 1.5    # lead pole

Ci = (s + zi) / s               # PI part
Cl = (s + zl) / (s + pl)        # lead part
C1 = Kc * Ci * Cl

L1 = C1 * P1                    # open loop
T1 = ctrl.feedback(L1, 1)       # closed loop from r to y

# Bode plot and margins
omega = np.logspace(-2, 2, 400)
mag, phase, wout = ctrl.bode(L1, omega, Plot=False)
gm, pm, wgc, wpc = ctrl.margin(L1)
print("Gain margin:", gm, "Phase margin:", pm, "deg")

# Step response
t, y = ctrl.step_response(T1)
import matplotlib.pyplot as plt
plt.figure()
plt.plot(t, y)
plt.xlabel("t [s]")
plt.ylabel("position")
plt.title("Servo step response with loop-shaped PI+lead")
plt.grid(True)
plt.show()
      

5.2 C++ (discrete-time controller core, robotics-style loop)

In a robotic servo drive, the controller runs in a fixed-period loop (e.g. inside a ros_control controller with Eigen-based state representation). Below is a simplified discrete-time implementation of the same PI+lead law.


#include <iostream>
#include <cmath>

// Simple discrete-time PI + lead controller for one servo axis.
class ServoController {
public:
    ServoController(double Kc, double zi, double zl, double pl, double Ts)
        : Kc_(Kc), zi_(zi), zl_(zl), pl_(pl), Ts_(Ts),
          x_int_(0.0), x_lead_(0.0) {}

    // One control step: r = reference, y = measured position
    double step(double r, double y) {
        double e = r - y;

        // Integral state update (backward Euler approximation)
        x_int_ += Ts_ * zi_ * e;

        // Lead filter (first-order, bilinear-style discretization)
        double a = 1.0 + pl_ * Ts_;
        double b = zl_ * Ts_;
        double u_lead = (b * e + x_lead_) / a;
        x_lead_ = b * e + (1.0 - pl_ * Ts_) * x_lead_;

        // Control output
        double u = Kc_ * (e + x_int_ + u_lead);
        return u;
    }

private:
    double Kc_, zi_, zl_, pl_, Ts_;
    double x_int_;
    double x_lead_;
};

int main() {
    double Ts = 0.001;  // 1 kHz servo loop
    ServoController ctrl(12.0, 0.8, 6.0, 1.5, Ts);

    double r = 1.0;     // unit position step
    double y = 0.0;     // measured position (here a dummy)
    for (int k = 0; k < 5000; ++k) {
        double u = ctrl.step(r, y);
        // In a real robot, send u to motor drive and read updated y.
        // Here we just print u occasionally:
        if (k % 1000 == 0) {
            std::cout << "k = " << k << ", u = " << u << std::endl;
        }
    }
    return 0;
}
      

5.3 Java (core control law for a servo thread)


public class ServoController {
    private final double Kc;
    private final double zi;
    private final double zl;
    private final double pl;
    private final double Ts;

    private double xInt = 0.0;
    private double xLead = 0.0;

    public ServoController(double Kc, double zi, double zl, double pl, double Ts) {
        this.Kc = Kc;
        this.zi = zi;
        this.zl = zl;
        this.pl = pl;
        this.Ts = Ts;
    }

    // One iteration of the control loop
    public double step(double r, double y) {
        double e = r - y;

        // Integrator
        xInt += Ts * zi * e;

        // Lead filter
        double a = 1.0 + pl * Ts;
        double b = zl * Ts;
        double uLead = (b * e + xLead) / a;
        xLead = b * e + (1.0 - pl * Ts) * xLead;

        // Control signal
        return Kc * (e + xInt + uLead);
    }
}
      

In a robotics Java stack (e.g., using ROSJava), this controller would be wrapped in a periodic task that reads joint positions and writes actuator commands at a fixed sample time \( T_s \).

5.4 MATLAB/Simulink (with Control System and Robotics System Toolboxes)


% Plant and controller (continuous time)
s  = tf('s');
P1 = 1 / (s * (s + 1));

Kc = 12;
zi = 0.8;
zl = 6;
pl = 1.5;

Ci = (s + zi) / s;
Cl = (s + zl) / (s + pl);
C1 = Kc * Ci * Cl;

L1 = C1 * P1;
T1 = feedback(L1, 1);

figure;
margin(L1); grid on;
title('Loop-shaped open-loop for position servo');

figure;
step(T1);
grid on;
title('Closed-loop step response for position servo');

% In Simulink, place blocks for P1, Ci, Cl and connect them
% in feedback; use "To Workspace" blocks to compare with this script.
      

In robotic applications (e.g., with Robotics System Toolbox and Simscape Multibody), T1 often represents an inner joint servo loop inside a larger multibody simulation.

5.5 Wolfram Mathematica


(* Plant and PI+lead controller *)
s = LaplaceTransformVariable[];
P1 = TransferFunctionModel[1/(s (s + 1)), s];

Kc = 12; zi = 0.8; zl = 6; pl = 1.5;
Ci = TransferFunctionModel[(s + zi)/s, s];
Cl = TransferFunctionModel[(s + zl)/(s + pl), s];
C1 = Kc Ci Cl;

L1 = SeriesConnection[C1, P1];
T1 = FeedbackConnect[L1, 1];

BodePlot[L1, {0.01, 100},
  PlotLabel -> "Open-loop L1(j omega)"];

StepResponsePlot[T1, {0, 5},
  PlotLabel -> "Closed-loop step response"];
      

6. Case Study 2 — High-Bandwidth Servo with Noise Constraints

Consider a lighter, faster actuator (e.g., a small robot joint or galvanometer) approximated by

\[ P_2(s) = \frac{1}{0.2 s^2 + 0.4 s + 1}, \]

which already has reasonable damping. Suppose we want higher bandwidth for fast tracking, but sensor noise is significant. The design goals now include:

  • closed-loop bandwidth around \( 30 \)\( 40 \) rad/s,
  • no more than modest overshoot,
  • attenuation of measurement noise above, say, \( 100 \) rad/s.

A typical loop shape is obtained by:

  1. adding a single integrator to reduce steady-state error,
  2. using modest lead to achieve the desired phase margin at the new crossover,
  3. adding an extra high-frequency pole (or a low-pass filter) in \( C_2(s) \) so that \( |L_2(j\omega)| \) decays quickly for large \( \omega \), reducing noise amplification.

Denoting the resulting controller by

\[ C_2(s) = K_c\,\frac{s + z_i}{s}\,\frac{s + z_\ell}{s + p_\ell}\, \frac{1}{1 + s/p_h}, \]

the additional pole at \( p_h \) steepens the high-frequency roll-off of \( L_2(s) = C_2(s)P_2(s) \), at the cost of some phase lag near \( p_h \). Loop-shaping requires balancing these effects to satisfy both noise and robustness constraints. The design procedure is analogous to Case Study 1 but with an explicit high-frequency attenuation requirement.

flowchart TD
  S["Start with P2(s)"] --> B["Choose target omega_c and phase margin"]
  B --> I["Add integrator for low-frequency tracking"]
  I --> L["Add lead to recover phase at omega_c"]
  L --> H["Insert high-frequency pole p_h to limit noise"]
  H --> V["Verify: bandwidth, overshoot, noise gain"]
  V --> ADJ["If specs not met, adjust Kc, z_i, z_l, p_l, p_h"]
        

7. Problems and Solutions

Problem 1 (Gain for specified crossover): For the plant \( P_1(s) = 1/(s(s + 1)) \) and controller \( C(s) = K_c \) (pure gain), find the gain \( K_c \) that yields a crossover frequency \( \omega_c \) satisfying \( |L(j\omega_c)| = 1 \). Evaluate \( K_c \) and the approximate phase margin for \( \omega_c = 4 \) rad/s.

Solution: The open loop is

\[ L(s) = C(s)P_1(s) = \frac{K_c}{s(s + 1)}. \]

The magnitude at \( s = j\omega \) is

\[ |L(j\omega)| = \frac{K_c}{|j\omega(j\omega + 1)|} = \frac{K_c}{\omega\,\sqrt{\omega^2 + 1}}. \]

Setting \( |L(j\omega_c)| = 1 \) gives

\[ K_c = \omega_c\,\sqrt{\omega_c^2 + 1}. \]

For \( \omega_c = 4 \), we obtain \( K_c = 4\sqrt{17} \approx 16.5 \). The phase of \( P_1(j\omega) \) is

\[ \angle P_1(j\omega) = -90^\circ - \arctan(\omega), \]

so at \( \omega_c = 4 \), \( \angle P_1(j\omega_c) \approx -90^\circ - 76^\circ = -166^\circ \) and the corresponding phase margin is approximately \( \phi_m \approx 180^\circ - 166^\circ = 14^\circ \), which is too small for a good servo. This motivates the use of lead compensation.

Problem 2 (Effect of integral action on step error): Consider unity feedback with plant \( P(s) \) having finite static gain and controller \( C(s) = K_c(s + z_i)/s \). Show that the closed-loop system has zero steady-state error for a unit step reference.

Solution: For a unit step input, \( R(s) = 1/s \). The static position error constant is

\[ K_p = \lim_{s \to 0} C(s)P(s) = \lim_{s \to 0} K_c \frac{s + z_i}{s} P(s). \]

Assuming \( P(s) \) has finite nonzero limit at \( s = 0 \), the factor \( (s + z_i)/s \) behaves like \( z_i/s \) near the origin, so \( K_p = \infty \). Hence

\[ e_{\text{ss, step}} = \frac{1}{1 + K_p} = 0. \]

Integral action guarantees zero steady-state error to step for such plants.

Problem 3 (Lead network design from required phase lead): A lead element \( C_\ell(s) = (T s + 1)/(\alpha T s + 1) \) with \( 0 < \alpha < 1 \) is needed to provide an additional phase lead of \( 30^\circ \) at \( \omega_c \). Show how to select \( \alpha \) and \( T \) so that \( \phi_{\max} \approx 30^\circ \) and \( \omega_m \approx \omega_c \).

Solution: From the formula

\[ \phi_{\max} = \sin^{-1}\!\left(\frac{1 - \alpha}{1 + \alpha}\right), \]

we first choose \( \alpha \) to achieve \( \phi_{\max} \approx 30^\circ \). This is done by solving

\[ \sin(30^\circ) = \frac{1 - \alpha}{1 + \alpha}, \]

which yields \( (1 - \alpha)/(1 + \alpha) = 0.5 \) and hence \( \alpha = 1/3 \). The frequency of maximum phase lead is \( \omega_m = 1/(T\sqrt{\alpha}) \). Setting \( \omega_m \approx \omega_c \) implies

\[ T \approx \frac{1}{\omega_c \sqrt{\alpha}} = \frac{1}{\omega_c \sqrt{1/3}}. \]

Once \( T \) is fixed, the zero and pole locations are \( z_\ell = 1/T \) and \( p_\ell = 1/(\alpha T) \), completing the lead design.

Problem 4 (Conceptual design flow for servo loop shaping): Sketch the decision flow from plant modeling to final servo controller validation when using loop shaping.

Solution (conceptual flow):

flowchart TD
  M["Model plant P(s)"] --> SP["Set specs: error, bandwidth, margins"]
  SP --> LT["Propose initial C(s) (PI/PID)"]
  LT --> LS["Shape loop: tune zeros/poles, Kc"]
  LS --> AN["Analyze: Bode, margins, time response"]
  AN --> OK["Specs met?"]
  OK -->|no| ADJ["Adjust design and repeat"]
  OK -->|yes| IMPL["Implement in code / hardware"]
        

8. Summary

In this lesson we applied loop-shaping principles to servo problems. Starting from a plant model and servo specifications in the time and frequency domains, we constructed PI+lead controllers that deliver desired bandwidth, steady-state accuracy, and robustness. We emphasized how integral action shapes the low-frequency loop gain, how lead networks restore phase margin near crossover, and how additional high-frequency poles trade off noise attenuation and robustness. Multi-language implementations showed how these controllers appear in typical robotic software stacks.

9. References

  1. Bode, H.W. (1945). Network Analysis and Feedback Amplifier Design. Van Nostrand, New York.
  2. Horowitz, I.M. (1963). Synthesis of feedback systems with prescribed sensitivity properties. International Journal of Control, 2(1), 1–31.
  3. Horowitz, I.M. (1965). Synthesis of feedback systems by asymptotic loop shaping. International Journal of Control, 1(3), 317–339.
  4. Middleton, R.H., & Goodwin, G.C. (1988). Improved finite word length characteristics in digital control using delta operators. IEEE Transactions on Automatic Control, 33(11), 1046–1054.
  5. Åström, K.J., & Hägglund, T. (1984). Automatic tuning of simple regulators with specifications on phase and amplitude margins. Automatica, 20(5), 645–651.
  6. Stein, G. (2003). Respect the unstable. IEEE Control Systems Magazine, 23(4), 12–25.
  7. McFarlane, D.C., & Glover, K. (1990). Robust controller design using normalized coprime factor plant descriptions. Lecture Notes in Control and Information Sciences, Vol. 138.