Chapter 8: Adaptive Control

Lesson 2: Adaptive Computed-Torque Structure

This lesson develops the mathematical structure of adaptive computed-torque control for rigid robot manipulators. Building on the standard computed-torque (inverse-dynamics) controller from Chapter 3, we exploit the linear-in-parameters property of robot dynamics to introduce a regressor-based adaptive structure that compensates for unknown inertial and gravitational parameters online. Stability-oriented parameter update laws are postponed to Lesson 3, but the control architecture and all underlying equations are developed rigorously here.

1. Dynamic Model and Classical Computed-Torque Recap

We assume the student is familiar with the standard rigid manipulator dynamics from the robotics kinematics and dynamics course:

\[ \mathbf{M}(\mathbf{q}) \ddot{\mathbf{q}} + \mathbf{C}(\mathbf{q},\dot{\mathbf{q}})\dot{\mathbf{q}} + \mathbf{g}(\mathbf{q}) = \boldsymbol{\tau} \]

where \( \mathbf{q} \in \mathbb{R}^n \) is the joint position vector, \( \mathbf{M}(\mathbf{q}) \) is the positive definite inertia matrix, \( \mathbf{C}(\mathbf{q},\dot{\mathbf{q}}) \) collects Coriolis/centrifugal terms, and \( \mathbf{g}(\mathbf{q}) \) is the gravity vector; \( \boldsymbol{\tau} \) is the vector of joint torques.

With perfect model knowledge, classical computed-torque defines an auxiliary (virtual) control \( \mathbf{v} \) and chooses

\[ \boldsymbol{\tau} = \mathbf{M}(\mathbf{q}) \mathbf{v} + \mathbf{C}(\mathbf{q},\dot{\mathbf{q}})\dot{\mathbf{q}} + \mathbf{g}(\mathbf{q}), \]

with tracking error \( \tilde{\mathbf{q}} = \mathbf{q} - \mathbf{q}_d \), \( \dot{\tilde{\mathbf{q}}} = \dot{\mathbf{q}} - \dot{\mathbf{q}}_d \) and

\[ \mathbf{v} = \ddot{\mathbf{q}}_d - \mathbf{K}_D \dot{\tilde{\mathbf{q}}} - \mathbf{K}_P \tilde{\mathbf{q}}, \quad \mathbf{K}_P = \mathbf{K}_P^\top > 0, \; \mathbf{K}_D = \mathbf{K}_D^\top > 0. \]

Substituting into the dynamics yields a linear closed-loop error system which, under perfect modeling, behaves like a stack of stable second-order systems.

flowchart TD
  Qd["Desired trajectory q_d(t), qd_d, qdd_d"] --> ERR["Error tilde_q = q - q_d"]
  Q["Measured q, qd"] --> ERR
  ERR --> V["Virtual input v = qdd_d - K_D * (qd - qd_d) - K_P * (q - q_d)"]
  V --> CT["Inverse dynamics: M(q)*v + C(q,qd)*qd + g(q)"]
  CT --> TAU["Joint torques tau"]
  TAU --> PLANT["Robot dynamics"]
  PLANT --> Q
        

In practice, the true dynamics are not known exactly. The key idea in adaptive computed-torque is to keep the same overall structure, but replace the exact dynamics with an online-estimated model based on a regressor and estimated parameters.

2. Linear-in-Parameters Robot Dynamics (Regressor Form)

A crucial structural property of rigid-body robot dynamics (without flexible links or complex friction models) is linear parametrization: dynamic equations can be written as

\[ \mathbf{M}(\mathbf{q}) \ddot{\mathbf{q}} + \mathbf{C}(\mathbf{q},\dot{\mathbf{q}})\dot{\mathbf{q}} + \mathbf{g}(\mathbf{q}) = \mathbf{Y}(\mathbf{q},\dot{\mathbf{q}},\ddot{\mathbf{q}})\,\boldsymbol{\theta}, \]

