Chapter 6: Force and Compliant Interaction Control

Lesson 4: Admittance Control

This lesson develops admittance control as a dual concept to impedance control. We derive the virtual mass–damper–spring dynamics that map measured external forces into compliant end-effector motion, analyze stability using Lyapunov methods, and discuss discrete-time implementation suitable for robot controllers. Practical implementations in Python, C++, Java, MATLAB/Simulink, and Wolfram Mathematica are provided for simulation and integration with existing low-level joint controllers.

1. Conceptual Overview and Impedance–Admittance Duality

In impedance control (previous lesson), the robot behaves like a virtual mechanical impedance that maps motion errors to commanded forces. If \( \mathbf{x}_d \) is the desired task-space pose and \( \mathbf{x} \) the actual pose, the position error \( \mathbf{x}_e = \mathbf{x}_d - \mathbf{x} \) is used to generate a commanded interaction force:

\[ \mathbf{F}_{cmd} = \mathbf{M}_d \ddot{\mathbf{x}}_e + \mathbf{D}_d \dot{\mathbf{x}}_e + \mathbf{K}_d \mathbf{x}_e , \]

where \( \mathbf{M}_d, \mathbf{D}_d, \mathbf{K}_d \) are user-chosen positive-definite matrices shaping apparent inertia, damping, and stiffness.

In admittance control, we invert this viewpoint. We measure an external wrench \( \mathbf{F}_{ext} \) using, for example, a 6-axis force/torque sensor, and compute a virtual motion \( \mathbf{x}_r \) that the low-level position controller must track. The robot then appears as a compliant device whose motion admittance (force → velocity/position) is shaped by our controller.

At a conceptual level:

  • Impedance control: specify virtual \( Z(s) = \frac{\mathbf{F}(s)}{\mathbf{V}(s)} \) (force from motion).
  • Admittance control: specify virtual \( Y(s) = \frac{\mathbf{V}(s)}{\mathbf{F}(s)} = Z(s)^{-1} \) (motion from force).

Admittance control is particularly appropriate for stiff, high-gear-ratio robots interacting with relatively soft environments, where torque-level modulation is difficult but accurate position tracking is readily available.

flowchart TD
  Fext["Measured wrench F_ext"] --> VA["Virtual admittance model (M_a, D_a, K_a)"]
  VA --> Xref["Desired pose x_r"]
  Xref --> IK["Kinematics: x_r to q_r"]
  IK --> Low["Low-level joint position/velocity controller"]
  Low --> Robot["Robot + environment"]
  Robot --> Fext
        

2. Virtual Admittance Dynamics in Task Space

We first consider a single translational degree of freedom along a contact normal, with reference displacement \( x_r(t) \) and measured interaction force \( F_{ext}(t) \). The standard admittance law is a mass–damper–spring:

\[ M_a \ddot{x}_r(t) + D_a \dot{x}_r(t) + K_a \bigl(x_r(t) - x_0\bigr) = F_{ext}(t), \]

where \( M_a > 0 \), \( D_a \ge 0 \), \( K_a \ge 0 \), and \( x_0 \) is the equilibrium position when no force is applied.

In vector form, for an \( m \)-dimensional task variable \( \mathbf{x}_r \in \mathbb{R}^m \) and wrench \( \mathbf{F}_{ext} \in \mathbb{R}^m \):

\[ \mathbf{M}_a \ddot{\mathbf{x}}_r(t) + \mathbf{D}_a \dot{\mathbf{x}}_r(t) + \mathbf{K}_a \bigl(\mathbf{x}_r(t) - \mathbf{x}_0\bigr) = \mathbf{S}_f \mathbf{F}_{ext}(t), \]

where \( \mathbf{M}_a, \mathbf{D}_a, \mathbf{K}_a \in \mathbb{R}^{m\times m} \) are symmetric positive (semi-)definite design matrices and \( \mathbf{S}_f \) is a selection matrix, possibly extracting only the normal force component or mapping a 6D wrench into controlled directions.

Taking Laplace transforms with zero initial conditions, the transfer function from force to displacement is

