Problem 423295 · medium · Level 04 Non-Linear Data Structures

P, PI or PID for the Lifting Arm?

PID control · overshoot · settling time · integrated absolute error · disturbance

A warehouse robot's arm lifts boxes. Its shoulder motor turns the arm to an angle target (degrees) while the box's weight pulls it back with a constant torque load (in the same units as the motor's push). With steps of dt = 0.01 s:

w = w + 0.01 * (50 * u - 5 * w - load)       (speed, degrees per second; 5 * w is friction)
a = a + 0.01 * w                             (angle, degrees)

Compare three controllers on the same lift, using the gains Kp, Ki and Kd: P uses only Kp (Ki = Kd = 0), PI uses Kp and Ki (Kd = 0), and PID uses all three. The encoder measures the speed w directly, so the derivative term is taken on the measurement, -Kd * w. Each run starts at rest, a = 0, w = 0, I = 0, and takes round(seconds / 0.01) steps, recording a[0] = 0, a[1], .... Each step, in this order:

e = target - a
IAE = IAE + abs(e) * 0.01                    (integrated absolute error, degree-seconds)
I = I + e * 0.01
u = Kp * e + Ki * I - Kd * w
w = w + 0.01 * (50 * u - 5 * w - load)
a = a + 0.01 * w

For each controller measure:

  1. overshoot: max(recorded angles) - target, or 0.0 if the arm never passes the target;
  2. settling: i * 0.01 seconds for the smallest index i such that a[i] and every later angle are within 0.02 * target of the target; None if the last angle is outside that band;
  3. IAE, the integrated absolute error.

Write compare_pid(target, Kp, Ki, Kd, load, seconds) that returns a dict {"P": (overshoot, settling, IAE), "PI": (...), "PID": (...)}. Plot the three angle lists on one chart to see the story.

Examples

Input:  target = 60, Kp = 1, Ki = 0.5, Kd = 0.1, load = 200, seconds = 6
Output: {"P":   (12.7907342, None, 35.86161714),
         "PI":  (18.66176159, 1.92, 19.28384206),
         "PID": (4.32054333, 1.54, 17.35917699)}
Explanation: P control swings past and then sags 4 degrees short under the box's weight,
outside the ±1.2 degree band. Integral action removes the sag but adds overshoot;
the derivative term damps it, and PID settles first with the smallest IAE.

Input:  target = 60, Kp = 1, Ki = 0.5, Kd = 0.1, load = 0, seconds = 0
Output: {"P": (0.0, None, 0.0), "PI": (0.0, None, 0.0), "PID": (0.0, None, 0.0)}

Constraints

  • answers are compared with a tolerance of 1e-6; do not round

Goals

  • Simulate P, PI and PID control of the same position servo with a load
  • Measure overshoot, settling time and integrated absolute error
  • See what each term buys: I removes the offset, D gives back the damping I takes away
Starting Python…