Problem 532141 · medium · Level 05 Advanced Algorithms & Graphs

Cascade Control of a Camera Slider

cascade control · inner loop · outer loop · saturation · sampling rate · simulation

A motorised camera slider moves a camera along a rail to a target position. It is controlled by two loops, one inside the other (cascade control):

  • the outer loop looks at the position theta (in rad of the motor shaft) and asks for a speed: w_ref = Kp * (target - theta), limited to -20..20 rad/s;
  • the inner loop looks at the measured speed omega and sets the motor voltage to reach that speed: u = Kv * (w_ref - omega), limited to -12..12 V.

The inner loop runs every step of dt = 0.01 s. The outer loop runs only every every steps (on steps 0, every, 2*every, ...), and its w_ref is held in between. The motor's speed follows the voltage with a time constant of 0.2 s and a gain of 10 rad/s per volt. Starting from theta = omega = w_ref = 0, each step k does, in this order:

if k % every == 0:  w_ref = Kp * (target - theta), limited to -20..20
u = Kv * (w_ref - omega), limited to -12..12
omega = omega + 0.01 * (-omega + 10 * u) / 0.2
theta = theta + 0.01 * omega          (with the new omega)

and records theta after the update.

The design rule of cascade control is that the inner loop must be much faster than the outer one (five to ten times is common): then the outer loop can treat "ask for a speed" as if the speed simply happened. Here the inner loop's time constant is about 0.2 / (1 + 10 * Kv) seconds and the outer loop's about 1 / Kp.

Write cascade(target, Kp, Kv, every, steps) that returns the list of the steps recorded positions. Press Run with plot(cascade(1, 15, 0.1, 1, 300)) and compare it with cascade(1, 5, 1, 10, 300).

Examples

Input:  target = 1, Kp = 5, Kv = 1, every = 10, steps = 4
Output: [0.025, 0.06125, 0.1025625, 0.146153125]
Explanation: step 0: w_ref = 5, u = 5 V, omega = 0 + 0.01 * 50 / 0.2 = 2.5, theta = 0.025.

Input:  target = 1, Kp = 5, Kv = 0.05, every = 2, steps = 4
Output: [0.00125, 0.0036562499999999998, 0.0071274609375, 0.011583760742187501]

Over 300 steps the peaks show the rule: Kp = 5, Kv = 1, every = 10 (inner 0.018 s, outer 0.2 s) peaks at 1.000 with no overshoot; Kp = 15, Kv = 0.1, every = 1 (inner 0.1 s, outer 0.067 s: the inner loop is slower than the outer one) rings up to 1.099; and Kp = 15, Kv = 1, every = 10 overshoots to 1.309, because an outer loop that updates only every 0.1 s is now too slow for its own gain.

Constraints

  • 1 <= every <= 100, 0 <= steps <= 5000, 0 <= Kv <= 3
  • answers are compared with a tolerance of 1e-6

Goals

  • Simulate two nested loops: an outer position loop that sets the target of an inner speed loop
  • Run the outer loop less often than the inner one and hold its output in between
  • See why the inner loop must be much faster than the outer loop
Starting Python…