Cascade control: let position request velocity and velocity request torque

Build cascade control from nested position and velocity loops. Follow command units, compare finite inner dynamics with ideal velocity tracking, and calculate the effect of an opposing load.

By 12 min read

A position controller can ask for a velocity. A velocity controller can turn that request into torque. Each layer measures a different quantity, so each can correct an error near the part of the system it controls.

The connection only works as intended when the outer controller accounts for the inner loop's response. This lesson makes that response visible.

Build cascade control from nested feedback loops

In cascade control, an outer controller sets the reference for an inner controller. The inner loop closes around an intermediate quantity; the outer loop closes around the final quantity of interest.

A motor-driven joint can use three nested layers:

  • The position loop compares desired and measured angle, then requests velocity.
  • The velocity loop compares requested and measured speed, then requests torque or current.
  • The current loop compares requested and measured current, then commands drive voltage.

MathWorks' electric-drive example uses a speed loop around a faster current loop. An outer position loop can then treat the complete speed loop as part of its plant. These are separate feedback paths, not merely a chain of gains with one sensor at the end.

Keep command units visible at every layer

For the two proportional controllers in this lesson:

Signal or gainMeaningUnits
r, qDesired and measured positionrad
KqPosition gain1/s
ωref = Kq(r − q)Requested velocityrad/s
KvVelocity gainN·m·s/rad
τ = Kv(ωref − ω)Requested torqueN·m

The position controller does not send its numeric output directly to a torque actuator. The velocity controller interprets it as a speed reference and produces a torque command with its own gain.

For a direct-drive motor with torque constant Kt, a torque request can become a current reference through iref = τ/Kt. For example, 1.2 N·m and Kt = 0.2 N·m/A give 6 A. A current controller then uses voltage to make the measured current follow that request; actuator dynamics explains why current cannot change instantly in a real inductive motor.

Define the two loops that the lab simulates

Use a horizontal joint with fixed inertia J = 0.5 kg·m² and viscous damping B = 1 N·m·s/rad. It has no gravity or elastic restoring torque. Positive load d opposes positive rotation:

q̇ = ω
Jω̇ = τ − Bω − d
ωref = Kq(r − q)
τ = Kv(ωref − ω)

The reference steps to r = 1 rad at time zero. Position and velocity start at zero. At 4 s, the load changes from zero to the selected value and stays there.

The simulation includes only position and velocity feedback. An ideal current/torque actuator applies τ immediately, with no torque or voltage limit. It assumes exact measurements and continuous-time controllers; there is no simulated current-control state.

Close the velocity loop first

Temporarily open the position loop and supply an independent velocity reference. Substituting the velocity controller into the joint equation gives:

Jω̇ + (B + Kv)ω = Kvωref − d
Ginner(s) = Ω(s)/Ωref(s) = Kv / (Js + B + Kv), with d = 0

The inner time constant is J/(B + Kv). Its pole is −(B + Kv)/J. Its DC gain is Kv/(B + Kv), which is below one because B is positive.

At the default Kv = 4, the time constant is 0.1 s, the pole is −10/s, and the DC gain is 0.8. A constant 1 rad/s request with no load therefore produces 0.8 rad/s after the transient. Increasing Kv changes both response speed and tracking gain.

For a constant load, the independent inner-loop equilibrium becomes ω = (Kvωref − d)/(B + Kv). The inner controller reacts to velocity error caused by that load, but its proportional rule leaves a residual velocity error when holding a nonzero torque.

Include inner dynamics in the position loop

Close the position loop around the velocity loop and the physical integration from velocity to position:

Jq̈ + (B + Kv)q̇ + KvKq q = KvKq r − d
p(s) = Js² + (B + Kv)s + KvKq

Every coefficient is positive over the lab's positive gain range, so both closed-loop poles have negative real parts. All selectable models are asymptotically stable. Their natural frequency and damping ratio are:

ωn = √(KvKq/J)
ζ = (B + Kv) / [2√(JKvKq)]

The defaults give ωn = 4 rad/s and ζ = 1.25. Keeping Kv = 4 and raising Kq from 2 to 8 gives ωn = 8 rad/s and ζ = 0.625. The response becomes underdamped and can overshoot, while this ideal model remains stable.

For these simple proportional loops, expanding the command gives τ = KvKq(r − q) − Kvω. It has the same algebraic form as position PD control with derivative action on measurement. The cascade drawing adds meaning to the intermediate velocity request; it does not create different dynamics from the expanded equation.

Follow an opposing load through both loops

At the load step, position and velocity stay continuous. The acceleration changes immediately by −d/J. Velocity error then changes the inner torque, and the resulting position error changes the outer velocity request.

At a stationary equilibrium, ω = 0 and τ = d. Combining both controller equations gives:

r − q∞ = d/(KvKq)
ωref,∞ = d/Kv
τ∞ = d

With d = 0.5 N·m, Kv = 4, and Kq = 2, the position error approaches 0.0625 rad. The joint stops at 0.9375 rad while the outer loop still requests 0.125 rad/s. That velocity error supplies the holding torque through Kv.

