One corner of a car is a mass sitting on a spring and a shock absorber (a damper): the classic mass-spring-damper. When a passenger sits down on that corner, a constant extra force F (newtons) pushes the body down, and it sinks by a displacement x (metres, positive downwards) from where it was. Three forces act on the mass m (kg):
- the passenger's weight
F, pushing down, - the spring,
-k * x: it pushes back harder the further it is squeezed (kin N/m), - the damper,
-c * v: it resists motion in proportion to the speedv(m/s), whichever way it goes (cin N·s/m).
Newton's second law says the acceleration is the total force divided by the mass. Unlike the first-order systems so far, this one has two states, position and velocity, and it is simulated with semi-implicit Euler steps of dt seconds, in this order:
acc = (F - c * v - k * x) / m
v = v + dt * acc
x = x + dt * v # uses the velocity just updated
(Using the new velocity for the position keeps the simulated energy from creeping up, so an undamped spring keeps a constant swing instead of growing.) The car starts at rest: x = 0, v = 0.
Write suspension_step(m, c, k, F, dt, n) that performs n steps and returns the list of positions: 0.0 first, then the position after every step (n + 1 entries). Press Run with plot(suspension_step(400, 2000, 20000, 800, 0.01, 300)): the body sinks past its final sag of F / k = 4 cm, bounces back and settles.
Examples
Input: m = 400, c = 2000, k = 20000, F = 800, dt = 0.01, n = 4
Output: [0.0, 0.0002, 0.000589, 0.001155605, 0.001888101725]
Explanation: step 1: acc = 800 / 400 = 2 m/s², v = 0.02 m/s, x = 0.0002 m.
Step 2: acc = (800 - 2000 * 0.02 - 20000 * 0.0002) / 400 = 1.89, v = 0.0389, x = 0.000589.
Input: m = 1, c = 0, k = 4, F = 2, dt = 0.5, n = 3
Output: [0.0, 0.5, 1.0, 1.0]
Constraints
- answers are compared with a tolerance of
1e-6; do not round
Goals
- Simulate a mass on a spring with a damper in small time steps
- Update velocity before position (semi-implicit Euler) in the stated order
- See that a second-order system can overshoot and oscillate before it settles