A team building a racing kart has no data sheet for a second-hand suspension unit. They put the unit on a rig with a known mass m (kg), drop a weight on it at sample 0 and log the sag (samples, any length unit, one sample every dt seconds) until it has nearly settled at final. From that one bounce they want the spring constant k (N/m) and the damper constant c (N·s/m).
Three facts about an underdamped mass-spring-damper do it:
- Damping ratio from overshoot. With
os = (peak - final) / (final - samples[0])(peakthe largest sample) andL = ln(os):zeta = -L / sqrt(pi ** 2 + L ** 2). - Natural frequency from the period. The response wobbles with a period
Tdseconds, the time from one peak to the next. Its angular frequencywd = 2 * pi / Td(radians per second) is the damped frequency; the natural frequency, the one the spring and mass would have without the damper, iswn = wd / sqrt(1 - zeta ** 2). - Back to the hardware. For a mass on a spring
wn = sqrt(k / m)andzeta = c / (2 * sqrt(k * m)), sok = m * wn ** 2andc = 2 * zeta * m * wn.
A peak is a sample i (not the first or the last) with samples[i-1] < samples[i] >= samples[i+1]. Use the first two peaks: Td = (i2 - i1) * dt. The log is clean (no noise) and has at least two peaks.
Write identify_suspension(samples, dt, m, final) that returns the tuple (zeta, wn, k, c). Notice that the unit of the samples does not matter: every step uses only ratios of them.
To try your function, the helper rig_log(m, c, k, F, dt, n) makes a log like the rig's: the semi-implicit Euler simulation of the suspension problem, positions in metres, n + 1 samples, settling at F / k. For example identify_suspension(rig_log(400, 2000, 20000, 800, 0.01, 300), 0.01, 400, 0.04) should give a k near 20000 and a c near 2000 (not exactly: the period is only measured to the nearest sample, and the simulation is not the exact solution). Press Run with plot(samples) and look at the peaks.
Examples
Input: samples = [0, 2, 5, 7, 6, 4, 4.5, 5.5, 5.2, 4.9, 5], dt = 0.1, m = 10, final = 5
Output: (0.27999799333504155, 16.36245176189057, 2677.2982766019577, 91.62907318741549)
Explanation: os = 2 / 5 = 0.4 gives zeta = 0.280. The peaks are samples 3 (7) and 7 (5.5),
so Td = 0.4 s, wd = 15.708 rad/s and wn = 15.708 / sqrt(1 - 0.0784) = 16.362 rad/s.
Then k = 10 * 16.362 ** 2 = 2677 N/m and c = 2 * 0.280 * 10 * 16.362 = 91.6 N·s/m.
Constraints
final > samples[0], the overshoot is between 0 and 100 %, and there are at least two peaks- answers are compared with a tolerance of
1e-6; do not round
Goals
- Measure the period of a decaying oscillation from the gap between two peaks
- Turn the damped frequency into the natural frequency using the damping ratio
- Recover the spring and damper constants of a mass-spring-damper from a step response