where \( \boldsymbol{\theta} \in \mathbb{R}^p \) is a vector of constant but unknown physical parameters (combinations of link masses, inertias, center-of-mass locations, friction coefficients), and \( \mathbf{Y}(\cdot) \in \mathbb{R}^{n \times p} \) is the regressor matrix.

For a given joint position \( \mathbf{q} \), velocity \( \dot{\mathbf{q}} \) and acceleration \( \ddot{\mathbf{q}} \), the torque is a linear function of the constant parameters \( \boldsymbol{\theta} \). This is the foundation for adaptive schemes:

\[ \boldsymbol{\tau} = \mathbf{Y}(\mathbf{q},\dot{\mathbf{q}},\ddot{\mathbf{q}})\,\boldsymbol{\theta}. \]

In model-based control, we use an estimate \( \hat{\boldsymbol{\theta}} \) instead of the true \( \boldsymbol{\theta} \), yielding an estimated torque

\[ \hat{\boldsymbol{\tau}} = \mathbf{Y}(\mathbf{q},\dot{\mathbf{q}},\ddot{\mathbf{q}})\,\hat{\boldsymbol{\theta}}. \]

The goal of adaptive computed-torque is to embed this regressor form into the computed-torque structure in such a way that the tracking error converges, even when \( \boldsymbol{\theta} \) is unknown.

3. Adaptive Computed-Torque Architecture (Slotine–Li Type)

We introduce the classical Slotine–Li adaptive computed-torque structure. Define the tracking error and a filtered (or “sliding”) error

\[ \tilde{\mathbf{q}} = \mathbf{q} - \mathbf{q}_d,\quad \dot{\tilde{\mathbf{q}}} = \dot{\mathbf{q}} - \dot{\mathbf{q}}_d, \]

\[ \mathbf{s} = \dot{\tilde{\mathbf{q}}} + \boldsymbol{\Lambda}\tilde{\mathbf{q}}, \quad \boldsymbol{\Lambda} = \boldsymbol{\Lambda}^\top > 0. \]

The vector \( \mathbf{s} \) plays the role of a filtered error; convergence of \( \mathbf{s} \) to zero implies convergence of \( \tilde{\mathbf{q}} \) and \( \dot{\tilde{\mathbf{q}}} \) to zero under mild conditions.

Define a reference joint acceleration and corresponding “reference” velocity:

\[ \dot{\mathbf{q}}_r = \dot{\mathbf{q}}_d - \boldsymbol{\Lambda}\tilde{\mathbf{q}}, \quad \ddot{\mathbf{q}}_r = \ddot{\mathbf{q}}_d - \boldsymbol{\Lambda}\dot{\tilde{\mathbf{q}}}, \]

so that \( \mathbf{s} = \dot{\mathbf{q}} - \dot{\mathbf{q}}_r \).

The adaptive computed-torque control law is structured as

\[ \boldsymbol{\tau} = \mathbf{Y}(\mathbf{q},\dot{\mathbf{q}},\dot{\mathbf{q}}_r,\ddot{\mathbf{q}}_r)\,\hat{\boldsymbol{\theta}} + \mathbf{K}_D \mathbf{s}, \quad \mathbf{K}_D = \mathbf{K}_D^\top > 0. \]

Here, the regressor \( \mathbf{Y} \) is evaluated at the current joint variables and the reference signals \( \dot{\mathbf{q}}_r, \ddot{\mathbf{q}}_r \), while \( \hat{\boldsymbol{\theta}} \) is the online estimate of the dynamic parameters. The term \( \mathbf{K}_D \mathbf{s} \) contributes damping and robustness to unmodeled effects.

If, hypothetically, \( \hat{\boldsymbol{\theta}} = \boldsymbol{\theta} \), then the closed-loop dynamics in terms of \( \mathbf{s} \) become

\[ \mathbf{M}(\mathbf{q})\dot{\mathbf{s}} + \mathbf{C}(\mathbf{q},\dot{\mathbf{q}})\mathbf{s} + \mathbf{K}_D \mathbf{s} = \mathbf{0}, \]