\[ X_r(s) = \frac{1}{M_a s^2 + D_a s + K_a} F_{ext}(s) + \frac{K_a}{M_a s^2 + D_a s + K_a} x_0 . \]

The mechanical admittance is usually defined as the ratio between velocity and force:

\[ Y(s) = \frac{V_r(s)}{F_{ext}(s)} = \frac{s X_r(s)}{F_{ext}(s)} = \frac{s}{M_a s^2 + D_a s + K_a} . \]

In practice, we implement the time-domain differential equation, integrate it numerically at the controller sampling rate, and treat the resulting \( \mathbf{x}_r(t) \) as the command to a lower-level motion controller.

3. Coupling with Manipulator Dynamics

The joint-space equations of motion for an \( n \)-DOF rigid manipulator (known from the robotics kinematics and dynamics course) are

\[ \mathbf{M(q)} \ddot{\mathbf{q}} + \mathbf{C(q,\dot{\mathbf{q}})} \dot{\mathbf{q}} + \mathbf{g(q)} = \boldsymbol{\tau}_c + \mathbf{J(q)}^\top \mathbf{F}_{ext}, \]

where \( \boldsymbol{\tau}_c \) are commanded joint torques, \( \mathbf{J(q)} \) is the geometric Jacobian, and \( \mathbf{F}_{ext} \) is the contact wrench at the end-effector.

In admittance control, we assume an inner joint-space controller (e.g., PD, PID, or computed-torque, from previous chapters) that tracks a joint reference \( \mathbf{q}_r(t) \) or task reference \( \mathbf{x}_r(t) \) with high bandwidth. Let \( \mathbf{x} = \mathbf{f(q)} \) denote the forward kinematics. For sufficiently fast tracking,

\[ \mathbf{x}(t) \approx \mathbf{x}_r(t), \qquad \dot{\mathbf{x}}(t) \approx \dot{\mathbf{x}}_r(t). \]

Therefore, the human or environment interacting with the robot perceives the virtual admittance:

\[ \mathbf{M}_a \ddot{\mathbf{x}}(t) + \mathbf{D}_a \dot{\mathbf{x}}(t) + \mathbf{K}_a \bigl(\mathbf{x}(t) - \mathbf{x}_0\bigr) \approx \mathbf{S}_f \mathbf{F}_{ext}(t). \]

By suitable choice of \( \mathbf{M}_a, \mathbf{D}_a, \mathbf{K}_a \), we can make the stiff industrial robot behave, from the user's perspective, like a soft and easily moveable device (e.g., a virtual mass on a spring).

4. Stability and Energy Interpretation

Consider again the 1-DOF admittance:

\[ M_a \ddot{x}_r(t) + D_a \dot{x}_r(t) + K_a \bigl(x_r(t) - x_0\bigr) = F_{ext}(t). \]

First analyze the free dynamics with no external force: \( F_{ext}(t) = 0 \). Define the state \( z_1 = x_r - x_0 \), \( z_2 = \dot{x}_r \). Then

\[ \dot{z}_1 = z_2, \qquad \dot{z}_2 = -\frac{D_a}{M_a} z_2 - \frac{K_a}{M_a} z_1 . \]

A natural Lyapunov function candidate is the virtual mechanical energy:

\[ V(z_1,z_2) = \tfrac{1}{2} M_a z_2^2 + \tfrac{1}{2} K_a z_1^2 . \]

Since \( M_a > 0 \), \( K_a \ge 0 \), \( V \) is positive definite in \( (z_1,z_2) \) around the equilibrium \( (0,0) \). Its time derivative along trajectories is

\[ \dot{V} = M_a z_2 \dot{z}_2 + K_a z_1 \dot{z}_1 = z_2 \bigl( M_a \dot{z}_2 + K_a z_1 \bigr) = z_2 \bigl( -D_a z_2 \bigr) = - D_a z_2^2 \le 0 . \]