A different disturbance entry point gives a different response. For example, a position-sensor bias changes the outer error directly; the inner velocity sensor cannot identify that bias. Use the signal paths in the block diagram to state where a disturbance or sensor error enters.

Check the ideal-velocity approximation

If velocity follows its request perfectly, the outer loop becomes q̇ = Kq(1 − q). Starting from rest gives qideal(t) = 1 − exp(−Kq t). Modern Robotics' velocity-input control lesson derives this first-order position-error behavior.

The ideal comparison assumes unlimited, instantaneous velocity authority. It keeps its response even when the modeled mechanical load changes. Realizing its initial velocity jump would require an impulse under the finite-inertia model, so it serves as an approximation to assess, not an actuator command to reproduce exactly.

The lab reports the ratio (B + Kv)/(JKq): the inner decay rate divided by the ideal outer decay rate. This is not a measurement of the complete cascade's bandwidth. A large ratio can suggest separated response times, but the inner DC gain and disturbance response still matter.

For example, Kq = 0.5 and Kv = 0.5 give a rate ratio of 6 while the inner DC gain is only 1/3. With the default load, their steady position error is 2 rad. That large error shows why a response-time ratio alone cannot certify good tracking.

The control bandwidth lesson defines a cutoff from the closed-loop frequency response. It separates that cutoff from DC tracking gain, loop crossover, and the torque needed to follow a reference.

Compare the requests with the resulting motion

Follow the intermediate command

How closely does velocity follow its request?

Change the inner and outer gains, then compare their signals after an opposing load arrives.

2.00
4.00
0.50
6.00

J = 0.5 kg·m² and B = 1 N·m·s/rad. Both loops use proportional feedback. The joint begins at zero position and velocity, with a 1 rad target. An ideal current/torque actuator supplies the requested torque with no saturation or delay.

Position and velocity feedback loops around one jointThe one-radian reference enters the position-error sum. Measured position returns through the left negative-feedback path. The position gain produces a velocity reference for the inner error sum. Measured velocity returns through the right negative-feedback path. The velocity gain produces torque, an opposing torque load subtracts before the joint, and integrating measured velocity gives position. The current and torque actuator is ideal; no current loop state is simulated.r = 1 radΣΣΣ+−+−+−Position Kqωref(rad/s)Velocity Kvτ (N·m)dJoint J, Bω (rad/s)1/sq (rad)
Orange feedback carries measured velocity to the inner sum. Green feedback carries measured position to the outer sum. The load d uses torque units and enters before the joint dynamics. The current/torque actuator applies the inner command ideally.
Cascade position compared with ideal velocity trackingThe blue curve shows cascade position; the orange dashed curve shows position with an ideal velocity source. The vertical guide at four seconds marks the scheduled load change, including a zero selected load. At 6.000000 seconds, the blue value is 0.939018 and the orange value is 0.999994. Lines join analytic samples at 0.025-second intervals.-10.5204812Position (rad)Time (s)
Blue: cascade position. Orange dashes: the same outer gain with ideal velocity tracking, which rejects the load perfectly and assumes unlimited authority. Gray dashes: the 1 rad target.
Requested and measured velocity in the cascadeThe blue curve shows measured velocity; the orange dashed curve shows the outer loop's velocity request. The vertical guide at four seconds marks the scheduled load change, including a zero selected load. At 6.000000 seconds, the blue value is -0.003036 and the orange value is 0.121964. Lines join analytic samples at 0.025-second intervals.-11304812Velocity (rad/s)Time (s)
Blue: measured velocity. Orange dashes: the outer velocity request. Their difference produces the inner torque command. At a loaded stationary equilibrium, the request stays positive while measured velocity is zero.
Position q (rad)
0.939018
Velocity ω (rad/s)
-0.003036
Position error (rad)
0.060982
Velocity request (rad/s)
0.121964
Velocity error (rad/s)
0.125000
Inner torque command (N·m)
0.500000
Opposing load (N·m)
0.500000
Acceleration (rad/s²)
0.006072
Ideal-loop position (rad)
0.999994
Inner time constant (s)
0.100000
Inner DC gain
0.800000
Inner rate / outer gain
5.000000
Cascade damping ratio
1.250000
Steady position error (rad)
0.062500
Model stability
Asymptotically stable

All available gains are stable in this two-state model. Increasing the outer gain can reduce damping and produce overshoot. The rate ratio compares the inner decay rate with Kq; the inner DC gain and load error also affect tracking. Steady error assumes the selected load continues indefinitely.

The signal diagram shows the two feedback paths and the load entry point. The position plot compares the finite inner loop with an ideal velocity source. The velocity plot separates the request from the measured motion, including their difference after the joint approaches rest.

At the default replay time of 6 s, q = 0.939018 rad, ω = −0.003036 rad/s, and ωref = 0.121964 rad/s. Their velocity error is 0.125000 rad/s, which gives τ = 0.500000 N·m after rounding. The ideal position is 0.999994 rad.

Try the lower and higher inner-gain presets at the same replay time. Then keep the inner loop fixed and select the aggressive outer request. Compare the damping ratio with the full position trace; a single point near the target does not describe the whole transient.

