udaan.flatness package

Submodules

Module contents

Differential-flatness state recovery for the systems in udaan.

Central type

Jet — a value and all its time derivatives up to some order, used as the input to every flat-to-state map in this package.

Per-system maps

Quadrotor — flat-to-state recovery for a rigid-body quadrotor with flat output (x_Q, ψ).

QuadrotorCsPayload — flat-to-state recovery for a quadrotor with a cable-suspended point-mass payload, with flat output (x_L, ψ).

class udaan.flatness.Flat2State[source]

Bases: object

Differential-flatness map for a specific robotic system.

Subclass contract:
  • Declare three dataclasses as class attributes:

    Flats flat-output derivative bundle at a single time RefState recovered kinematic reference state Inputs recovered feedforward inputs

  • Implement recover(self, flats) -> (RefState, Inputs).

Optional: provide a from_model(cls, model) classmethod that reads physical parameters off the corresponding simulation model.

Intermediate abstract classes (ones that only partially specify the triple and are subclassed again before instantiation) can opt out of the declaration check with _abstract = True.

Flats: ClassVar[type]
Inputs: ClassVar[type]
RefState: ClassVar[type]
recover(flats)[source]

Map flat-output derivatives to (reference state, feedforward inputs).

Subclasses must override.

class udaan.flatness.Jet[source]

Bases: object

Time-derivative tuple (y, ẏ, ÿ, …) of a signal at a single time.

Parameters:

data (ndarray) – Either a 1-D array of shape (order+1,) — which promotes to a scalar jet with dim == 1 — or a 2-D array of shape (order+1, dim). Dtype is coerced to float64.

data

2-D numpy array of shape (order+1, dim).

Examples

Scalar signal (e.g. yaw angle with three derivative levels):

>>> psi = Jet(np.array([0.0, 0.1, 0.2]))
>>> psi.order
2
>>> psi.dim
1
>>> psi[1]
0.1

Vector signal (e.g. position with four derivative levels):

>>> x = Jet(np.stack([[0, 0, 1], [1, 0, 0], [0, 0, 0], [0, 0, 0]], axis=0))
>>> x.order
3
>>> x.dim
3
>>> x[1]
array([1., 0., 0.])
__init__(data=<factory>)
property acceleration: float | ndarray
property crackle: float | ndarray
data: ndarray
differentiate()[source]

Shift derivatives down by one level and return a new jet.

Given J = (y, ẏ, ÿ, …, y⁽ᵒʳᵈᵉʳ⁾) returns J' = (ẏ, ÿ, …, y⁽ᵒʳᵈᵉʳ⁾) — i.e. the jet of the time derivative of the original signal, with order reduced by one.

Return type:

Jet

property dim: int

Signal dimension; data.shape[1] (1 for scalar signals).

classmethod from_list(derivatives)[source]

Construct from an explicit list of derivative arrays/scalars.

Return type:

Jet

Examples

>>> Jet.from_list([pos, vel, acc, jerk, snap])
property is_scalar: bool

True if the signal is scalar (dim == 1).

property jerk: float | ndarray
property order: int

Highest derivative index stored; data.shape[0] - 1.

property pop: float | ndarray
property snap: float | ndarray
truncate(new_order)[source]

Drop derivatives above new_order and return a new jet.

Return type:

Jet

property value: float | ndarray
property velocity: float | ndarray
classmethod zeros(order, dim=1)[source]

A jet of all zeros with the given order and dim.

Return type:

Jet

class udaan.flatness.Quadrotor[source]

Bases: Flat2State

Differential-flatness recovery for the single rigid-body quadrotor.

Flats

alias of QuadrotorFlats

Inputs

alias of QuadrotorInputs

RefState

alias of QuadrotorRefState

__init__(mass, inertia)[source]
classmethod from_model(model)[source]

Build from a udaan.models.quadrotor.QuadrotorBase-like model.

Return type:

Quadrotor

recover(flats)[source]

Map flat-output derivatives to (reference state, feedforward inputs).

Subclasses must override.

Return type:

tuple[QuadrotorRefState, QuadrotorInputs]

class udaan.flatness.QuadrotorCsPayload[source]

Bases: Flat2State

Differential-flatness recovery for a quadrotor with a cable-suspended, point-mass payload (taut cable, single rigid-body quadrotor).

Flats

alias of QuadrotorCsPayloadFlats

Inputs

alias of QuadrotorCsPayloadInputs

RefState

alias of QuadrotorCsPayloadRefState