If \( D_a > 0 \), the set where \( \dot{V} = 0 \) is \( z_2 = 0 \). On that set, the dynamics reduce to \( \dot{z}_1 = 0 \), \( \dot{z}_2 = -(K_a/M_a) z_1 \), which implies \( z_1 = 0 \) at any invariant point. Thus the only largest invariant set is the origin \( (z_1,z_2) = (0,0) \), and by LaSalle's invariance principle (introduced in Chapter 1) the equilibrium is globally asymptotically stable.

With external forces included, the energy rate becomes

\[ \dot{V} = \dot{x}_r F_{ext} - D_a \dot{x}_r^2 . \]

The virtual system absorbs energy proportionally to \( D_a \dot{x}_r^2 \), and the time integral of \( \dot{x}_r F_{ext} \) is the work done by the environment. This energy balance underlies passivity-type arguments used in more advanced stability analyses of human–robot interaction.

5. Discrete-Time Implementation

Let \( T_s \) be the control sampling period, and denote discrete-time signals by \( x_r[k] \approx x_r(k T_s) \) and \( F_{ext}[k] \approx F_{ext}(k T_s) \). Introduce the state variables \( z_1[k] = x_r[k] - x_0 \), \( z_2[k] = \dot{x}_r[k] \).

Using a forward-Euler approximation:

\[ \dot{x}_r(t) \approx \frac{x_r[k+1] - x_r[k]}{T_s}, \qquad \ddot{x}_r(t) \approx \frac{z_2[k+1] - z_2[k]}{T_s} . \]

Substituting into the continuous admittance equation yields the recursions (with \( \alpha = T_s / M_a \)):

\[ \begin{aligned} z_2[k+1] &= z_2[k] + \alpha \Bigl( F_{ext}[k] - D_a z_2[k] - K_a z_1[k] \Bigr), \\ z_1[k+1] &= z_1[k] + T_s z_2[k+1]. \end{aligned} \]

This is a linear time-invariant system of the form \( \mathbf{z}[k+1] = \mathbf{A}_d \mathbf{z}[k] + \mathbf{B}_d F_{ext}[k] \), with

\[ \mathbf{A}_d = \begin{bmatrix} 1 - T_s \alpha K_a & T_s \bigl(1 - \alpha D_a\bigr) \\ -\alpha K_a & 1 - \alpha D_a \end{bmatrix}, \quad \mathbf{B}_d = \begin{bmatrix} T_s \alpha \\[0.3em] \alpha \end{bmatrix}, \]

and \( \mathbf{z}[k] = \begin{bmatrix} z_1[k] \\ z_2[k] \end{bmatrix} \). For stability in the absence of external forces, the eigenvalues of \( \mathbf{A}_d \) must lie strictly inside the unit disc. For sufficiently small \( T_s \) and positive \( M_a, D_a, K_a \), this holds automatically, but aggressive gains and large sampling periods can destabilize the discrete-time system.

The real-time control loop for an admittance controller is:

flowchart TD
  Start["Start of sample k"] --> Read["Read F_ext[k] and x[k] from sensors"]
  Read --> Update["Update virtual state (z_1, z_2) and compute x_r[k+1]"]
  Update --> Limits["Apply filtering and motion limits to x_r[k+1]"]
  Limits --> Inner["Send x_r[k+1] to inner motion controller"]
  Inner --> Next["Wait until next sampling instant k+1"]
        

6. Python Implementation (Admittance Law Only)

The following Python code implements the discrete-time 1-DOF admittance model derived above. In a ROS 2 setup, this logic would typically run in a node built with rclpy, subscribing to a force/torque sensor topic (e.g. geometry_msgs/WrenchStamped) and publishing a reference pose to a motion controller or a package such as ros2_control or MoveIt.


import numpy as np