Tune from the inside out and check the full system

First establish the current/torque actuator's behavior. Then open the outer position loop and tune the velocity loop against independent requests and relevant disturbances. Close the position loop and tune it using that measured or modeled inner response. MathWorks' multiloop design workflow follows this inner-first sequence.

A faster inner loop can reduce intermediate errors before they accumulate into large outer errors. The amount of useful speed separation depends on phase lag, tracking gain, disturbances, and actuator authority. Recheck the complete closed loop after changing either controller; no fixed bandwidth ratio guarantees acceptable behavior for every system.

Both simulated controllers use P only. Adding integral action can remove certain steady errors, but it adds controller state and changes the stability analysis. Feedforward control can supply predictable effort when a suitable model is available.

The lab has no saturation. In hardware, an outer velocity request may exceed what the inner actuator can deliver. If a loop contains an integrator, its anti-windup mechanism must account for the relevant unavailable command and the units at that interface; review integral windup before treating command clipping as a complete solution.

Reproduce the cascade response in Python

The normalized second-order step S(t) solves the complete position equation with zero initial state and no load. Linearity then gives q(t) = S(t) − [d/(KvKq)]S(t − 4), where S is zero before its step. This program evaluates the underdamped, critical, and overdamped forms using the standard library.

from math import cos, exp, expm1, sin, sqrt

def step(kq, kv, t):
    if t <= 0:
        return 0.0, 0.0
    alpha = 1.0 + kv  # (B + Kv)/(2J), J=0.5, B=1
    wn2 = 2.0 * kv * kq
    delta = wn2 - alpha**2
    if delta > 0:
        beta = sqrt(delta)
        c = exp(-alpha*t) * cos(beta*t)
        s = exp(-alpha*t) * sin(beta*t) / beta
    elif delta == 0:
        c = exp(-alpha*t)
        s = t*c
    else:
        beta = sqrt(-delta)
        slow = -wn2 / (alpha + beta)
        c = exp(slow*t) * (1 + exp(-2*beta*t)) / 2
        s = exp(slow*t) * (-expm1(-2*beta*t)) / (2*beta)
    return 1-c-alpha*s, wn2*s

def response(kq, kv, d=0.5, t=6.0):
    q, omega = step(kq, kv, t)
    qd, wd = step(kq, kv, t-4)
    q -= d/(kv*kq)*qd
    omega -= d/(kv*kq)*wd
    request = kq*(1-q)
    torque = kv*(request-omega)
    return q, omega, request, torque

for name, kq, kv in (("default", 2, 4), ("lower inner", 2, 0.5),
                     ("higher inner", 2, 8), ("faster outer", 8, 4),
                     ("critical", 2, 1)):
    q, omega, request, torque = response(kq, kv)
    print(f"{name}: q={q:.6f}, omega={omega:.6f}, "
          f"request={request:.6f}, torque={torque:.6f}")
print(f"ideal position at 6 s: {1-exp(-2*6):.6f}")
print(f"default steady error: {0.5/(4*2):.6f}")

Output:

default: q=0.939018, omega=-0.003036, request=0.121964, torque=0.500000
lower inner: q=0.621226, omega=-0.112074, request=0.757548, torque=0.434811
higher inner: q=0.969397, omega=-0.001294, request=0.061206, torque=0.500000
faster outer: q=0.984376, omega=0.000001, request=0.124995, torque=0.499977
critical: q=0.772815, omega=-0.036484, request=0.454371, torque=0.490854
ideal position at 6 s: 0.999994
default steady error: 0.062500

Try it yourself

Exercise 1. At one instant, q = 0.8 rad and ω = 0.1 rad/s. Use the default gains and a load of 0.5 N·m. Calculate both errors, the velocity request, the torque command, and acceleration.

Check the two command interfaces

Position error is 1 − 0.8 = 0.2 rad. The outer loop requests 2 × 0.2 = 0.4 rad/s. Velocity error is 0.4 − 0.1 = 0.3 rad/s, so the inner torque command is 4 × 0.3 = 1.2 N·m. Acceleration is (1.2 − 1 × 0.1 − 0.5)/0.5 = 1.2 rad/s².

Exercise 2. Set Kq = 0.5/s and Kv = 0.5 N·m·s/rad. Keep d = 0.5 N·m. Find the inner time constant, inner DC gain, rate ratio, and final position. Explain why the rate ratio does not imply ideal velocity tracking.

Check response speed and tracking gain separately

The inner time constant is 0.5/(1 + 0.5) = 1/3 s, and its DC gain is 0.5/1.5 = 1/3. Its decay rate is 3/s, so the ratio to Kq is 3/0.5 = 6. Steady position error is 0.5/(0.5 × 0.5) = 2 rad, giving q∞ = 1 − 2 = −1 rad. The finite proportional inner gain needs velocity error to provide holding torque; the rate ratio alone does not describe that error.

Sources and further study

Continue with actuator dynamics to replace ideal torque delivery with electrical and mechanical states, or revisit PID control before adding integral action inside either loop.