Skip to the content
FixTheRobot Explore Robotics / UAV / Module 5 / M5-T14

UAV Systems Engineering · Module 5

M5-T14: Trajectory tracking

A trajectory is only as good as the controller that follows it. Feedforward and the thrust-vector construction turn a reference into attitude commands.

  • Lesson 14 of 17
  • UAV Guidance, Navigation and Control (GNC)
  • Established engineering
  • About 7 minutes to read

Planners hand over a time-parameterised reference; the tracking controller is what makes the vehicle follow it. A pure feedback controller always lags a moving reference. Adding the reference acceleration as feedforward removes most of that lag, and the thrust-vector construction connects the outer position loop to the attitude loop.

Learning objectives

After this lesson, you should be able to:

  • Write the position tracking law with feedback and acceleration feedforward and the closed-loop error dynamics.
  • Construct the desired thrust vector and the desired attitude from it, including the yaw reference.
  • Compute standard tracking error metrics.
  • Explain why the tracking error depends on the reference’s derivatives and the inner-loop bandwidth.

Conceptual explanation

Established The thrust-vector construction follows the geometric tracking control literature (Lee, Leok and McClamroch 2010) and common autopilot practice. Specific autopilots implement variants with different saturation and priority rules.

Given a reference pr(t)p_{r}(t) with derivatives vrv_{r} and ara_{r}, define the errors ep=p−pre_{p}=p-p_{r} and ev=v−vre_{v}=v-v_{r}. A PD law with acceleration feedforward commands

Tracking law (acceleration command)
acmd=ar−Kp ep−Kv ev\mathbf a_{\text{cmd}} = \mathbf a_r - K_p\,\mathbf e_p - K_v\,\mathbf e_v

With the inner loops fast enough to treat the commanded acceleration as achieved, the error obeys e¨p+Kv e˙p+Kp ep=0\ddot{e}_{p}+K_{v}\,\dot{e}_{p}+K_{p}\,e_{p}=0, a linear, exponentially stable system with no dependence on the trajectory. Without the feedforward term the error obeys the same equation driven by −ara_{r}, so the tracking error is proportional to the reference acceleration.

Trajectory tracking loopA trajectory supplies position, velocity, acceleration and yaw as functions of time. The tracking controller combines feedback on the position error with feedforward of the reference acceleration, producing a desired thrust vector, from which the attitude controller takes its reference.Trajectoryp, v, a, ψ (t)Errore_p, e_vForce lawfeedback + feedforwardThrust vectorattitude refAttitude / rateinner loopsFeedforward of the reference acceleration removes most of the lag error on curved paths.
The reference enters twice: as error comparison and as acceleration feedforward.
Animation of two vehicles tracking a circular reference, one with feedback only and one with feedback plus feedforward of the reference acceleration. Both start on the circle. The feedback-only vehicle runs on a smaller circle and lags behind the reference point; the feedforward vehicle stays close. A strip plots the tracking error of both over time, and the printed rms errors differ by a large factor.
Tracking law acmd=aref−Kp ep−Kv eva_{\text{cmd}}=a_{\text{ref}}-K_{p}\,e_{p}-K_{v}\,e_{v}: without arefa_{\text{ref}} the error is driven by the reference acceleration and the vehicle lags in proportion to it. A first-order lag of 0.1 s between commanded and achieved acceleration models the inner loops. Circle of radius 5 m at 0.6 rad/s; computed. (Looping, about 6 seconds; drawn and computed for this course with illustrative values.)

Engineering intuition

Chasing a car by only looking at the gap always leaves you behind: you accelerate when the gap has already opened. Knowing the car’s planned acceleration lets you accelerate at the same moment. That is feedforward. With it the feedback only has to correct disturbances and model errors, so the gains can be modest and the response smooth.

The outer loop cannot be faster than the inner. If the attitude loop takes 0.15 s to realise a commanded tilt, the position loop assumes a wrong acceleration for that long. Tracking aggressive references demands bandwidth in the inner loops, or a reference whose derivatives stay within what they deliver.

Mathematical formulation

For a multirotor with mass mm, total thrust TT along the body zz axis and the world frame with zz up, m p¨=T R e3−m g e3m\,\ddot{p}=T\,R\,e_{3}-m\,g\,e_{3}. The desired thrust vector from the commanded acceleration is