class Admittance1D:
    def __init__(self, M_a, D_a, K_a, x0=0.0, dt=0.001):
        self.M_a = float(M_a)
        self.D_a = float(D_a)
        self.K_a = float(K_a)
        self.x0 = float(x0)
        self.dt = float(dt)

        # discrete-time state: z1 = x_r - x0, z2 = xdot_r
        self.z1 = 0.0
        self.z2 = 0.0

        alpha = self.dt / self.M_a
        self.A11 = 1.0 - self.dt * alpha * self.K_a
        self.A12 = self.dt * (1.0 - alpha * self.D_a)
        self.A21 = -alpha * self.K_a
        self.A22 = 1.0 - alpha * self.D_a
        self.B1 = self.dt * alpha
        self.B2 = alpha

    def step(self, F_ext):
        """
        One control step of the admittance model.
        F_ext: measured external force (scalar) at current sample.
        Returns x_r, xdot_r.
        """
        F = float(F_ext)

        z1_next = self.A11 * self.z1 + self.A12 * self.z2 + self.B1 * F
        z2_next = self.A21 * self.z1 + self.A22 * self.z2 + self.B2 * F

        self.z1 = z1_next
        self.z2 = z2_next

        x_r = self.z1 + self.x0
        xdot_r = self.z2
        return x_r, xdot_r


if __name__ == "__main__":
    ctrl = Admittance1D(M_a=3.0, D_a=20.0, K_a=50.0, x0=0.0, dt=0.001)
    T = 2.0
    n_steps = int(T / ctrl.dt)
    F_profile = np.zeros(n_steps)
    # constant push of 10 N after 0.2 s
    start_idx = int(0.2 / ctrl.dt)
    F_profile[start_idx:] = 10.0

    x_log = np.zeros(n_steps)
    for k in range(n_steps):
        x_r, _ = ctrl.step(F_profile[k])
        x_log[k] = x_r

    # x_log can be plotted to inspect the compliant motion
      

The output \( x_r \) should be passed to a task-space or joint-space controller that tracks this reference while respecting kinematic limits and collision constraints.

7. C++ Implementation and Robotics Libraries

In C++, admittance controllers are often integrated into the ros_control framework or vendor-specific robot SDKs. Libraries such as orocos_kdl (Kinematics and Dynamics Library) are commonly used for Jacobian and kinematics computations; here we focus only on the admittance law:


#include <iostream>

class Admittance1D {
public:
    Admittance1D(double M_a, double D_a, double K_a, double x0, double dt)
        : M_a_(M_a), D_a_(D_a), K_a_(K_a), x0_(x0), dt_(dt),
          z1_(0.0), z2_(0.0)
    {
        const double alpha = dt_ / M_a_;
        A11_ = 1.0 - dt_ * alpha * K_a_;
        A12_ = dt_ * (1.0 - alpha * D_a_);
        A21_ = -alpha * K_a_;
        A22_ = 1.0 - alpha * D_a_;
        B1_ = dt_ * alpha;
        B2_ = alpha;
    }

    void step(double F_ext, double& x_r, double& xdot_r) {
        const double z1_next = A11_ * z1_ + A12_ * z2_ + B1_ * F_ext;
        const double z2_next = A21_ * z1_ + A22_ * z2_ + B2_ * F_ext;
        z1_ = z1_next;
        z2_ = z2_next;
        x_r = z1_ + x0_;
        xdot_r = z2_;
    }

private:
    double M_a_, D_a_, K_a_, x0_, dt_;
    double z1_, z2_;
    double A11_, A12_, A21_, A22_, B1_, B2_;
};

int main() {
    Admittance1D ctrl(3.0, 20.0, 50.0, 0.0, 0.001);
    double x_r = 0.0, xdot_r = 0.0;
    const double F_ext = 10.0;

    for (int k = 0; k < 5000; ++k) {
        ctrl.step(F_ext, x_r, xdot_r);
        if (k % 1000 == 0) {
            std::cout << "k=" << k
                      << ", x_r=" << x_r
                      << ", xdot_r=" << xdot_r
                      << std::endl;
        }
    }
    return 0;
}
      

In a full ROS controller, the step method would be called at each control cycle using the latest force readings, and the resulting \( x_r \) would be converted to a joint-space reference via inverse kinematics and tracked with torque or position control.

8. Java Implementation Sketch