which is a stable linear-like system in the sense that \( \mathbf{K}_D \) is positive definite and \( \mathbf{M}(\mathbf{q}) \) is positive definite for all \( \mathbf{q} \). In Lesson 3, we design parameter update laws such that the parameter estimation error and the tracking error converge without requiring prior knowledge of \( \boldsymbol{\theta} \).

4. Example: 1-DOF Rotary Joint and Regressor Construction

Consider a simple 1-DOF rotary joint with viscous friction and gravity torque, such as a rotary pendulum:

\[ (I + m \ell_c^2)\,\ddot{q} + b\,\dot{q} + m g \ell_c \cos(q) = \tau. \]

Define the parameter vector

\[ \boldsymbol{\theta} = \begin{bmatrix} \theta_1 \\ \theta_2 \\ \theta_3 \end{bmatrix} = \begin{bmatrix} I + m \ell_c^2 \\ b \\ m g \ell_c \end{bmatrix}. \]

Then the dynamics can be written in regressor form as

\[ \tau = \underbrace{\begin{bmatrix} \ddot{q} & \dot{q} & \cos(q) \end{bmatrix}}_{\mathbf{Y}(q,\dot{q},\ddot{q})} \boldsymbol{\theta}. \]

For adaptive computed-torque, we do not use the actual acceleration \( \ddot{q} \), but the reference acceleration \( \ddot{q}_r \). Using the definition from Section 3:

\[ \mathbf{Y}(q,\dot{q},\dot{q}_r,\ddot{q}_r) = \begin{bmatrix} \ddot{q}_r & \dot{q}_r & \cos(q) \end{bmatrix}. \]

The adaptive control torque becomes

\[ \tau = \mathbf{Y}(q,\dot{q},\dot{q}_r,\ddot{q}_r)\,\hat{\boldsymbol{\theta}} + k_D s, \]

where \( s = \dot{q} - \dot{q}_r \), and \( k_D > 0 \) is a scalar gain. This scalar example is directly generalizable to multi-DOF manipulators using higher-dimensional regressors.

5. Implementation Architecture – Signal Flow

The structure of an adaptive computed-torque controller is illustrated below. Note that the parameter update block is conceptually present but its exact equations will be derived in the next lesson.

flowchart TD
  QD["q_d, qd_d, qdd_d"] --> ERR["tilde_q, tilde_qd"]
  Q["q, qd"] --> ERR
  ERR --> REF["q_r, qrd, qrdd via Lambda-filter"]
  REF --> REG["Regressor Y(q, qd, qrd, qrdd)"]
  THETA["Parameter estimate theta_hat"] --> REG
  REG --> SUMT["Computed torque from Y * theta_hat"]
  SUMT --> PLUS["+ damping K_D * s"]
  Q --> S["s = qd - qrd"]
  S --> PLUS
  PLUS --> TAU["Torque tau"]
  TAU --> PLANT["Robot dynamics"]
  PLANT --> Q
  S --> ADAPT["Parameter update law (next lesson)"]
  ADAPT --> THETA
        

This block-level view is what you would implement in a real-time controller (e.g., in Simulink, C++ or on an embedded target), with the regressor and parameter estimates updated at each control cycle.

6. Python Implementation – 1-DOF Adaptive Computed-Torque

We implement the 1-DOF example in Python using numpy. For multi-DOF robots, one would typically build Y using a robotics dynamics library (e.g. pinocchio, roboticstoolbox-python) and then plug it into the same structure.


import numpy as np

# Controller gains
Lambda = 10.0
k_D = 5.0

# Adaptation gain matrix (diagonal for simplicity)
Gamma = np.diag([5.0, 1.0, 1.0])

def regressor_1dof(q, qd, qrd, qrdd):
    """
    Y(q, qd, qrd, qrdd) for 1-DOF rotary joint.
    Here we approximate qrd by qd_r and qrdd by qdd_r.
    """
    return np.array([[qrdd, qrd, np.cos(q)]])  # shape (1,3)

