Chapter 1: Control Prerequisites for Robotics

Lesson 1: Review of Feedback Control Concepts

This lesson revisits fundamental feedback control concepts with a focus on robotic manipulators and actuators. We formalize the notions of plant, controller, reference, disturbance, and measurement noise; derive the standard unity-feedback input–output equations; connect first- and second-order models to step responses and tracking error; and sketch how these ideas are realized in digital control loops used in robot joints.

1. Basic Feedback Loop for a Robot Joint

Consider a single revolute joint of a robot, with joint angle \( q(t) \) (in radians) and torque input \( \tau(t) \). At a high level, a feedback control loop is composed of:

  • Reference (command) \( r(t) \): desired joint angle.
  • Sensor: measures \( y(t) \), usually a noisy version of \( q(t) \).
  • Controller: computes control input \( u(t) \) (e.g., torque or motor current command).
  • Plant: the physical joint dynamics mapping \( u(t) \) to \( q(t) \).
  • Disturbances: unmodeled loads, friction, gravity mismatch, etc.

The tracking error is defined as \( e(t) = r(t) - y(t) \). The goal in most robot control problems is to design the controller so that \( e(t) \) becomes small in an appropriate sense (e.g., small steady-state error, fast transients without excessive overshoot, robustness to disturbances).

flowchart TD
  R["Reference r(t)"]
  E["Error e = r - y"]
  C["Controller"]
  U["Control signal u"]
  P["Robot joint (plant)"]
  Y["Output y"]
  D["Disturbances (load, friction)"]

  R --> E
  Y --> E
  E --> C
  C --> U
  U --> P
  D --> P
  P --> Y
  

Throughout this course, we will mostly work with SISO (single-input single-output) models for each controlled variable, even when the underlying robot dynamics are multivariable. Later chapters will reintroduce the full coupled manipulator model.

2. Linear Time-Invariant Models and Transfer Functions

For a single joint around an operating point, we approximate the dynamics as linear and time invariant (LTI). In the time domain, a simple model is

\[ J \ddot{q}(t) + b \dot{q}(t) = u(t), \]

where \( J > 0 \) is the equivalent inertia and \( b \ge 0 \) is viscous friction. Taking Laplace transforms with zero initial conditions gives

\[ (J s^2 + b s) Q(s) = U(s), \]

so the plant transfer function from input torque to joint angle is

\[ G(s) = \frac{Q(s)}{U(s)} = \frac{1}{J s^2 + b s}. \]

More generally, we denote the controller transfer function by \( C(s) \), the sensor transfer function by \( H(s) \), and define the loop transfer function

\[ L(s) = C(s) G(s) H(s). \]

For a standard unity-feedback configuration with reference \( R(s) \) and output \( Y(s) \), the closed-loop relation is

\[ Y(s) = \frac{C(s) G(s)}{1 + C(s) G(s) H(s)} R(s), \]

assuming the reference is injected at the input of the controller and the feedback signal is \( H(s) Y(s) \).

3. Derivation of Closed-Loop Transfer and Sensitivity

We derive the closed-loop transfer function more systematically. Let \( R(s) \), \( E(s) \), \( U(s) \), and \( Y(s) \) be the Laplace transforms of reference, error, control input, and output.

  1. Error relation:

    \[ E(s) = R(s) - H(s) Y(s). \]

  2. Controller relation:

    \[ U(s) = C(s) E(s). \]

  3. Plant relation:

    \[ Y(s) = G(s) U(s). \]

Substitute (2) into (3): \( Y(s) = G(s) C(s) E(s) \). From (1), \( E(s) = R(s) - H(s) Y(s) \), so

\[ Y(s) = G(s) C(s) \bigl( R(s) - H(s) Y(s) \bigr) = G(s) C(s) R(s) - G(s) C(s) H(s) Y(s). \]

Collect terms with \( Y(s) \):

\[ \bigl( 1 + G(s) C(s) H(s) \bigr) Y(s) = G(s) C(s) R(s), \]

hence

\[ \frac{Y(s)}{R(s)} = \frac{G(s) C(s)}{1 + G(s) C(s) H(s)} =: T(s). \]