Java is less common for industrial robot control, but is used in educational robots (e.g. LEGO-based systems) and in frameworks like WPILib for mobile robots. The same discrete-time admittance can be coded as:


public class Admittance1D {
    private final double M_a;
    private final double D_a;
    private final double K_a;
    private final double x0;
    private final double dt;

    private double z1;
    private double z2;

    private final double A11, A12, A21, A22, B1, B2;

    public Admittance1D(double M_a, double D_a, double K_a, double x0, double dt) {
        this.M_a = M_a;
        this.D_a = D_a;
        this.K_a = K_a;
        this.x0 = x0;
        this.dt = dt;

        this.z1 = 0.0;
        this.z2 = 0.0;

        double alpha = dt / M_a;
        this.A11 = 1.0 - dt * alpha * K_a;
        this.A12 = dt * (1.0 - alpha * D_a);
        this.A21 = -alpha * K_a;
        this.A22 = 1.0 - alpha * D_a;
        this.B1 = dt * alpha;
        this.B2 = alpha;
    }

    public double[] step(double F_ext) {
        double z1Next = A11 * z1 + A12 * z2 + B1 * F_ext;
        double z2Next = A21 * z1 + A22 * z2 + B2 * F_ext;

        z1 = z1Next;
        z2 = z2Next;

        double x_r = z1 + x0;
        double xdot_r = z2;
        return new double[]{x_r, xdot_r};
    }

    public static void main(String[] args) {
        Admittance1D ctrl = new Admittance1D(3.0, 20.0, 50.0, 0.0, 0.001);
        double F_ext = 10.0;
        for (int k = 0; k < 2000; ++k) {
            double[] state = ctrl.step(F_ext);
            if (k % 500 == 0) {
                System.out.println("k=" + k
                        + ", x_r=" + state[0]
                        + ", xdot_r=" + state[1]);
            }
        }
    }
}
      

In embedded Java-based robot controllers, the step method would be executed in a periodic control loop, using sensory data from force sensors or estimated interaction forces from motor currents.

9. MATLAB / Simulink Implementation

MATLAB is widely used in robotics. Via the Robotics System Toolbox, one can combine admittance controllers with detailed rigid-body dynamics models. Below is a simple 1-DOF continuous-time implementation suitable for direct simulation, or for incorporation into a MATLAB Function block in Simulink.


function [dx, y] = admittance1d_ct(t, x, Fext, M_a, D_a, K_a, x0)
% x(1) = x_r, x(2) = xdot_r
xr = x(1);
xrdot = x(2);

xddot = (Fext - D_a * xrdot - K_a * (xr - x0)) / M_a;

dx = zeros(2,1);
dx(1) = xrdot;
dx(2) = xddot;

y = xr;
end
      

In Simulink, a typical structure is:

  • Input block representing the measured \( F_{ext} \).
  • Continuous or discrete integrator blocks implementing the second-order ODE.
  • A saturation and rate-limiter block to keep \( x_r \) within allowable workspace bounds and velocity limits.
  • A block implementing the inner joint or task-space controller that receives \( x_r \) and sends torque or velocity commands to actuators.

10. Wolfram Mathematica Implementation

Wolfram Mathematica is convenient for symbolic analysis and numerical simulation of admittance-controlled systems. The following code constructs a state-space model and simulates the response to a step in \( F_{ext} \).


(* Parameters *)
M_a = 3.0;
D_a = 20.0;
K_a = 50.0;
x0 = 0.0;

(* State variables x_r and xdot_r *)
xr[t_] := x[t];
xrdot[t_] := x'[t];

Fext[t_] := 10.0 * UnitStep[t - 0.2];

eq = M_a*x''[t] + D_a*x'[t] + K_a*(x[t] - x0) == Fext[t];