def reference_signals(q, qd, q_d, qd_d, qdd_d, Lambda):
    tilde_q = q - q_d
    tilde_qd = qd - qd_d
    qrd = qd_d - Lambda * tilde_q      # q_rdot
    qrdd = qdd_d - Lambda * tilde_qd   # q_rddot
    s = qd - qrd
    return qrd, qrdd, s, tilde_q, tilde_qd

def adaptive_ct_step(q, qd, theta_hat, q_d, qd_d, qdd_d, dt):
    # Compute reference quantities
    qrd, qrdd, s, tilde_q, tilde_qd = reference_signals(q, qd, q_d, qd_d, qdd_d, Lambda)

    # Build regressor and torque
    Y = regressor_1dof(q, qd, qrd, qrdd)         # (1,3)
    tau = float(Y @ theta_hat + k_D * s)         # scalar torque

    # Simple gradient adaptation law (detailed Lyapunov design in next lesson)
    # theta_hat_dot = -Gamma @ Y.T * s
    theta_hat_dot = -Gamma @ (Y.T * s)
    theta_hat_next = theta_hat + theta_hat_dot * dt

    return tau, theta_hat_next, s

# Example simulation loop
def simulate_adaptive_ct(T=10.0, dt=0.001):
    n_steps = int(T / dt)
    # True parameters (unknown to controller)
    theta_true = np.array([[2.0, 0.5, 3.0]]).T  # (3,1)

    # Initial estimates
    theta_hat = np.array([[0.5, 0.1, 0.5]]).T

    # State: q, qd
    q = 0.0
    qd = 0.0

    # Desired trajectory: constant 0.5 rad
    def q_des(t):
        return 0.5, 0.0, 0.0  # q_d, qd_d, qdd_d

    qs = []
    qds = []
    qds_d = []
    s_vals = []

    for k in range(n_steps):
        t = k * dt
        q_d, qd_d, qdd_d = q_des(t)

        tau, theta_hat, s = adaptive_ct_step(q, qd, theta_hat, q_d, qd_d, qdd_d, dt)

        # Plant dynamics: tau = theta_true^T * [qdd; qd; cos(q)]
        a, b, c = float(theta_true[0]), float(theta_true[1]), float(theta_true[2])
        # Solve for qdd
        qdd = (tau - b * qd - c * np.cos(q)) / a

        # Integrate with explicit Euler
        qd = qd + qdd * dt
        q = q + qd * dt

        qs.append(q)
        qds.append(qd)
        qds_d.append(q_d)
        s_vals.append(s)

    return np.array(qs), np.array(qds), np.array(qds_d), np.array(s_vals)

if __name__ == "__main__":
    qs, qds, qds_d, s_vals = simulate_adaptive_ct()
    # Plotting can be added with matplotlib if desired.
      

In multi-DOF implementations, theta_hat becomes a vector of dimension equal to the number of base parameters, and Y becomes an (n, p) matrix, but the update structure is identical.

7. C++ Implementation – Class Skeleton with Eigen and RBDL

For C++ implementations, it is natural to rely on established rigid-body dynamics libraries such as RBDL or Pinocchio to compute the regressor or the dynamics terms. Below is a schematic 1-DOF controller using Eigen for small vectors; extending to multi-DOF robots mainly requires using the library's regressor routines.


#include <Eigen/Dense>

class AdaptiveCT1DOF {
public:
    AdaptiveCT1DOF()
        : Lambda_(10.0), kD_(5.0)
    {
        theta_hat_.setZero();
        theta_hat_ << 0.5, 0.1, 0.5; // initial guess
        Gamma_.setZero();
        Gamma_.diagonal() << 5.0, 1.0, 1.0;
    }

    double step(double q, double qd,
                double q_d, double qd_d, double qdd_d,
                double dt)
    {
        double tilde_q  = q - q_d;
        double tilde_qd = qd - qd_d;

        double qrd  = qd_d - Lambda_ * tilde_q;
        double qrdd = qdd_d - Lambda_ * tilde_qd;
        double s    = qd - qrd;

        Eigen::RowVector3d Y;
        Y << qrdd, qrd, std::cos(q);

        double tau = Y * theta_hat_ + kD_ * s;

        Eigen::Vector3d theta_dot = -Gamma_ * (Y.transpose() * s);
        theta_hat_ += theta_dot * dt;

        return tau;
    }