The complementary sensitivity function is \( T(s) \), and the sensitivity function is

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

where again \( L(s) = C(s) G(s) H(s) \). Note that

\[ S(s) + T(s) H(s) = 1, \]

which expresses a fundamental trade-off: improving disturbance rejection or tracking in one frequency region (reducing \( |S(j\omega)| \)) tends to worsen it in another (because the functions must still sum to 1).

4. First-Order and Second-Order Prototypes

4.1 First-Order System

A common approximation for a controlled joint (after closing a fast inner torque loop) is a first-order system

\[ G_1(s) = \frac{K}{1 + \tau s}, \]

where \( K > 0 \) is a static gain and \( \tau > 0 \) is the time constant. For a unit step input \( R(s) = \frac{1}{s} \) in unity feedback (with \( C(s) = 1 \), \( H(s) = 1 \)), the closed-loop transfer is

\[ T_1(s) = \frac{G_1(s)}{1 + G_1(s)} = \frac{K}{1 + \tau s + K}. \]

In the time domain the response is exponential with effective time constant \( \frac{\tau}{1 + K} \). Larger \( K \) speeds up the response but also amplifies measurement noise and unmodeled dynamics.

4.2 Second-Order System

Position-controlled joints and end-effector axes are often approximated by a second-order model

\[ G_2(s) = \frac{\omega_n^2}{s^2 + 2 \zeta \omega_n s + \omega_n^2}, \]

where \( \omega_n > 0 \) is the natural frequency and \( \zeta \ge 0 \) is the damping ratio. For unity feedback with proportional gain \( K \), the effective closed-loop parameters are modified; for example, simple proportional control yields

\[ T_2(s) = \frac{K G_2(s)}{1 + K G_2(s)}. \]

Analysis of overshoot, settling time, and damping will be treated rigorously in later lessons on performance specifications, but the second-order model already illustrates that joint-level control must balance response speed and oscillatory behavior.

5. Steady-State Error and Final Value Theorem

For a stable closed-loop system, the steady-state error to a given reference input \( r(t) \) is

\[ e_{\text{ss}} = \lim_{t → \infty} e(t), \]

which, by the final value theorem (for poles in the open left half-plane), can be computed as

\[ e_{\text{ss}} = \lim_{s → 0} s E(s). \]

For unity feedback and reference \( R(s) \), we know \( E(s) = S(s) R(s) \), so

\[ e_{\text{ss}} = \lim_{s → 0} s S(s) R(s). \]

For a unit step \( R(s) = \frac{1}{s} \), this reduces to

\[ e_{\text{ss}} = \lim_{s → 0} S(s) = S(0). \]

Thus, for step tracking, the DC value of the sensitivity function directly gives the steady-state error. For a well-designed joint position controller we usually require \( S(0) \approx 0 \), which is achieved by including an integral term in later lessons.

6. Digital Implementation of a Joint Feedback Loop

In robot controllers, feedback is implemented on a digital processor at a fixed sampling period \( T_s \). The abstract continuous loop is realized as:

  • Sample sensor outputs at rate \( 1/T_s \).
  • Compute control law in software (e.g., PID on joint error).
  • Update actuator command via a digital-to-analog or PWM interface.
flowchart TD
  R["Reference r[k]"] --> E["Error e[k] = r[k] - y[k]"]
  E --> C["Digital controller (e.g. PID)"]
  C --> U["Actuator command u[k]"]
  U --> ZH["Zero-order hold"]
  ZH --> P["Joint dynamics (continuous)"]
  P --> SENS["Encoder / sensor"]
  SENS --> A2D["Sampling at Ts"]
  A2D --> Y["Measured output y[k]"]
        

Later chapters on digital control will formalize discretization (\( z \)-domain models) and sampling effects. For now, it is sufficient to understand that the mathematics of continuous-time feedback still guides controller design, but implementation is necessarily discrete.

7. Multi-language Implementations of a Simple Feedback Loop

We now illustrate how a simple first-order plant with proportional control can be simulated in several languages. Consider the continuous-time plant

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

