About this simulation

Written by MySimulator Team · Reviewed by MySimulator Editorial Review

Last updated: 20 July 2026

This simulation models a car's cruise control as a real PI (Proportional-Integral) controller driving a real vehicle: mass × acceleration = engine force − aerodynamic drag − rolling resistance − the gravity component of the road grade. Each control tick the controller measures the speed error e = target − v and computes a commanded engine force u = Kp·e + Ki·∫e·dt, clamped to the engine's real maximum tractive force. Drive up the adjustable hill and you'll see a genuine, well-documented failure mode of practical PI control: integral windup, where the integral term keeps accumulating error while the engine is saturated, producing a real overshoot once the grade flattens — fixed by toggling on anti-windup, which freezes the integral while the actuator can't respond.

🔬 What it shows

A 3D car drives a looped test track with a flat run-in, an adjustable uphill grade, and a flat run-out. The engine force needed to hold the target speed on the hill can exceed the engine's real force limit, so the car is physically unable to hold speed while climbing — the readouts show the commanded force pinned at maximum and the saturation flag turning active. The difference the anti-windup toggle makes on the flat after the hill is real control-loop behaviour, not a scripted animation.

🎮 How to use

Set a target speed and Kp/Ki gains, then watch the car climb the hill. With Anti-windup off, the integral term (∫e·dt in the readouts) keeps growing the whole time the engine is saturated on the hill; once the road flattens the pent-up integral commands far more force than needed and the car overshoots the target speed before settling back. Turn Anti-windup on, reset, and repeat — the integral stops growing once saturated, and the same hill produces little or no overshoot. Raise the hill grade slider to make the effect more dramatic, or lower it toward 0% to see the difference disappear.

💡 Did you know?

Real production cruise-control systems are almost always PI, not full PID — a derivative term reacting to speed noise from wheel-speed sensors and road bumps would make the throttle twitchy, so engineers accept a slightly slower response in exchange for smoothness. Integral windup is not a toy problem: it's a documented failure mode in autopilots, industrial process control and robotics any time an actuator (a valve, a motor, an engine) has a real physical limit — which every real actuator does.

Frequently asked questions

Why does this cruise control use a PI controller instead of full PID?

A PI controller pairs a proportional term Kp·e (immediate correction, proportional to how far the current speed is from the target) with an integral term Ki·∫e·dt (which eliminates the small steady-state error a proportional-only controller would leave, for example on a mild constant grade). Real automotive cruise control is almost always PI rather than PID: a derivative term reacting to the rate of change of speed would amplify noise from the speed sensor and road irregularities into a jittery, uncomfortable throttle, so the industry standard trades a touch of response speed for a smooth ride.

What is integral windup, concretely, in this simulation?

When the road grade demands more engine force than the engine can physically deliver, the commanded force u = Kp·e + Ki·∫e·dt is clamped down to the real maximum force, but the underlying integral term ∫e·dt itself keeps accumulating positive error every tick, growing far beyond what the plant can ever use, if nothing stops it. That's integral windup: the integrator "winds up" to a large value while the actuator sits saturated and unable to respond to it.

How does anti-windup fix it, and what does this simulation actually do?

This simulation implements the standard clamping (conditional-integration) anti-windup technique: before updating the integral each tick, it checks whether the tentative commanded force would push further into saturation in the same direction as the current error. If so, the integral update is frozen for that tick; otherwise it proceeds normally. The result is that the integral only accumulates when doing so can still produce a useful, deliverable force — exactly the standard technique taught in every practical control-systems course, and it is a toggle you can switch mid-run to compare against naive (always-integrating) PI on the identical physics.

What real physics governs the car's motion in this simulation?

The car obeys a genuine longitudinal equation of motion: mass × acceleration = engine force − aerodynamic drag − rolling resistance − gravity component of the grade. Aerodynamic drag grows with the square of speed (F = ½·ρ·Cd·A·v²), rolling resistance is a small constant force proportional to the car's weight, and the grade force is m·g·sin(θ) where θ is the road's incline angle — all real terms from vehicle dynamics, not a simplified "speed snaps to target" model.

Why does the engine force saturate, and is that a realistic limit?

Every real engine has a maximum tractive force it can deliver at a given gear and RPM — there is a hard physical ceiling on how much forward force the drivetrain can produce, no matter how large the controller's computed command is. This simulation enforces that same real limit: the controller can ask for more force than the engine can give, but the actual force applied to the car is clamped to that maximum, which is exactly the actuator saturation that causes windup in real systems.

Why does the car overshoot the target speed once the hill ends?

While climbing, the engine is pinned at its maximum force and — without anti-windup — the integral term keeps growing well past the value that was actually needed. The moment the grade flattens, the force required to hold the target speed drops sharply, but the controller is still commanding near-maximum force because of the inflated integral, so the car accelerates hard and shoots past the target before the integral (and the error, now negative) unwinds back down to a sensible value. With anti-windup enabled, the integral never grew past what the saturated engine could use, so there is little excess to unwind and little or no overshoot.