    const Eigen::Vector3d& theta_hat() const { return theta_hat_; }

private:
    double Lambda_;
    double kD_;
    Eigen::Vector3d theta_hat_;
    Eigen::Matrix3d Gamma_;
};
      

In multi-DOF cases with RBDL, Y would be constructed from the model using functions such as a custom regressor builder (often based on the same recursive Newton–Euler algorithm used for dynamics), and theta_hat_ would be a higher-dimensional vector.

8. Java Implementation – Scalar Adaptive Computed-Torque

In Java, we can implement the same 1-DOF structure using basic arrays. For multi-DOF applications, one can use numerical libraries such as EJML or Apache Commons Math for matrix operations and integrate the regressor computation with an external robotics dynamics library or precomputed symbolic expressions.


public class AdaptiveCT1DOF {

    private double lambda = 10.0;
    private double kD = 5.0;

    // theta_hat = [theta1, theta2, theta3]^T
    private double[] thetaHat = {0.5, 0.1, 0.5};
    // Gamma is diagonal
    private double[] gammaDiag = {5.0, 1.0, 1.0};

    public double step(double q, double qd,
                       double q_d, double qd_d, double qdd_d,
                       double dt) {

        double tilde_q  = q - q_d;
        double tilde_qd = qd - qd_d;

        double qrd  = qd_d - lambda * tilde_q;
        double qrdd = qdd_d - lambda * tilde_qd;
        double s    = qd - qrd;

        double[] Y = new double[3];
        Y[0] = qrdd;
        Y[1] = qrd;
        Y[2] = Math.cos(q);

        double tau = Y[0] * thetaHat[0]
                   + Y[1] * thetaHat[1]
                   + Y[2] * thetaHat[2]
                   + kD * s;

        // theta_dot = -Gamma * Y^T * s
        double[] thetaDot = new double[3];
        for (int i = 0; i < 3; ++i) {
            thetaDot[i] = -gammaDiag[i] * Y[i] * s;
            thetaHat[i] += thetaDot[i] * dt;
        }

        return tau;
    }

    public double[] getThetaHat() {
        return thetaHat.clone();
    }
}
      

The same pattern extends to each joint of a multi-DOF manipulator if the regressor is computed appropriately and the parameters correspond to physically consistent dynamic quantities.

9. MATLAB/Simulink Implementation Sketch

MATLAB is particularly convenient for connecting code with Simulink. Below is a script implementing the 1-DOF adaptive computed-torque scheme in continuous time using a simple Euler integration loop. In practice, you would move the core computations into a MATLAB Function block inside Simulink and connect it with integrator and summing blocks.


