A garage tests shock absorbers on a rig: a heavy weight is lowered onto the car's corner at sample 0, and a laser logs how far the body sinks (samples, millimetres). A worn damper lets the body bounce; a good one lets it overshoot a little and settle.
For a mass-spring-damper the size of the overshoot depends only on the damping ratio zeta, not on the mass or the spring. With the fraction
os = (peak - final) / (final - start)
where start = samples[0], peak is the largest sample and final the settled sag, the damping ratio is
L = ln(os) # negative, because os < 1
zeta = -L / sqrt(pi ** 2 + L ** 2)
(The formula comes from the exact solution of the mass-spring-damper; you only need to use it. A large overshoot means a small zeta: os = 0.5 gives about 0.22, os = 0.05 about 0.69, which suspension designers like.) If the response never goes above final there is no overshoot, the system has zeta >= 1, and the overshoot cannot tell how much more than 1: return None.
Write damping_from_overshoot(samples, final). The sag goes down into the springs, which the log records as positive numbers, so final > samples[0], and the overshoot is less than 100 %. Press Run with plot(samples) to see the bounce.
Examples
Input: samples = [0, 3, 5.8, 6.4, 5.9, 5.4, 5.5], final = 5
Output: 0.3755396607279802
Explanation: os = (6.4 - 5) / (5 - 0) = 0.28; L = ln 0.28 = -1.273; zeta = 1.273 / sqrt(9.870 + 1.621).
Input: samples = [0, 1, 3, 5], final = 5
Output: None
Explanation: the body creeps down to 5 mm and never past it.
Constraints
final > samples[0]andmax(samples) < 2 * final - samples[0]- answers are compared with a tolerance of
1e-6; do not round
Goals
- Measure the overshoot of a step response as a fraction of the step
- Invert the overshoot formula of a second-order system to estimate its damping ratio
- Recognise when a response carries no information about the damping ratio