and controller \( C(s) = K_p \) in unity feedback. Below we approximate the closed-loop behavior using a discrete-time Euler integration of the underlying first-order differential equation.

7.1 Python (with NumPy)


import numpy as np
import matplotlib.pyplot as plt

# Parameters
Kp = 5.0       # proportional gain
tau = 0.2      # time constant
Ts = 0.001     # sampling time
T_end = 1.0
n_steps = int(T_end / Ts)

# Preallocate
t = Ts * np.arange(n_steps + 1)
r = np.ones_like(t)   # unit step reference
y = np.zeros_like(t)  # output
u = np.zeros_like(t)  # control

# Discrete-time first-order model: y[k+1] = y[k] + Ts * ( -y[k]/tau + u[k]/tau )
for k in range(n_steps):
    e_k = r[k] - y[k]
    u[k] = Kp * e_k
    dy = (-y[k] + u[k]) / tau
    y[k + 1] = y[k] + Ts * dy

# Plot
plt.figure()
plt.plot(t, r, linestyle="--", label="reference")
plt.plot(t, y, label="output")
plt.xlabel("time (s)")
plt.ylabel("joint position")
plt.legend()
plt.grid(True)
plt.show()
      

Libraries such as python-control and roboticstoolbox for Python provide higher-level interfaces for transfer functions, state-space models, and robot dynamics; here we intentionally implement the loop from scratch to expose the underlying numerical update.

7.2 C++ (typical embedded joint controller structure)


#include <iostream>
#include <vector>

int main() {
    double Kp = 5.0;
    double tau = 0.2;
    double Ts = 0.001;
    double T_end = 1.0;
    int n_steps = static_cast<int>(T_end / Ts);

    std::vector<double> t(n_steps + 1);
    std::vector<double> r(n_steps + 1, 1.0); // step
    std::vector<double> y(n_steps + 1, 0.0);
    std::vector<double> u(n_steps + 1, 0.0);

    for (int k = 0; k <= n_steps; ++k) {
        t[k] = k * Ts;
    }

    for (int k = 0; k < n_steps; ++k) {
        double e = r[k] - y[k];
        u[k] = Kp * e;
        double dy = (-y[k] + u[k]) / tau;
        y[k + 1] = y[k] + Ts * dy;
    }

    // Print a few samples
    for (int k = 0; k < n_steps; k += n_steps / 10) {
        std::cout << "t=" << t[k]
                  << "  r=" << r[k]
                  << "  y=" << y[k] << std::endl;
    }
    return 0;
}
      

In robotics, such C++ loops are often embedded in real-time frameworks (e.g., within a ROS controller_manager component) using linear algebra libraries such as Eigen for higher-dimensional dynamics.

7.3 Java (simulation-only skeleton)


public class JointControlSim {
    public static void main(String[] args) {
        double Kp = 5.0;
        double tau = 0.2;
        double Ts = 0.001;
        double T_end = 1.0;
        int nSteps = (int)(T_end / Ts);

        double[] t = new double[nSteps + 1];
        double[] r = new double[nSteps + 1];
        double[] y = new double[nSteps + 1];
        double[] u = new double[nSteps + 1];

        for (int k = 0; k <= nSteps; ++k) {
            t[k] = k * Ts;
            r[k] = 1.0; // step
            y[k] = 0.0;
            u[k] = 0.0;
        }

        for (int k = 0; k < nSteps; ++k) {
            double e = r[k] - y[k];
            u[k] = Kp * e;
            double dy = (-y[k] + u[k]) / tau;
            y[k + 1] = y[k] + Ts * dy;
        }

        for (int k = 0; k < nSteps; k += nSteps / 10) {
            System.out.println("t=" + t[k] + "  y=" + y[k]);
        }
    }
}
      

Java is less common for low-level joint control but can be used in high-level simulation or middleware applications.

7.4 MATLAB / Simulink


Kp  = 5.0;
tau = 0.2;

Ts     = 1e-3;
T_end  = 1.0;
t      = 0:Ts:T_end;
r      = ones(size(t));
y      = zeros(size(t));
u      = zeros(size(t));