function adaptive_ct_1dof_sim()
    Lambda = 10.0;
    kD = 5.0;
    Gamma = diag([5.0, 1.0, 1.0]);

    theta_hat = [0.5; 0.1; 0.5];  % initial guess

    % True parameters (unknown to controller)
    theta_true = [2.0; 0.5; 3.0];

    T  = 10.0;
    dt = 1e-3;
    N  = round(T / dt);

    q  = 0.0;
    qd = 0.0;

    qs    = zeros(1, N);
    qds   = zeros(1, N);
    qd_ds = zeros(1, N);

    for k = 1:N
        t = (k - 1) * dt;

        % Desired trajectory: constant position
        q_d   = 0.5;
        qd_d  = 0.0;
        qdd_d = 0.0;

        tilde_q  = q - q_d;
        tilde_qd = qd - qd_d;

        qrd  = qd_d - Lambda * tilde_q;
        qrdd = qdd_d - Lambda * tilde_qd;
        s    = qd - qrd;

        Y = [qrdd, qrd, cos(q)];  % 1x3 row

        tau = Y * theta_hat + kD * s;

        % Plant dynamics: tau = theta_true' * [qdd; qd; cos(q)]
        a = theta_true(1);
        b = theta_true(2);
        c = theta_true(3);

        qdd = (tau - b * qd - c * cos(q)) / a;

        % Integrate
        qd = qd + qdd * dt;
        q  = q  + qd * dt;

        % Parameter update
        theta_dot = -Gamma * (Y.' * s);
        theta_hat = theta_hat + theta_dot * dt;

        qs(k)    = q;
        qds(k)   = qd;
        qd_ds(k) = q_d;
    end

    figure; plot((0:N-1) * dt, qs, 'LineWidth', 1.5); hold on;
    plot((0:N-1) * dt, qd_ds, '--', 'LineWidth', 1.5);
    xlabel('Time [s]'); ylabel('q [rad]');
    legend('q', 'q_d');
    title('Adaptive Computed-Torque Tracking (1-DOF)');
end
      

In Simulink, the architecture follows the block diagram of Section 5: joint measurements feed a subsystem implementing the reference model and regressor, whose output together with the parameter estimates produce \( \tau \), which drives the plant model.

10. Wolfram Mathematica Implementation Sketch

Wolfram Mathematica can symbolically manipulate the regressor and then numerically integrate the closed-loop system. A minimal numeric 1-DOF implementation is sketched below.


(* Parameters *)
Lambda = 10.0;
kD = 5.0;
Gamma = DiagonalMatrix[{5.0, 1.0, 1.0}];

(* True parameters (unknown to controller) *)
thetaTrue = {2.0, 0.5, 3.0};

(* Desired trajectory: constant 0.5 rad *)
qDes[t_] := 0.5;
qdDes[t_] := 0.0;
qddDes[t_] := 0.0;

(* State vector: {q, qd, theta1, theta2, theta3} *)
dynEquations = {
  q'[t] == qd[t],
  qd'[t] == (tau[t] - thetaTrue[[2]]*qd[t] - thetaTrue[[3]]*Cos[q[t]]) / thetaTrue[[1]],
  theta1hat'[t] == -Gamma[[1, 1]]*Y1[t]*s[t],
  theta2hat'[t] == -Gamma[[2, 2]]*Y2[t]*s[t],
  theta3hat'[t] == -Gamma[[3, 3]]*Y3[t]*s[t]
  };

tildeq[t_] := q[t] - qDes[t];
tildeqd[t_] := qd[t] - qdDes[t];

qrd[t_] := qdDes[t] - Lambda*tildeq[t];
qrdd[t_] := qddDes[t] - Lambda*tildeqd[t];
s[t_] := qd[t] - qrd[t];

Y1[t_] := qrdd[t];
Y2[t_] := qrd[t];
Y3[t_] := Cos[q[t]];

tau[t_] := Y1[t]*theta1hat[t] + Y2[t]*theta2hat[t] + Y3[t]*theta3hat[t] + kD*s[t];

ic = {
  q[0] == 0.0,
  qd[0] == 0.0,
  theta1hat[0] == 0.5,
  theta2hat[0] == 0.1,
  theta3hat[0] == 0.5
  };

sol = NDSolve[
  Flatten[{dynEquations, ic}],
  {q, qd, theta1hat, theta2hat, theta3hat},
  {t, 0, 10.0}
  ];

Plot[{q[t] /. sol[[1]], qDes[t]}, {t, 0, 10},
     PlotLegends -> {"q(t)", "q_d(t)"},
     AxesLabel -> {"t", "angle"}]
      

For multi-DOF systems, symbolic generation of the regressor \( \mathbf{Y} \) is particularly attractive in Mathematica, after which the numeric adaptive law is structurally identical.

11. Problems and Solutions

Problem 1 (Regressor Identification in 1-DOF): For the rotary joint dynamics \( (I + m \ell_c^2)\ddot{q} + b\,\dot{q} + m g \ell_c \cos(q) = \tau \), construct the regressor \( \mathbf{Y}(q,\dot{q},\ddot{q}) \) and the parameter vector \( \boldsymbol{\theta} \). Verify that the dynamics are linear in \( \boldsymbol{\theta} \).

Solution: Set

\[ \boldsymbol{\theta} = \begin{bmatrix} \theta_1 \\ \theta_2 \\ \theta_3 \end{bmatrix} = \begin{bmatrix} I + m \ell_c^2 \\ b \\ m g \ell_c \end{bmatrix}. \]

Then rewrite the equation as

\[ \tau = \theta_1 \ddot{q} + \theta_2 \dot{q} + \theta_3 \cos(q) = \underbrace{\begin{bmatrix} \ddot{q} & \dot{q} & \cos(q) \end{bmatrix}}_{\mathbf{Y}(q,\dot{q},\ddot{q})} \boldsymbol{\theta}. \]

The dependence on the unknowns is purely linear, so this model satisfies the linear-in-parameters property.

Problem 2 (Error Coordinates for Adaptive Computed-Torque): Using the definitions \( \tilde{\mathbf{q}} = \mathbf{q} - \mathbf{q}_d \) and \( \mathbf{s} = \dot{\tilde{\mathbf{q}}} + \boldsymbol{\Lambda}\tilde{\mathbf{q}} \), show that \( \mathbf{s} = \dot{\mathbf{q}} - \dot{\mathbf{q}}_r \) where \( \dot{\mathbf{q}}_r = \dot{\mathbf{q}}_d - \boldsymbol{\Lambda}\tilde{\mathbf{q}} \).

Solution: From the definition of \( \dot{\mathbf{q}}_r \), we have

\[ \dot{\mathbf{q}}_r = \dot{\mathbf{q}}_d - \boldsymbol{\Lambda}(\mathbf{q} - \mathbf{q}_d) = \dot{\mathbf{q}}_d - \boldsymbol{\Lambda}\mathbf{q} + \boldsymbol{\Lambda}\mathbf{q}_d. \]

Then

\[ \dot{\mathbf{q}} - \dot{\mathbf{q}}_r = \dot{\mathbf{q}} - \dot{\mathbf{q}}_d + \boldsymbol{\Lambda}(\mathbf{q} - \mathbf{q}_d) = (\dot{\mathbf{q}} - \dot{\mathbf{q}}_d) + \boldsymbol{\Lambda}(\mathbf{q} - \mathbf{q}_d) = \dot{\tilde{\mathbf{q}}} + \boldsymbol{\Lambda}\tilde{\mathbf{q}} = \mathbf{s}. \]

Hence \( \mathbf{s} = \dot{\mathbf{q}} - \dot{\mathbf{q}}_r \) as claimed.

Problem 3 (Nominal Stability of the s-dynamics): Assume \( \hat{\boldsymbol{\theta}} = \boldsymbol{\theta} \), so that the adaptive computed-torque control law yields \( \mathbf{M}(\mathbf{q})\dot{\mathbf{s}} + \mathbf{C}(\mathbf{q},\dot{\mathbf{q}})\mathbf{s} + \mathbf{K}_D\mathbf{s} = \mathbf{0} \). Show that the Lyapunov function \( V(\mathbf{s}) = \tfrac{1}{2}\mathbf{s}^\top \mathbf{M}(\mathbf{q})\mathbf{s} \) has a negative semidefinite derivative.

Solution: Using standard properties of robot dynamics, \( \mathbf{M}(\mathbf{q}) \) is symmetric positive definite, and \( \dot{\mathbf{M}}(\mathbf{q}) - 2\mathbf{C}(\mathbf{q},\dot{\mathbf{q}}) \) is skew-symmetric. Compute

\[ \dot{V} = \tfrac{1}{2}\mathbf{s}^\top \dot{\mathbf{M}}\mathbf{s} + \mathbf{s}^\top \mathbf{M}\dot{\mathbf{s}}. \]

Substitute \( \mathbf{M}\dot{\mathbf{s}} = -\mathbf{C}\mathbf{s} - \mathbf{K}_D\mathbf{s} \):

\[ \dot{V} = \tfrac{1}{2}\mathbf{s}^\top \dot{\mathbf{M}}\mathbf{s} - \mathbf{s}^\top \mathbf{C}\mathbf{s} - \mathbf{s}^\top \mathbf{K}_D\mathbf{s}. \]

Using the skew-symmetry property \( \mathbf{s}^\top(\dot{\mathbf{M}} - 2\mathbf{C})\mathbf{s} = 0 \), we obtain

\[ \dot{V} = - \mathbf{s}^\top \mathbf{K}_D\mathbf{s} \leq 0, \]

since \( \mathbf{K}_D \) is positive definite. Thus the origin \( \mathbf{s} = \mathbf{0} \) is stable in the Lyapunov sense for the nominal case.

Problem 4 (Adaptive Structure vs. Fixed Computed-Torque): Explain qualitatively why a fixed computed-torque controller using a nominal model \( \mathbf{M}_0, \mathbf{C}_0, \mathbf{g}_0 \) may yield poor tracking when the robot payload changes, while the adaptive computed-torque structure can compensate such changes if the regressor is correctly constructed.

Solution: A fixed computed-torque law assumes that the physical parameters (masses, inertias, payload) match the model used in the controller. When the payload changes, the true parameters \( \boldsymbol{\theta} \) no longer match those implicit in \( \mathbf{M}_0, \mathbf{C}_0, \mathbf{g}_0 \), producing steady-state tracking errors or oscillations. In contrast, the adaptive computed-torque structure represents the dynamics as \( \mathbf{Y}(\cdot)\boldsymbol{\theta} \) and maintains an online estimate \( \hat{\boldsymbol{\theta}} \), updated based on the observed filtered error \( \mathbf{s} \). As long as the regressor captures the new payload's effect and sufficient excitation is present, the parameter estimates adapt toward the new physical values, restoring good tracking performance.

12. Summary

In this lesson we introduced the structure of adaptive computed-torque control for robot manipulators. Starting from the standard rigid-body dynamics, we exploited their linear-in-parameters form and defined a regressor \( \mathbf{Y} \) and parameter vector \( \boldsymbol{\theta} \). We then constructed the Slotine–Li type adaptive computed-torque law, using a filtered error \( \mathbf{s} \) and reference signals \( \dot{\mathbf{q}}_r, \ddot{\mathbf{q}}_r \) to shape the closed-loop dynamics. A 1-DOF example made the regressor explicit, and implementations in Python, C++, Java, MATLAB/Simulink, and Wolfram Mathematica illustrated how the same structure can be realized in software. In the next lesson, we complete the theory by deriving parameter update laws and Lyapunov-based stability guarantees.

13. References

  1. Slotine, J.-J. E., & Li, W. (1987). On the adaptive control of robot manipulators. International Journal of Robotics Research, 6(3), 49–59.
  2. Craig, J. J., Hsu, P., & Sastry, S. S. (1986). Adaptive control of mechanical manipulators. International Journal of Robotics Research, 6(2), 16–28.
  3. Ortega, R., Spong, M. W., Gomez-Estern, F., & Blankenstein, G. (2002). Stabilization of a class of underactuated mechanical systems via interconnection and damping assignment. IEEE Transactions on Automatic Control, 47(8), 1218–1233. (Conceptual background on passivity-based designs.)
  4. Ioannou, P. A., & Sun, J. (1996). Robust Adaptive Control. Prentice Hall. (General adaptive control framework, including regressor-based parameter adaptation.)
  5. Kelly, R. (1994). A simple set-point robot controller with prescribed performance. IEEE Transactions on Robotics and Automation, 10(5), 652–657.
  6. Kelly, R., Santibáñez, V., & Loría, A. (2005). Control of Robot Manipulators in Joint Space. Springer. (Chapters on adaptive computed-torque structures.)
  7. Slotine, J.-J. E., & Li, W. (1991). Applied Nonlinear Control. Prentice Hall. (Classic reference for adaptive robot control and Slotine–Li scheme.)