A camera gimbal on a drone turns the camera to a new heading. Its control loop runs every dt seconds, and its slowest (dominant) pole is at z = re + im*j. You do not need to simulate anything: the pole's polar form z = r\,(\cos\theta + j\sin\theta) = r e^{j\theta} already says how the camera will move.
- Radius r = |z|: decay. After k samples the pole's part of the response has shrunk to r^k of its start. The usual settling rule waits until it is down to 2 %: r^k = 0.02, so k = \ln(0.02) / \ln(r) samples, and the settling time is k\,\Delta t seconds (
k * dt). Keepkas a real number (do not round it). - Angle \theta = |\angle z| (in radians, between 0 and \pi): oscillation. Each sample turns the pole by \theta, so one full swing takes 2\pi / \theta samples, a period of 2\pi\,\Delta t / \theta seconds. A pole on the positive real axis (\theta = 0) does not oscillate at all: its period is
None. - Overshoot. The first overshoot comes half a swing after the start, \pi / \theta samples, by which time the swing has shrunk to r^{\pi/\theta}. So the overshoot is about 100\,r^{\pi/\theta} per cent of the step. With \theta = 0 there is no overshoot:
0.0.
(These are exact for a loop whose step response is set by one pair of poles, and good estimates when one pair dominates.) cmath.polar(complex(re, im)) gives (r, angle); math.atan2(im, re) gives the angle too.
Write read_pole(re, im, dt) that returns (settling_time, period, overshoot_percent).
Examples
Input: re = 0.8, im = 0.3, dt = 0.01
Output: (0.24861070488208192, 0.1751309632540762, 25.2109970130379)
Explanation: r = 0.8544 and θ = 0.3588 rad. Settling takes ln(0.02) / ln(0.8544) = 24.86 samples,
0.2486 s; one swing takes 2π / 0.3588 = 17.51 samples, 0.1751 s; the overshoot is
0.8544 ** 8.757 = 0.252, about 25 %.
Input: re = 0.8, im = 0, dt = 0.5
Output: (8.765709298763475, None, 0.0)
Explanation: a real pole: 0.8 ** 17.53 = 0.02, so 17.53 samples of 0.5 s. No swing, no overshoot.
Constraints
0 < |z| < 1(the loop is stable);dt > 0- answers are compared with a tolerance of
1e-6; a list is accepted in place of the tuple
Goals
- Read a pole's radius as a rate of decay and turn it into a settling time
- Read a pole's angle as an oscillation and turn it into a period
- Estimate the overshoot from how much the swing decays in half a period