for k = 1:(length(t) - 1)
    e      = r(k) - y(k);
    u(k)   = Kp * e;
    dy     = (-y(k) + u(k)) / tau;
    y(k+1) = y(k) + Ts * dy;
end

plot(t, r, "--", t, y, "LineWidth", 1.5);
xlabel("time (s)");
ylabel("joint position");
legend("reference", "output");
grid on;

% In Simulink, you can instead use a Transfer Fcn block with 1/(tau*s + 1)
% in closed loop with a Gain block (Kp) and a Step input.
      

7.5 Wolfram Mathematica


Kp  = 5.0;
tau = 0.2;

(* Continuous-time closed-loop transfer for unity feedback *)
G[s_]  := 1/(1 + tau*s);
Tcl[s_] := (Kp*G[s])/(1 + Kp*G[s]);

sys = TransferFunctionModel[Tcl[s], s];

(* Step response *)
ResponsePlot[
  {SystemResponse[sys, UnitStep], 1},
  {t, 0, 1},
  PlotLegends -> {"output", "reference"},
  Frame -> True,
  FrameLabel -> {"time (s)", "joint position"}
]
      

Mathematica offers symbolic capabilities that are useful for deriving closed-loop transfer functions and stability conditions analytically.

8. Problems and Solutions

Problem 1 (Unity-Feedback Closed-Loop Transfer):
Consider a plant \( G(s) \) and controller \( C(s) \) with sensor \( H(s) = 1 \) in unity feedback. Derive \( T(s) = \frac{Y(s)}{R(s)} \) and \( S(s) = \frac{E(s)}{R(s)} \).

Solution:

Error: \( E(s) = R(s) - Y(s) \). Controller: \( U(s) = C(s) E(s) \). Plant: \( Y(s) = G(s) U(s) \). Substituting,

\[ Y(s) = G(s) C(s) \bigl( R(s) - Y(s) \bigr) = G(s) C(s) R(s) - G(s) C(s) Y(s). \]

Collecting \( Y(s) \) terms,

\[ \bigl( 1 + G(s) C(s) \bigr) Y(s) = G(s) C(s) R(s), \]

hence

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

The sensitivity function is \( S(s) = \frac{E(s)}{R(s)} = \frac{R(s) - Y(s)}{R(s)} = 1 - T(s) \), so

\[ S(s) = \frac{1}{1 + G(s) C(s)}. \]


Problem 2 (Steady-State Error of First-Order Loop):
For a plant \( G(s) = \frac{1}{1 + \tau s} \) and proportional controller \( C(s) = K_p \) in unity feedback, compute the steady-state error to a unit step reference.

Solution:

Loop transfer: \( L(s) = K_p G(s) = \frac{K_p}{1 + \tau s} \). Sensitivity:

\[ S(s) = \frac{1}{1 + L(s)} = \frac{1 + \tau s}{1 + \tau s + K_p}. \]

For a unit step, \( R(s) = \frac{1}{s} \), so \( E(s) = S(s) R(s) = \frac{1 + \tau s}{s(1 + \tau s + K_p)} \). The steady-state error is

\[ e_{\text{ss}} = \lim_{s → 0} s E(s) = \lim_{s → 0} \frac{1 + \tau s}{1 + \tau s + K_p} = \frac{1}{1 + K_p}. \]

Thus, increasing \( K_p \) reduces the step steady-state error but cannot make it exactly zero without adding integral action.


Problem 3 (Closed-Loop Pole Locations):
Consider the second-order plant \( G(s) = \frac{1}{s^2 + 2 s + 1} \) and proportional controller \( C(s) = K_p \) in unity feedback. Find the characteristic polynomial of the closed-loop system and its poles.

Solution:

Closed-loop transfer:

\[ T(s) = \frac{K_p G(s)}{1 + K_p G(s)} = \frac{K_p}{s^2 + 2 s + 1 + K_p}. \]

The characteristic polynomial is \( s^2 + 2 s + (1 + K_p) \). The poles are

\[ s_{1,2} = -1 \pm \sqrt{1 - (1 + K_p)} = -1 \pm j \sqrt{K_p}. \]