ic = {x[0] == x0, x'[0] == 0.0};

sol = NDSolve[{eq, ic}, x, {t, 0, 2.0}];

xrPlot = Plot[Evaluate[x[t] /. sol], {t, 0, 2.0},
  AxesLabel -> {"t", "x_r"},
  PlotLabel -> "Admittance response"];

xrPlot
      

Symbolic manipulation can also be used to compute the transfer functions and to analyze pole placement resulting from different choices of \( M_a, D_a, K_a \).

11. Problems and Solutions

Problem 1 (Transfer Function Derivation): For the 1-DOF admittance \( M_a \ddot{x}_r + D_a \dot{x}_r + K_a (x_r - x_0) = F_{ext} \), derive the transfer function from \( F_{ext}(s) \) to \( X_r(s) \). Identify the poles and discuss their dependence on \( M_a, D_a, K_a \).

Solution: Taking Laplace transforms with zero initial conditions:

\[ M_a s^2 X_r(s) + D_a s X_r(s) + K_a\bigl(X_r(s) - x_0/s\bigr) = F_{ext}(s). \]

Rearranging,

\[ \bigl(M_a s^2 + D_a s + K_a\bigr) X_r(s) = F_{ext}(s) + K_a \frac{x_0}{s}, \]

hence

\[ G(s) = \frac{X_r(s)}{F_{ext}(s)} = \frac{1}{M_a s^2 + D_a s + K_a}. \]

The poles are the roots of \( M_a s^2 + D_a s + K_a = 0 \), i.e. \( s_{1,2} = \frac{-D_a \pm \sqrt{D_a^2 - 4 M_a K_a}}{2 M_a} \). Increasing \( D_a \) moves poles leftwards (more damping), while increasing \( K_a \) increases the natural frequency and, for fixed \( D_a \), the damping ratio.

Problem 2 (Lyapunov Stability): Using the Lyapunov function candidate \( V = \tfrac{1}{2} M_a \dot{x}_r^2 + \tfrac{1}{2} K_a (x_r - x_0)^2 \), prove that the free admittance dynamics (\( F_{ext} = 0 \)) are globally asymptotically stable when \( M_a > 0 \), \( D_a > 0 \), \( K_a \ge 0 \).

Solution: We already derived \( \dot{V} = - D_a \dot{x}_r^2 \le 0 \), so \( V \) is nonincreasing and positive definite. The largest invariant set satisfying \( \dot{V} = 0 \) is \( \dot{x}_r = 0 \). On this set, the dynamics give \( \ddot{x}_r = 0 \), so \( K_a (x_r - x_0) = 0 \), leading to \( x_r = x_0 \) (or, if \( K_a = 0 \), the system is marginally stable with constant position). Thus the origin is the only invariant point and the equilibrium is globally asymptotically stable by LaSalle.

Problem 3 (Discrete-Time Eigenvalues): For the discrete-time system in Section 5 with \( z_1[k+1], z_2[k+1] \), write the characteristic polynomial of \( \mathbf{A}_d \) and discuss how decreasing \( T_s \) affects the eigenvalues.

Solution: The characteristic polynomial is

\[ p(\lambda) = \lambda^2 - \operatorname{tr}(\mathbf{A}_d) \lambda + \det(\mathbf{A}_d). \]

With \( \alpha = T_s / M_a \), one can compute \( \operatorname{tr}(\mathbf{A}_d) = 2 - \alpha D_a - T_s \alpha K_a \) and \( \det(\mathbf{A}_d) = 1 - \alpha D_a - T_s \alpha K_a \). As \( T_s \to 0 \), both the trace and determinant approach their continuous-time limits, and the eigenvalues approach \( 1 + s_i T_s \), where \( s_i \) are the continuous-time poles. Thus for small \( T_s \), the discrete-time eigenvalues lie close to the unit circle but inside it if the continuous-time system is stable.

Problem 4 (Multi-DOF Diagonal Admittance): Consider a 3D translational task with diagonal admittance matrices \( \mathbf{M}_a = \operatorname{diag}(m_x,m_y,m_z) \), \( \mathbf{D}_a = \operatorname{diag}(d_x,d_y,d_z) \), \( \mathbf{K}_a = \operatorname{diag}(k_x,k_y,k_z) \). Show that stability of each scalar admittance is sufficient for stability of the full system.

Solution: The vector equation decouples into three independent scalar equations in \( x_r, y_r, z_r \). Define a Lyapunov function as the sum of the three scalar energies:

\[ V = \tfrac{1}{2} m_x \dot{x}_r^2 + \tfrac{1}{2} k_x (x_r - x_{0x})^2 + \tfrac{1}{2} m_y \dot{y}_r^2 + \tfrac{1}{2} k_y (y_r - y_{0y})^2 + \tfrac{1}{2} m_z \dot{z}_r^2 + \tfrac{1}{2} k_z (z_r - z_{0z})^2 . \]

Its derivative is the sum of three terms, each of which is nonpositive when \( d_x,d_y,d_z > 0 \). Therefore the origin is globally asymptotically stable if each scalar system is.

Problem 5 (Matching Desired Human-Perceived Stiffness): Suppose the human operator perceives stiffness through the static relation \( F_{ext} = K_{eff} (x_r - x_0) \) for slowly varying motion. Given an admittance with parameters \( M_a, D_a, K_a \), show that for quasi-static motion the effective stiffness is \( K_{eff} = K_a \). Discuss how you would choose \( K_a \) to mimic a desired stiffness profile.

Solution: For quasi-static motion, time derivatives are small, so we approximate \( \dot{x}_r \approx 0 \), \( \ddot{x}_r \approx 0 \), and the admittance equation reduces to \( K_a (x_r - x_0) \approx F_{ext} \). Thus \( K_{eff} = K_a \). To mimic a desired stiffness profile, one chooses \( K_a \) directly equal to the desired stiffness in the contact direction, possibly varying it with position or context as long as the resulting control remains stable and respects actuator limits.

12. Summary

In this lesson we introduced admittance control as the dual of impedance control: instead of mapping motion errors to forces, we map measured forces to compliant motions via a virtual mass–damper–spring system. We formulated the admittance in task space, coupled it with known manipulator dynamics through a fast inner motion loop, and derived Lyapunov-based stability conditions. A discrete-time implementation suitable for digital control was obtained by Euler discretization, and we emphasized the importance of sampling period and gain selection for stability. Finally, we provided multi-language implementations (Python, C++, Java, MATLAB/Simulink, Mathematica) that realize the admittance law and can be integrated with existing robot software stacks.

The next lesson will compare impedance and admittance control in detail, discussing criteria for choosing one or the other under different robot and environment characteristics.

13. References

  1. Hogan, N. (1985). Impedance control: An approach to manipulation. Part I–III. Journal of Dynamic Systems, Measurement, and Control, 107(1), 1–24.
  2. Colgate, J. E., & Hogan, N. (1988). Robust control of dynamically interacting systems. International Journal of Control, 48(1), 65–88.
  3. Colgate, J. E., & Schenkel, G. G. (1997). Passivity of a class of sampled-data systems: Application to haptic interfaces. Journal of Robotic Systems, 14(1), 37–47.
  4. De Schutter, J., De Laet, T., Rutgeerts, J., De Schutter, J., & Bruyninckx, H. (2007). Constraint-based task specification and estimation for sensor-based robot systems. International Journal of Robotics Research, 26(5), 433–455.
  5. Ott, C., Albu-Sch�ffer, A., & Hirzinger, G. (2008). Cartesian impedance control of redundant robots: Recent results with the DLR-Light-Weight-Arms. IEEE International Conference on Robotics and Automation, 3704–3709.
  6. Villani, L., & De Schutter, J. (2008). Force control. In Springer Handbook of Robotics, B. Siciliano & O. Khatib (Eds.), 161–185.
  7. Stramigioli, S., van der Schaft, A. J., & Maschke, B. (2002). Passive output feedback and port interconnection. Systems & Control Letters, 48(5), 351–359.
  8. Khansari-Zadeh, S. M., & Billard, A. (2011). Learning stable nonlinear dynamical systems with Gaussian mixture models. IEEE Transactions on Robotics, 27(5), 943–957. (For dynamical systems perspectives relevant to virtual admittance design.)