Jets of flat outputs¶
This page defines the jet, states its basic operations, and documents
udaan.flatness.Jet — the Python container that every
flat-to-state map in udaan takes as input.
Formal definition¶
Let \(y : \mathbb{R} \to \mathbb{R}^m\) be a \(C^q\)-smooth signal (for example, the flat output of a differentially flat system). Fix a time \(t_0 \in \mathbb{R}\).
Definition 1 (Jet of a signal at a point)
The \(q\)-th order jet of \(y\) at \(t_0\) is the tuple
The jet space is the set of all such tuples; we write it \(J^q \mathbb{R}^m\).
Two signals agree “to order \(q\)” at \(t_0\) iff their \(q\)-jets at \(t_0\)
are equal. This is an equivalence relation, and the equivalence class
is what the differential-geometry literature calls the abstract jet
(Wikipedia’s Jet (mathematics)
article defines it as the truncated Taylor polynomial
\(\sum_{k=0}^{q} y^{(k)}(t_0) z^k / k!\), which is a canonical
representative of that class). Throughout udaan we store and
manipulate the derivative-tuple representation in
Definition 1 — the convention used in the applied flatness and
controls literature (Fliess, Lévine, et al.
[1][2]). The two encodings
carry identical information: the raw-derivative tuple and the Taylor
polynomial are related by the diagonal scaling \(1/k!\).
Operations on jets¶
Thinking of the flat-to-state map as a map between jet spaces earns access to a small toolkit of natural operations. Three that show up repeatedly in flatness work:
Definition 2 (Differentiation of a jet)
For \(J^q_{t_0} y = (y, \dot y, \dots, y^{(q)})\), the time-derivative jet is the \((q{-}1)\)-order jet obtained by shifting every entry one position down:
Definition 3 (Truncation)
For \(k \leq q\), the truncation drops all derivatives above order \(k\):
Definition 4 (Prolongation)
Going the other way requires knowing the dynamics — given \(J^q_{t_0} y\), the prolongation produces \(J^{q+1}_{t_0} y\) by differentiating \(y^{(q)}\) using the system’s ODE. In a flat system, this is always algebraically well-defined.
Truncation and differentiation are always available; prolongation requires side information (the dynamics). In code, the first two are simple array slices; the third is the substantive content of each per-system flat-to-state map.
The flat-to-state map, rewritten¶
With jets as first-class objects, equation (10) from the parent page reads as a map between jet spaces:
Every system in Differential flatness provides its own \(\Phi\). The input type is always a jet (or a collection of jets, one per component of the flat output); the output is the full recovered state plus the feedforward input.
The Jet class¶
udaan exposes jets as the udaan.flatness.Jet
dataclass. Storage is a 2-D numpy array of shape
\((\text{order} + 1,\; \text{dim})\); row \(k\) is the \(k\)-th time
derivative of the signal.
Construction¶
Vector signals (e.g. a 3-D position trajectory, up to snap):
from udaan.flatness import Jet
import numpy as np
x = Jet(np.stack([
position, # row 0 → y
velocity, # row 1 → ẏ
acceleration, # row 2 → ÿ
jerk, # row 3 → y⁽³⁾
snap, # row 4 → y⁽⁴⁾
]))
x.order # 4
x.dim # 3
x[2] # ndarray(3,) — acceleration
Scalar signals (e.g. a yaw angle) may be constructed from a 1-D
array of length order + 1; the jet promotes it to 2-D with
dim == 1:
psi = Jet(np.array([psi_0, psi_dot_0, psi_ddot_0]))
psi.order # 2
psi.dim # 1
psi[1] # float — yaw rate (scalar unwrapped by __getitem__)
Factory helpers:
Jet.zeros(order=4, dim=3) # zero-initialised
Jet.from_list([pos, vel, acc]) # stack derivatives from a Python list
Accessors¶
Order \(k\) |
Accessor |
Standard name |
|---|---|---|
0 |
|
position / value |
1 |
|
velocity |
2 |
|
acceleration |
3 |
|
jerk |
4 |
|
snap (a.k.a. jounce) |
5 |
|
crackle |
6 |
|
pop |
Each raises AttributeError if the jet’s order is below the
requested derivative. For orders beyond pop, use numerical indexing
(jet[7], jet[8], …) — the flexible \(N\)-link cable derivation needs
this at \(q = 2N + 2\).
Transformations¶
Reflecting Definition 2 and Definition 3:
jet.differentiate() # shift down by one → J^{q-1}(ẏ)
jet.truncate(k) # drop derivatives above order k
Numpy interop¶
np.asarray(jet) # returns the underlying (order+1, dim) array
jet.data # direct access (same array, no copy)
See also¶
Differential flatness — differential-flatness definition and per-system flat outputs.
Preliminaries — SO(3)/S² conventions used in the recovered states.