For any \( K_p > 0 \), the real part of both poles is \( -1 \), so the closed-loop system is exponentially stable. Larger \( K_p \) increases oscillation frequency \( \sqrt{K_p} \).


Problem 4 (Effect of Loop Gain on Sensitivity):
Let \( L(s) = K L_0(s) \) for some fixed strictly proper \( L_0(s) \) and scalar gain \( K > 0 \). Show that for low frequencies where \( |K L_0(j\omega)| \gg 1 \), one has approximately \( |S(j\omega)| \approx \frac{1}{K |L_0(j\omega)|} \).

Solution:

Sensitivity is \( S(s) = \frac{1}{1 + K L_0(s)} \), hence in the frequency domain \( S(j\omega) = \frac{1}{1 + K L_0(j\omega)} \). If \( |K L_0(j\omega)| \gg 1 \), then \( 1 + K L_0(j\omega) \approx K L_0(j\omega) \) and

\[ |S(j\omega)| \approx \frac{1}{|K L_0(j\omega)|}. \]

Thus, increasing loop gain reduces sensitivity at frequencies where the magnitude of \( K L_0(j\omega) \) is large, improving tracking and disturbance rejection in that band.


Problem 5 (Discrete Approximation of a First-Order System):
The continuous-time first-order system \( \dot{y}(t) = -\frac{1}{\tau} y(t) + \frac{1}{\tau} u(t) \) is discretized by forward Euler with sampling time \( T_s \). Derive the discrete-time update \( y[k+1] = a y[k] + b u[k] \), and express \( a \), \( b \) in terms of \( \tau \), \( T_s \).

Solution:

Forward Euler gives

\[ y[k+1] = y[k] + T_s \left( -\frac{1}{\tau} y[k] + \frac{1}{\tau} u[k] \right) = \left( 1 - \frac{T_s}{\tau} \right) y[k] + \frac{T_s}{\tau} u[k]. \]

Therefore \( a = 1 - \frac{T_s}{\tau} \), \( b = \frac{T_s}{\tau} \). Stability in discrete time requires \( |a| < 1 \), which yields \( 0 < T_s < 2 \tau \).

9. Summary

In this lesson we established the foundational feedback control structure for robot joints: reference, error, controller, plant, and feedback measurement. We introduced LTI models and transfer functions, derived the standard unity-feedback closed-loop transfer and sensitivity functions, and examined first- and second-order prototypes relevant to robotic motion. We also showed how continuous-time models are implemented in digital controllers and illustrated basic simulation code in Python, C++, Java, MATLAB, and Mathematica. These concepts form the backbone for subsequent lessons on state-space modeling, linearization, stability theory, and performance specifications.

10. References

  1. Nyquist, H. (1932). Regeneration theory. Bell System Technical Journal, 11(1), 126–147.
  2. Bode, H. W. (1945). Network analysis and feedback amplifier design. Van Nostrand.
  3. Zames, G. (1966). On the input-output stability of time-varying nonlinear feedback systems. IEEE Transactions on Automatic Control, 11(2), 228–238.
  4. Kalman, R. E. (1960). Contributions to the theory of optimal control. Boletín de la Sociedad Matemática Mexicana, 5(2), 102–119.
  5. Desoer, C. A., & Vidyasagar, M. (1975). Feedback Systems: Input-Output Properties. Academic Press.
  6. Francis, B. A., & Wonham, W. M. (1975). The internal model principle for linear multivariable regulators. Applied Mathematics and Optimization, 2(2), 170–194.
  7. Doyle, J. C. (1978). Guaranteed margins for LQG regulators. IEEE Transactions on Automatic Control, 23(4), 756–757.
  8. Å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.
  9. Safonov, M. G., Laub, A. J., & Hartmann, G. L. (1981). Feedback properties of multivariable systems: The role and use of the return difference matrix. IEEE Transactions on Automatic Control, 26(1), 47–65.
  10. Zhou, K., Doyle, J. C., & Glover, K. (1996). Robust and Optimal Control. Prentice Hall.