__init__(*, mass_q=0.9, mass_l=0.2, inertia=array([[0.0023, 0., 0.], [0., 0.0023, 0.], [0., 0., 0.004]]), cable_length=1.0, gravity=9.81)[source]
classmethod from_model(model)[source]

Build from a udaan.models.quadrotor_cspayload.QuadrotorCsPayloadBase-like model.

Return type:

QuadrotorCsPayload

recover(flats)[source]

Map flat-output derivatives to (reference state, feedforward inputs).

Subclasses must override.

Return type:

tuple[QuadrotorCsPayloadRefState, QuadrotorCsPayloadInputs]

class udaan.flatness.QuadrotorCsPayloadFlats[source]

Bases: object

Flat output of a quadrotor with cable-suspended payload: payload-position jet (order ≥ 6) and yaw-angle jet (order ≥ 2).

x_L

dim-3 Jet of the payload position, with derivatives through pop (order ≥ 6) — q^(4) and hence the moment feedforward consume the 6th derivative of x_L.

psi

scalar Jet of the yaw angle, with derivatives through yaw acceleration (order ≥ 2).

__init__(x_L, psi)
psi: Jet
x_L: Jet
class udaan.flatness.QuadrotorCsPayloadInputs[source]

Bases: object

Feedforward inputs recovered from the flat output.

thrust

collective thrust magnitude f.

moment

body-frame moment M.

tension

cable tension T = m_L ‖ẍ_L + g e_3‖. Falls out of the Newton–Euler form of Step 1 in the recovery; useful as a slack-cable diagnostic (T 0 marks the hybrid-mode boundary at which the cable goes slack).

__init__(thrust=0.0, moment=<factory>, tension=0.0)
moment: NDArray[floating]
tension: float = 0.0
thrust: float = 0.0
class udaan.flatness.QuadrotorCsPayloadRefState[source]

Bases: object

Recovered kinematic reference state for a quadrotor with cable-suspended payload.

Field naming mirrors udaan.models.quadrotor_cspayload.base.QuadrotorCsPayloadState where the two overlap; acceleration, payload_acceleration, and angular_acceleration are extras that the flatness map also produces.

__init__(payload_position=<factory>, payload_velocity=<factory>, payload_acceleration=<factory>, position=<factory>, velocity=<factory>, acceleration=<factory>, cable_attitude=<factory>, cable_angular_velocity=<factory>, cable_angular_acceleration=<factory>, orientation=<factory>, angular_velocity=<factory>, angular_acceleration=<factory>)
acceleration: NDArray[floating]
angular_acceleration: NDArray[floating]
angular_velocity: TSO3
as_state()[source]

Project onto the model’s QuadrotorCsPayloadState shape (drops all *_acceleration extras; wraps cable fields as S2/TS2).

cable_angular_acceleration: NDArray[floating]
cable_angular_velocity: NDArray[floating]
cable_attitude: NDArray[floating]
orientation: SO3
payload_acceleration: NDArray[floating]
payload_position: NDArray[floating]
payload_velocity: NDArray[floating]
position: NDArray[floating]
velocity: NDArray[floating]
class udaan.flatness.QuadrotorFlats[source]

Bases: object

Flat output of a rigid-body quadrotor: position jet (order ≥ 4) and yaw-angle jet (order ≥ 2).

x

dim-3 Jet of the centre-of-mass position, with derivatives through snap (order ≥ 4).

psi

scalar Jet of the yaw angle, with derivatives through yaw acceleration (order ≥ 2).

__init__(x, psi)
psi: Jet
x: Jet
class udaan.flatness.QuadrotorInputs[source]

Bases: object

Feedforward inputs recovered from the flat output.

__init__(thrust=0.0, moment=<factory>)
moment: NDArray[floating]
thrust: float = 0.0
class udaan.flatness.QuadrotorRefState[source]

Bases: object

Recovered kinematic reference state for a quadrotor.

The first four fields mirror udaan.models.quadrotor.base.QuadrotorState; acceleration and angular_acceleration are extras that the flatness map also makes available.

__init__(position=<factory>, velocity=<factory>, acceleration=<factory>, orientation=<factory>, angular_velocity=<factory>, angular_acceleration=<factory>)
acceleration: NDArray[floating]
angular_acceleration: NDArray[floating]
angular_velocity: TSO3
as_state()[source]

Project onto the model’s QuadrotorState shape (drops acceleration + angular_acceleration).

orientation: SO3
position: NDArray[floating]
velocity: NDArray[floating]