A robot arm's elbow joint is turned by a small motor. Unlike a heater, a joint has inertia: the motor's torque changes the joint's speed, and the speed changes its angle. A proportional controller keeps pushing until the angle reaches the target, so the joint arrives at full speed and swings past. With steps of dt = 0.01 s the joint moves as
w = w + 0.01 * (50 * u - 2 * w) (speed in degrees per second; 2 * w is friction)
a = a + 0.01 * w (angle in degrees)
Compare a P controller and a PD controller. Both start at rest at angle a = 0, w = 0, with the target target degrees. Each step, in this order:
e = target - a
d = (e - e_previous) / 0.01 (on the first step e_previous = e, so d = 0)
u = Kp * e + Kd * d (P controller: Kd = 0)
w = w + 0.01 * (50 * u - 2 * w)
a = a + 0.01 * w
The overshoot is how far the highest angle (after any step, or the starting 0) goes past the target: max(angle) - target, or 0.0 if the joint never passes it.
Write servo_overshoot(target, Kp, Kd, steps) that runs steps steps with the P controller (Kd = 0) and with the PD controller (the given Kd), and returns the tuple (overshoot_P, overshoot_PD) in degrees. Collect the angles and press Run with plot(angles) for both: the P joint rings back and forth, the PD joint settles almost at once, at the same final angle.
Examples
Input: target = 90, Kp = 2, Kd = 0.2, steps = 300
Output: (65.61517457, 7.57486559)
Explanation: with P alone the joint swings to 155.6 degrees. The derivative term adds
50 * 0.2 = 10 to the friction's 2, so the swing is far better damped.
Input: target = 90, Kp = 2, Kd = 0.2, steps = 3
Output: (0.0, 0.0)
Explanation: after 0.03 s the joint has hardly started to move.
Constraints
- answers are compared with a tolerance of
1e-6; do not round
Goals
- Simulate a motor position servo with two states, angle and speed
- Compare the overshoot of P control and PD control on the same joint
- See the derivative term add damping without changing where the joint ends up