explainer
Open-loop and closed-loop control: compare plans with position feedback
Explore open-loop and closed-loop control by moving an axis along a planned path. Calculate how gain errors, drift, initial position, and sensor bias change tracking, then connect or disconnect the feedback path.
What you will learn
- Identify whether measured position can change a controller's command.
- Derive a scheduled velocity command from a nominal motion model.
- Calculate position error during motion and after the target stops.
- Separate drift, gain mismatch, initial offset, and sensor bias.
- Explain when feedback helps and when measurement errors can hurt tracking.
Before you start
A motion plan can place an axis exactly where you want it. That result depends on the axis following the model and starting where the plan expects. A position measurement gives the controller a way to respond when either condition fails.
This lesson compares open-loop and closed-loop control on the same four-metre move. You will calculate both trajectories, disconnect the measurement path, and check whether a correction improves the true position.
Trace the open-loop and closed-loop control paths
An open-loop position controller selects its command without using the resulting position to update that command. Its schedule can still use a detailed model, a clock, or a known disturbance. Logging a position measurement does not close the loop if the command ignores it.
A closed-loop position controller returns measured position to the command calculation. The axis changes position, the sensor reports that change, and the controller adjusts what the axis receives.
| Information path | What changes the command? |
|---|---|
| Plan → command → axis | The scheduled plan |
| Plan and measured position → command → axis → measured position | The plan and the measured tracking error |
Lynch and Park's control overview follows this flow through sensors, controllers, actuators, and robot motion. Open or closed describes a particular loop boundary. A position controller can operate open loop while a motor drive underneath it closes an inner speed loop.
Define the axis and the motion plan
Use one straight axis. Its true position is x, its velocity command is u, and a positive dimensionless gain g maps command to actual velocity. A signed disturbance velocity d adds to that motion:
dx/dt = gu + d
This equation treats velocity response as immediate. Modern Robotics' velocity-input lesson uses this modeling choice when lower-level drives can follow velocity requests. Here d represents extra signed velocity, measured in m/s; it is not a force or torque.
| Quantity | Meaning |
|---|---|
| x, r | True and reference position, in metres |
| u | Velocity command, in m/s |
| g | Actual velocity gain, default 1 |
| d | Zero before 2 s, then the selected disturbance velocity |
| x₀ | Both axes' initial position, default 0 m |
| b | Constant position sensor bias, in metres |
The reference moves from 0 m at 1 m/s for four seconds. It then stays at 4 m. With time t measured in seconds, r(t) = min(t, 4) metres.
The reference velocity v is 1 m/s before 4 s and zero afterward. Position remains continuous at 4 s, while the reference velocity changes instantly. We use the value after a change when reporting a command at that exact time.
Turn a model into a scheduled command
Suppose the controller's nominal model is dx/dt = ĝu, with estimated gain ĝ = 1 and no disturbance. Solving that model for the desired velocity gives the feedforward command u = v / ĝ = v.
That command is 1 m/s for four seconds, then zero. It follows the reference velocity without waiting for a position error. The same scheduled term will remain part of the closed-loop controller.
Feedforward control extends this idea to a joint with inertia and drag. Its speed experiment predicts torque from the desired acceleration, then uses feedback to correct model mismatch and unexpected loads.
For the actual gain g and the disturbance step in this lesson, the open-loop position follows directly from integration:
x open(t) = x₀ + g r(t) + d after × max(0, t − 2 s)
With g = 1, d = 0, and x₀ = 0, this schedule tracks the reference exactly. A repeatable, calibrated task can use such a plan without continuous position correction, provided its errors meet the task's requirements.
Open loop retains an unknown initial offset. It also accumulates error from an unmodeled velocity disturbance. The model-uncertainty lesson separates uncertain parameter values from missing physics and disturbance assumptions.
Let measured position change the command
Let the sensor report y = x + b. Compare that measurement with the reference and multiply the measured error by a nonnegative gain K:
y = x + b
e measured = r − y
u = v + K(r − y)
K has units 1/s, so K times a position error has velocity units. If the sensor reports a position behind the reference, the correction increases the command. If it reports a position ahead, the correction decreases the command and can request reverse motion.
Modern Robotics' feedforward-plus-feedback treatment adds the desired velocity to a position correction. That source also develops integral feedback. This experiment uses only the proportional term, so some disturbances leave a lasting error.
Disconnecting the measurement path removes the entire correction. Setting K = 0 gives the same command and trajectory, even if the diagram still shows a connected path. A zero-gain connection has no influence on motion.
Solve the error between scheduled changes
Define true error as e = r − x. Since measured error is e − b, substituting the command into the axis equation gives:
de/dt = (1 − g)v − d + gKb − gKe
λ = gK
a = (1 − g)v − d + λb
During each interval with fixed v and d, the equation is de/dt = a − λe. For connected feedback with K positive, its exact solution is:
e∞ = a / λ
e(t₀ + Δt) = e∞ + [e(t₀) − e∞] exp(−λΔt)
T = 1 / λ
An interval equilibrium predicts what would happen if those inputs continued indefinitely. The reference moves for only four seconds, so its moving equilibrium may never occur. At 2 s and 4 s, carry the continuous position into the next interval and use the new inputs.
For K = 0 or a disconnected path, use de/dt = (1 − g)v − d. Error then changes linearly within each interval; there is no exponential correction. The code handles this branch without dividing by zero.
After the reference stops, connected feedback with positive K approaches e∞ = b − d/(gK). With zero feedback gain and nonzero d, the position keeps drifting and no finite error limit exists.
Follow unexpected drift through the hold
Use the defaults: g = 1, K = 1/s, b = 0, and x₀ = 0. Both axes track exactly until 2 s. Then a disturbance of −0.25 m/s starts.
For the connected axis, the reference-velocity term cancels because g = 1. From 2 s onward, de/dt = 0.25 − e, with e(2) = 0. Thus e(t) = 0.25[1 − exp(−(t − 2))] when the numerical time is in seconds.
At 6 s:
| Quantity | Open-loop axis | Connected axis |
|---|---|---|
| Reference position | 4 m | 4 m |
| True position | 3.000000 m | 3.754579 m |
| True error | 1.000000 m | 0.245421 m |
| Command | 0 m/s | +0.245421 m/s |
| Actual velocity | −0.250000 m/s | −0.004579 m/s |
The positive connected command nearly cancels the negative drift. At the long-time limit, a +0.25 m/s command exactly balances it, leaving a +0.25 m position error. Proportional correction needs that error to keep producing the balancing command.
At 4 s, the connected command drops by exactly 1 m/s because the reference velocity stops. The axis position does not jump. The command plot keeps separate curve segments at this change, so it does not draw a false gradual transition.
Separate gain mismatch from initial offset
Now set d = b = x₀ = 0 and use g = 0.75, K = 1/s. The open-loop axis covers only 3 m by 4 s and stays there. During the move, the connected error follows de/dt = 0.25 − 0.75e.
If motion continued forever, the connected error would approach 1/3 m. Once the target stops, the forcing term disappears and the remaining error decays toward zero. At 6 s the connected axis reaches 3.929326 m.
An initial position error behaves differently. Restore g = 1 with no disturbance or sensor bias, but start both axes at x₀ = +0.5 m. The open-loop axis keeps that +0.5 m lead through the move and hold.
The connected lead is 0.5 exp(−t) metres for K = 1/s. At 6 s it is only 0.001239 m. These cases show why a derivative or instantaneous velocity match alone does not establish correct position.
Judge feedback by physical tracking
Use an otherwise calibrated axis with b = +0.25 m and no disturbance. The sensor reports a position ahead of the true position, so the controller slows the axis. With g = K = 1 numerically, true error becomes 0.25[1 − exp(−t)] metres.
At 6 s, true position is 3.750620 m, while measured position is 4.000620 m. The measured error is −0.000620 m, even though true error is +0.249380 m. The calibrated open-loop axis remains exactly on the 4 m reference in this particular comparison.
Choose a control design around the task and available information:
- A stable, repeatable process with known starting conditions can use a calibrated schedule when its accuracy is sufficient.
- Position feedback can correct unplanned initial offsets and reduce drift within this model.
- Sensors add calibration, installation, and maintenance work. Their errors enter the correction itself.
- Feedback gains also need to respect delays, noise, actuator limits, and physical dynamics in the actual system.
This ideal axis includes none of those delays, velocity limits, inertias, or noisy samples. Its positive g and K always give stable first-order error dynamics. That result does not establish stability for a motor with actuator dynamics or a flexible joint.
Connect and disconnect the feedback path
The lab compares a permanently open-loop axis with the blue selected axis. Both start at the same chosen position and experience the same actual gain and disturbance. Changing a setting starts a new response from that initial condition; it does not switch the controller partway through an existing run.
- Start with Calibrated schedule. Both axes and the reference overlap. Feedback can be connected while its correction stays zero.
- Select Unexpected drift, then disconnect the feedback path. Both physical trajectories become identical. The sensor reading remains available for inspection.
- Select Incorrect velocity gain. Compare the tracking error during the move with its decay after 4 s.
- Select Biased position sensor. Compare true error with measured error before judging accuracy.
The plotted positions use the exact piecewise solution. Samples only draw the curves; their spacing is not a controller update period or integration step. Commands and velocities can jump in this model, while positions stay continuous.
Reproduce the comparison in Python
This standard-library example calculates each constant-input interval directly. It reports the same 6 s comparison as the presets and includes a disconnected measurement path. The long-time limits assume the final reference and disturbance continue beyond the eight-second plot.
from math import expm1
def compare(g=1.0, k=1.0, d=-0.25, bias=0.0, x0=0.0,
connected=True, time=6.0):
gain = k if connected else 0.0
rate = g * gain
error = -x0
for start, end, velocity, drift in [
(0.0, 2.0, 1.0, 0.0),
(2.0, 4.0, 1.0, d),
(4.0, 8.0, 0.0, d),
]:
elapsed = max(0.0, min(time, end) - start)
forcing = (1.0 - g) * velocity - drift + rate * bias
integral = elapsed if rate == 0 else -expm1(-rate * elapsed) / rate
error += (forcing - rate * error) * integral
reference = min(time, 4.0)
opened = x0 + g * reference + d * max(0.0, time - 2.0)
selected = reference - error
measured = selected + bias
command = (1.0 if time < 4.0 else 0.0) + gain * (error - bias)
return selected, opened, measured, command
cases = [
("calibrated", dict(d=0.0)),
("gain mismatch", dict(g=0.75, d=0.0)),
("drift", {}),
("initial offset", dict(d=0.0, x0=0.5)),
("sensor bias", dict(d=0.0, bias=0.25)),
("zero gain", dict(k=0.0)),
("disconnected", dict(connected=False)),
]
for name, settings in cases:
x, opened, measured, command = compare(**settings)
print(f"{name}: x={x:.6f}; open={opened:.6f}; "
f"measured={measured:.6f}; command={command:.6f}")
Expected output:
calibrated: x=4.000000; open=4.000000; measured=4.000000; command=0.000000
gain mismatch: x=3.929326; open=3.000000; measured=3.929326; command=0.070674
drift: x=3.754579; open=3.000000; measured=3.754579; command=0.245421
initial offset: x=4.001239; open=4.500000; measured=4.001239; command=-0.001239
sensor bias: x=3.750620; open=4.000000; measured=4.000620; command=-0.000620
zero gain: x=3.000000; open=3.000000; measured=3.000000; command=0.000000
disconnected: x=3.000000; open=3.000000; measured=3.000000; command=0.000000
The example supports the displayed 0–8 s interval. expm1(z) evaluates exp(z) − 1 accurately near zero, which keeps the response well behaved for a very small positive gain. Exact zero gain uses the linear branch.
Try it yourself
Exercise 1: follow a positive drift after the target stops
Use g = 1, K = 2/s, b = 0, x₀ = 0, and a +0.5 m/s disturbance starting at 2 s. Find both positions at 6 s and the connected axis's long-time true error and command.
Check your answer: Open-loop position is 4 + 0.5(6 − 2) = 6 m. The connected true error is −0.25[1 − exp(−8)] = −0.249916 m, so its position is 4.249916 m. Its command at 6 s is −0.499832 m/s.
The long-time true error is −0.25 m and command is −0.5 m/s. Multiplying that command by g and adding the +0.5 m/s disturbance gives zero actual velocity. The connected axis holds beyond the target because its negative position error supplies the balancing correction.
Exercise 2: disconnect a biased position measurement
Use the Biased position sensor preset at 6 s. Calculate true and measured errors with the path connected. Then disconnect it without changing the sensor bias. What happens to physical position, the displayed measurement, and the command?
Check your answer: With feedback connected, true position is 3.750620 m, true error is +0.249380 m, and measured error is −0.000620 m. The sensor reports 4.000620 m.
After starting a new run with the path disconnected, physical position is exactly 4 m and true error is zero. The sensor reports 4.25 m, so measured error is −0.25 m. The command is zero during the hold because the open-loop schedule ignores that measurement.
Displaying a measurement and using it to control motion are separate operations. This result depends on the otherwise calibrated axis and absence of disturbance in this preset.
Sources and further study
- Modern Robotics: Control System Overview explains the information flow through a controller, inner actuator loops, and simplifying assumptions for continuous control.
- Modern Robotics: Motion Control with Velocity Inputs, Part 1 derives proportional position control, contrasts moving and fixed references, and explains limits of the ideal velocity-input model.
- Modern Robotics: Motion Control with Velocity Inputs, Part 2 develops feedforward plus feedback. Its integral term extends the proportional-only controller used here.
Continue with transfer functions to describe the input-output relationships behind these trajectories. Keep the reference, disturbance, and measurement error separate as you build that representation.