A car's cruise control is asked to hold v_set m/s. On a flat road the engine only has to beat the air drag, 0.4 * v * v newtons at speed v m/s. A hill adds a pull of 1200 * 9.81 * grade newtons backwards (the car has a mass of 1200 kg; grade is the rise per metre of road, so 0.05 is a 5 % climb and a negative grade is downhill).
Two cruise controls drive the same road, given as one grade per second in grades. Both start at v_set.
- Open loop: the engine always pushes with
F = 0.4 * v_set * v_set, the force that holdsv_seton the flat. - Closed loop: every second it measures the speed and pushes with
F = 0.4 * v_set * v_set + K * (v_set - v), limited to the range0..4000N (the engine cannot pull backwards or exceed 4000 N).
Each second, for each car: compute F from the speed at the start of the second, then
v = v + 1 * (F - 0.4 * v * v - 1200 * 9.81 * grade) / 1200
and if v came out below 0, set it to 0 (the car has stopped; it does not roll back).
Write cruise_on_hill(v_set, grades, K) that returns a tuple (lowest_open, lowest_closed): the lowest speed of each car over the whole drive, counting the starting speed. Plot both speed lists to see the difference.
Examples
Input: v_set = 25, grades = [0, 0.04, 0.04, 0], K = 600
Output: (24.221688674, 24.417888674)
Explanation: the open-loop force is 0.4 * 25 * 25 = 250 N. In second 2 the hill pulls
1200 * 9.81 * 0.04 = 470.88 N, and both cars lose 470.88 / 1200 = 0.3924 m/s.
In second 3 the closed loop adds 600 * 0.3924 = 235.44 N, and loses much less.
Input: v_set = 25, grades = [0.04] * 60 + [0] * 60, K = 600
Output: (8.414522002, 24.240143625)
Explanation: a minute-long climb slows the open-loop car to 8.4 m/s;
feedback holds the other within 0.8 m/s of the set speed.
Constraints
- answers are compared with a tolerance of
1e-6; do not round
Goals
- Simulate a car's speed with drive force, air drag and a slope
- Compare a fixed open-loop setting with feedback on the same road
- See how feedback rejects a disturbance that the open-loop setting ignores