Desired thrust vector and body z axis
Fdes=m(acmd+g e3)\mathbf F_{\text{des}} = m\left(\mathbf a_{\text{cmd}} + g\,\mathbf e_3\right)
T=∥Fdes∥,b3,des=Fdes∥Fdes∥T = \lVert\mathbf F_{\text{des}}\rVert, \qquad \mathbf b_{3,\text{des}} = \frac{\mathbf F_{\text{des}}}{\lVert\mathbf F_{\text{des}}\rVert}

Given a desired yaw ψr\psi _{r}, the other axes follow from a heading vector c=(cos⁡ ψr, sin⁡ ψr, 0)c=(\cos \,\psi _{r},\,\sin \,\psi _{r},\,0):

Desired attitude from thrust direction and yaw
b2,des=b3,des×c∥b3,des×c∥,b1,des=b2,des×b3,des\mathbf b_{2,\text{des}} = \frac{\mathbf b_{3,\text{des}}\times\mathbf c}{\lVert\mathbf b_{3,\text{des}}\times\mathbf c\rVert}, \qquad \mathbf b_{1,\text{des}} = \mathbf b_{2,\text{des}}\times\mathbf b_{3,\text{des}}
Rdes=[b1,desb2,desb3,des]\mathbf R_{\text{des}} = \begin{bmatrix}\mathbf b_{1,\text{des}} & \mathbf b_{2,\text{des}} & \mathbf b_{3,\text{des}}\end{bmatrix}

The construction is singular when b3, desb_{3,\,\text{des}} is parallel to cc, which is only the case when the desired thrust is horizontal (more than 90∘90^{\circ} of tilt, outside any normal envelope). Practical autopilots limit the tilt and prioritise the thrust direction over yaw when the limit is reached. Common metrics for evaluating tracking are the RMS and maximum position error:

Tracking error metrics
erms=1N∑k∥pk−pr,k∥2e_{\text{rms}} = \sqrt{\frac{1}{N}\sum_k\lVert\mathbf p_k - \mathbf p_{r,k}\rVert^{2}}
emax⁡=max⁡k∥pk−pr,k∥e_{\max} = \max_k\lVert\mathbf p_k - \mathbf p_{r,k}\rVert
KpK_{p}, KvK_{v}
position and velocity gains (1/s2, 1/s)(1/s^{2},\,1/s).
b3b_{3},des
desired body zz axis (thrust direction).
ψr\psi _{r}
reference yaw angle.

Architecture and data flow

Trajectory generator (or planner) → sample prp_{r}, vrv_{r}, ara_{r}, ψr\psi _{r} at the controller’s rate → position controller (feedback plus feedforward) → thrust magnitude and desired attitude → attitude controller → rate controller → motor mixer. The estimator supplies pp and vv; its latency and noise enter the error directly, so tracking performance cannot be better than estimation quality allows. In PX4 offboard mode the trajectory setpoint message carries position, velocity and acceleration fields, so feedforward terms can be supplied (check the documentation of your version for how they are combined).

Real-world UAV applications

  • Following minimum-snap trajectories in aggressive flight.
  • Inspection paths with a required position accuracy.
  • Formation and coordinated flight following reference time laws.
  • Testing controllers by comparing error metrics on standard figure-eight references.

Implementation example

This runs as shown. A point-mass model with a first-order lag (0.1 s) between commanded and achieved acceleration tracks a circle of radius 5 m at 3 m/s. The test shows that feedforward of the reference acceleration reduces the RMS error, and checks the thrust-vector construction gives an orthonormal RdesR_{\text{des}} with the right thrust direction.

import numpy as np

def ref(t, r=5.0, w=0.6):
    return (np.array([r * np.cos(w * t), r * np.sin(w * t)]), np.array([-r * w * np.sin(w * t), r * w * np.cos(w * t)]),
            np.array([-r * w * w * np.cos(w * t), -r * w * w * np.sin(w * t)]))
def run(ff, Kp=9.0, Kv=6.0, tau=0.1, dt=0.005, T=20.0):
    p, v, a = np.array([5.0, 0.0]), np.array([0.0, 3.0]), np.array([-1.8, 0.0]); errs = []
    for k in range(int(T / dt)):
        pr, vr, ar = ref(k * dt)
        a_cmd = (ar if ff else 0.0) - Kp * (p - pr) - Kv * (v - vr)
        a += (a_cmd - a) / tau * dt; v = v + a * dt; p = p + v * dt            # first-order lag between commanded and achieved acceleration
        if k * dt > 5: errs.append(np.linalg.norm(p - pr))
    return np.sqrt(np.mean(np.square(errs))), max(errs)
(r0, m0), (r1, m1) = run(False), run(True)
print(f"RMS error without feedforward {r0:.3f} m, with feedforward {r1:.3f} m (max {m1:.3f} m)")
assert r1 < 0.5 * r0
def desired_attitude(a_cmd, yaw, m=1.5, g=9.81):
    F = m * (a_cmd + np.array([0, 0, g])); b3 = F / np.linalg.norm(F)
    c = np.array([np.cos(yaw), np.sin(yaw), 0.0]); b2 = np.cross(b3, c); b2 /= np.linalg.norm(b2); b1 = np.cross(b2, b3)
    return np.column_stack([b1, b2, b3]), np.linalg.norm(F)
R, T = desired_attitude(np.array([2.0, -1.0, 0.5]), 0.7)
print(f"thrust {T:.2f} N, orthonormal: {np.allclose(R.T @ R, np.eye(3), atol=1e-12)}, det {np.linalg.det(R):.3f}")
assert np.allclose(R.T @ R, np.eye(3), atol=1e-12) and abs(np.linalg.det(R) - 1) < 1e-12 and np.allclose(R[:, 2] * T, 1.5 * np.array([2.0, -1.0, 10.31]))
Tracking a circle with and without acceleration feedforward, and the desired-attitude construction.

Common engineering mistakes

No feedforward on curved references

Constant lag proportional to the reference acceleration.

Time-base mismatch

The reference is sampled with a different clock than the estimate; the error contains a time offset times the velocity.

Aggressive reference beyond inner-loop bandwidth

Position error grows and the vehicle cuts corners.

Yaw reference with a discontinuity

A 359∘→1∘A\,359^{\circ}\to 1^{\circ} wrap commands a full turn; wrap the yaw error to ±π\pi .

Ignoring tilt and thrust limits

The commanded acceleration cannot be produced; saturate and prioritise explicitly.

Failure modes

Failure modes, symptoms and causes
Failure modeHow it shows upLikely cause
Steady lag behind the referenceConstant offset along the pathMissing feedforward, or latency in the reference or estimate
Oscillation in trackingGrowing wobble at high speedOuter-loop gain too high relative to inner-loop bandwidth
Altitude sag in turnsLoss of height in banked turnsThrust magnitude not compensated for tilt; thrust saturation
Yaw spins at the wrapSudden full rotationUnwrapped yaw error

Debugging approach

  1. Plot position error against time and against reference acceleration: correlation indicates missing feedforward.
  2. Check the clocks: shift the reference by Δt\Delta t and see whether the error decreases.
  3. Plot commanded against achieved tilt to measure inner-loop lag.
  4. Check thrust and tilt saturation flags in the log.

Practical exercises

  1. Sweep the circular reference angular rate from 0.3 to 1.2 rad/s and plot the RMS error with and without feedforward.
  2. Add a 50 ms estimation delay and show the effect on the RMS error.
  3. Increase the lag to 0.3 s and tune the gains to restore stability.
  4. Implement tilt saturation at 30∘30^{\circ} and report the change in tracking error at 1.2 rad/s.

Interview questions

Write an answer in your own words, then reveal the model answer. Nothing is sent anywhere.

Question 1

Why add acceleration feedforward?

Model answer

Feedback acts only after an error has appeared, so a pure PD controller lags a moving reference by an amount proportional to its acceleration. Feedforward supplies the acceleration needed at the moment it is needed.

Question 2

How is the desired attitude computed from the desired acceleration?

Model answer

The desired thrust vector m(a+g e3)m(a+g\,e_{3}) gives the body zz axis and the thrust magnitude; a yaw reference fixes the remaining rotation about that axis through cross products.

Question 3

What limits how aggressive a reference can be tracked?

Model answer

Actuator and tilt limits, inner-loop bandwidth and estimation quality: the achieved acceleration must follow the commanded one.

References and further reading

Primary papers, official documentation and standards. Each claim above that is specific to a tool or version points here.

What’s next

Mark this lesson

Saved in this browser and synced to your account when you are signed in.

Practice this lesson

M5-L3: Implement MPC trajectory tracking

Tune horizon and constraints for tracking.

Practice this lesson

M5-L8: Evaluate tracking errors

Compute RMS and maximum tracking error.

Next lesson

M5-T15: Guidance and control integration

Define the interface between planner and controller (rates, frames, smoothness) and avoid the oscillations caused by mismatched assumptions.