Oragnization

Primary methods for generating integrated-sensor outputs are provided in hitman.gyro. For example, hitman.gyro.functional_factory().

Exponential coordinates are used when representing group elements of \(SO(3)\) through the class hitman.rotation.LieExponential.

Notation

A brief note on vairable names. Subscripts precede superscripts. For example, \(x_a^b\) should receive a variable name x_a_b.

Preference is to local-to-global rotations.

We take the contentious stand that names of matrix-valued variables may begin with capital letters.

Modules

Autogenerated documentation for included modules:

gyro

The gyro module collects gyro measurement and solution functions

Direct parametric relationship between instantaneous rate and attitude are elusive. Consider the relationships

\[\begin{split}\dot{\phi} &= \left(J_\phi^r\right)^{-1} \omega^r\\ \Delta R(t) &= \exp\big(-\phi(t-\tau)\big)\exp\big(\phi(t)\big) \\ \Delta \theta &= \int_{t-\tau}^t \omega^r(s) ds\end{split}\]

If \(\omega\) is defined as a polynomial, then \(\Delta \theta\) is available directly. However, \(\phi\) must be solved numerically. Conversely, if \(\phi\) is defined as a polynomial then \(\Delta R\) is available directly. However, \(\Delta \theta\) must then be solved numerically.

The following functions provide consistent expressions for \(\Delta R\) and \(\Delta \theta\). They can be specified from a single polynomial expression for either \(\omega\) or \(\phi\). The approach is wrapped in hitman.gyro.functional_factory().

hitman.gyro.delta_R_from_phi(t, tau, phi=None)[source]

Direct evaluation of \(\Delta R\) from \(\phi\) functional

\[\Delta R = \exp\left(-\phi(t - \tau)\right) \exp\left(\phi(t)\right)\]
Parameters:
  • t – time (end of integration)

  • tau – integration interval

  • phi (Callable[[float], ndarray]) – functional of attitude \(\phi : \mathbb{R}\rightarrow \mathbb{R}^3\)

Returns:

\(\Delta R \in SO(3)\).

hitman.gyro.delta_phi_from_omega(t, tau, omega=None, Jinv=SO.J_r_inv, **kwargs)[source]

Numerically solve attitude update

Solve the ODE

\[\Delta \dot{\phi} = J_\phi^{-1} \omega\]

for \(\Delta \phi(t)\) from \(\Delta \phi(t-\tau) = 0\)

Parameters:
  • t – final time

  • tau – integration period

  • omega (Callable[[float], ndarray]) – functional of instantaneous rate \(\omega : \mathbb{R}\rightarrow \mathbb{R}^3\)

  • Jinv (Callable[[ndarray], ndarray]) – functional \(J^{-1} : \mathbb{R}^N\rightarrow \mathbb{R}^{N\times N}\)

Returns:

\(\Delta R \in SO(3)\)

hitman.gyro.delta_theta_from_omega(t, tau, omega=None, **kwargs)[source]

Compute delta-theta from omega functional

Integrated rate is defined as the lagged integral

\[\Delta \theta = \int_{t-\tau}^{t} \omega(s) ds\]

Will compute integral directly if omega is a scipy.interpolate.BPoly. Othwerwise, will compute numerically using hitman.integrate.delta_functional().

Parameters:
  • t (float) – final time

  • tau (float) – integration period

  • omega (Callable[[float], ndarray]) – functional of instantaneous rate \(\omega : \mathbb{R}\rightarrow \mathbb{R}^3\)

  • **kwargs – keyword arguments passed to hitman.integrate.delta_functional().

Return type:

ndarray

hitman.gyro.functional_factory(f, is_omega)[source]
Generate functionals for \(\Delta R\), \(\Delta \theta\) and

\(\omega\)

Input is a polynomial expression for either \(\omega\) or \(\phi\). Returns a consistent set of functionals for integrated values.

Parameters:
  • f (BPoly) – polynomial expression for either \(\omega\) or \(\phi\)

  • is_omega (bool) – if true, interpret f as \(\omega\)

Return type:

Tuple[Callable[[float, float], ndarray], Callable[[float, float], ndarray], Callable[[float], ndarray]]

Returns:

functionals \(\Delta \theta (t,\tau)\), \(\Delta R (t,\tau)\),

\(\omega (t)\)

hitman.gyro.omega_from_phi(t, phi=None, phidot=None, J=SO.J_r)[source]

functional representation of instantaneous rate

Instantaneous rate is obtained by inverting the Bortz equation

\[\omega = J_\phi \dot{\phi}\]
Parameters:
  • t – time to evaluate

  • phi (Callable[[float], ndarray]) – functional of attitude \(\phi : \mathbb{R}\rightarrow \mathbb{R}^3\)

  • phidot (Callable[[float], ndarray]) – functional of attitude rate \(\dot{\phi} : \mathbb{R}\rightarrow \mathbb{R}^3\)

  • J – Jacobian associated with omega (right vs. left). Default: right.

Returns:

instantaneous rate functional

\(\omega : \mathbb{R}\rightarrow \mathbb{R}^3\)

hitman.gyro.phi_factory(phi0, t0, omega, Jinv=SO.J_r_inv, **kwargs)[source]

Generate functional for rotation in exponential coordinates

Provide \(\phi(t)\) which solves the Bortz equation [Bor71] numerically.

Parameters:
  • phi0 (ndarray) – Initial attitude

  • t0 (float) – Initial time

  • omega (Callable[[float], ndarray]) – functional \(\omega^r : \mathbb{R} \rightarrow \mathbb{R}^3\)

  • Jinv (Callable[[ndarray], ndarray]) – functional \(J^{-1} : \mathbb{R}^N\rightarrow \mathbb{R}^{N\times N}\)

  • max_step – maximum step size for numeric solver

  • **kwargs – additional keyword arguments passed to hitman.ode.solve_numeric()

Return type:

Callable[[float], ndarray]

Returns:

functional providing attitude \(\phi : \mathbb{R} \rightarrow \mathbb{R}^3\)

rotation

rotation module for special orthogonal groups, e.g. \(SO(3)\)

class hitman.rotation.Cartesian

Bases: object

Rotations about Cartesian axes

Active, right-hand rotations [SGB+18].

static x(theta)[source]

Return the rotation matrix about the x-axis

\[\begin{split}R_x(\theta) = \begin{pmatrix} 1 & 0 & 0 \\ 0 & \cos(\theta) & -\sin(\theta) \\ 0 & \sin(\theta) & \cos(\theta) \end{pmatrix}\end{split}\]
Parameters:

theta (float) – radians

Return type:

matrix

Returns:

Rotation matrix, \(SO(3)\)

static y(theta)[source]

Return the rotation matrix about the y-axis

\[\begin{split}R_y(\theta) = \begin{pmatrix} \cos(\theta) & 0 & \sin(\theta) \\ 0 & 1 & 0 \\ -\sin(\theta) & 0 & \cos(\theta) \end{pmatrix}\end{split}\]
Parameters:

theta (float) – radians

Return type:

matrix

Returns:

Rotation matrix, \(SO(3)\)

static z(theta)[source]

Return the rotation matrix about the z-axis

\[\begin{split}R_z(\theta) = \begin{pmatrix} \cos(\theta) & -\sin(\theta) & 0 \\ \sin(\theta) & \cos(\theta) & 0 \\ 0 & 0 & 1 \end{pmatrix}\end{split}\]
Parameters:

theta (float) – radians

Return type:

matrix

Returns:

Rotation matrix, \(SO(3)\)

class hitman.rotation.LieExponential(theta=None, M=None, **kwargs)

Bases: LieGroup

Rotation group with exponential coordinates

Retains group element in matrix form as property M

Note, if constructed using a matrix, no error-checking is applied to ensure the input is indeed a group element (othonormal).

Several operations are retained as static methods which can be called without construction.

static Ad(R, X)[source]

Adjoint operator is a group-parameterized linear operator of the algebra

Parameters:
  • R (matrix) – group element \(SO(3)\)

  • X (matrix) – algebra element \(so(3)\)

Return type:

matrix

Returns: algebra element \(so(3)\)

static J_l(x, right=False)[source]

left-Jacobian for exponential coordinates

(See [Chi12] eq. 10.86)

Parameters:
  • x (ndarray) – vector representation of Lie algebra

  • right – optionally compute right-Jacobian

Return type:

ndarray

Returns:

General linear group, \(\mathbb{R}^{3\times 3}\)

See also

static J_l_dot(x, xdot, right=False)[source]

time-derivative of Jacobian for exponential coordinates

Parameters:
  • x (ndarray) – vector representation of Lie algebra

  • xdot (ndarray) – time-derivative of Lie algebra exponential coordinates

  • right (bool) – optionally compute right-Jacobian

Return type:

matrix

Returns:

General linear group \(\mathbb{R}^{3\times 3}\)

static J_l_inv(x, right=False)[source]

inverse left-Jacobian for exponential coordinates

See [Chi12] eq. 10.86

Parameters:
  • x (array) – vector representation of Lie algebra

  • right – optionally compute right-Jacobian

Return type:

matrix

Returns:

inverse-Jacobian of exp at x

See also

static J_r(theta)[source]

Right-Jacobian for exponential coordinates

See [Chi12] eq. 10.86

Parameters:

x – vector representation of Lie algebra

Return type:

matrix

Returns:

Jacobian of exp at x

See also

static J_r_dot(x, xdot)[source]

time-derivative of right-Jacobian for exponential coordinates

Parameters:
  • x (ndarray) – vector representation of Lie algebra

  • xdot (ndarray) – time-derivative of Lie algebra exponential coordinates

  • right – optionally compute right-Jacobian

Return type:

matrix

Returns:

General linear group \(\mathbb{R}^{3\times 3}\)

static J_r_inv(theta)[source]

Inverse right-Jacobian at exponential coordinates

See [Chi12] eq. 10.86

Parameters:

theta (array) – exponential coordinates (vector)

Return type:

matrix

Returns:

Inverse right-Jacobian

See also

static exp(theta)[source]

Exponential operation for so in vector form, returns group element

Parameters:

theta (array) – Element of Lie algebra of \(so(2)\) or \(so(3)\) as a vector

Raises:

Exception – if dimensions are incorrect

Return type:

matrix

Returns:

Group element of \(SO(2)\), \(SO(3)\)

static hat(theta)[source]

hat operator mapping \(\mathbb{R}^n \rightarrow so(n)\)

Parameters:

theta (array) – exponential coordinate parameterization

Return type:

matrix

Returns:

Element of Lie algebra (\(so(2)\) or \(so(3)\))

static log(X)[source]
Log of group element, \(SO(3)\rightarrow \mathbb{R}^3\)

or \(SO(2)\rightarrow \mathbb{R}\)

Parameters:

X (array) – group element

Return type:

ndarray

Returns:

vector

static vee(M, tol=1e-15)[source]

vee operator mapping \(so(n) \rightarrow \mathbb{R}^n\)

Parameters:
  • M (matrix) – Element of Lie algebra (\(so(2)\) or \(so(3)\))

  • tol (float) – tolerance for checking skew-symmetry

Return type:

array

Returns:

vector parameterization

lie

General Lie-theoretic tools for associating Lie groups with Lie algebras.

Note, Lie groups extend beyond rotations [Chi12].

See also

rotation

class hitman.lie.LieGeneric[source]

Generic, brute-force, methods for Lie groups

Analytic expressions are available for specific Lie groups (e.g. \(LieSO(3)\)) which are typically more efficient computationally.

static dexp(A, C, order=20)[source]

Left-Jacobian at \(A\) applied to \(C\)

\(A,C\) are in the Lie algebra.

Left indicates derivative appears on the left (c.f. (2.42) Iserles et al. [IMKNorsettZ00])

\[\operatorname{dexp}(A,C) = \left(\frac{d}{dt} \exp(A)\right) \exp(A)^{-1}\]

where

\[C = A' (t)\]

For the commutator expansion, see (2.44) in Iserles et al. [IMKNorsettZ00].

Parameters:
  • A (matrix) – algebra elements

  • C (matrix) – algebra elements

  • order (int) – series order to evaluate

Return type:

matrix

Returns:

algebra element.

static exp(A)[source]

Matrix exponential

Return type:

matrix

class hitman.lie.LieGroup[source]

Lie groups base for building efficient, coordinate-depenedent implementations

See also hitman.rotation.LieExponential

abstractmethod static Ad(R, X)[source]

Adjoint operator is a group-parameterized linear operator of the algebra

Parameters:
  • R (array) – group element

  • X (array) – algebra element

Return type:

array

Returns: algebra element

abstractmethod static hat(q)[source]

hat operator mapping vectors to the Lie algebra element

Parameters:

q (array) – vector coordinates

Return type:

matrix

Returns:

algebra element

abstractmethod static vee(Omega)[source]

vee operator mapping Lie algebra element to vector coordinates

Parameters:

Omega (matrix) – algebra element

Return type:

array

Returns:

vector coordinates

hitman.lie.comm(A, B)[source]

Matrix commutator, or (little) adjoint

hitman.lie.cot(x)[source]

Cotangent, because not defined in numpy?!?

Return type:

float

derivative

hitman.derivative.directional_derivative_numeric(f, x, d, tau)[source]

Numerical directional derivative using centered finite differences

\[\nabla_d f(x) = \lim_{\tau\rightarrow 0}\frac{f(x + \tau d)-f(x)}{\tau}\]
Parameters:
  • f (Callable[[ndarray], ndarray]) – functional \(\mathbb{R}^n \rightarrow \mathbb{R}^m\)

  • x (ndarray) – starting point \(x\in\mathbb{R}^n\)

  • d (ndarray) – direction \(d\in\mathbb{R}^n\)

  • tau (float) – step size

Return type:

float

Returns:

Finite difference (right-continuous)

hitman.derivative.fit_stats_loglog(errors, deltas, bounds=None, verbose=False)[source]

Compute linear fit of log-log data and return statistics

Designed to provide unit-test metrics

Parameters:
  • errors – (R, M) array

  • deltas

    1. array

  • bounds – (2,) array

Returns:

minimum delta for which fit was applied error_at_min_delta: error at minimum delta slope : line slope (loglog scale) var_resid : line fit residual (loglog scale)

Return type:

min_delta

hitman.derivative.jacobian_numeric(fctn, x, tau, m=None)[source]

Numerical directional derivative using finite differences

Parameters:
  • fctn – functional \(\mathbb{R}^n \rightarrow \mathbb{R}^m\)

  • x – starting point \(x\in\mathbb{R}^n\)

  • tau – step size

Returns:

Jacobian \(J\in\mathbb{R}^{m\times n}\)

hitman.derivative.verify_derivative(f, fdot, x_generator=None, taus=np.logspace(-9, 2, num=10), num_samples=100, norm=np.linalg.norm, fdot_gets_xdot=False)[source]

Compare directional derivative numerically

Randomly generate both starting points and directions, then compute residual between analytic and numeric derivatives.

Parameters:
  • f (Callable[[ndarray], ndarray]) – functional \(\mathbb{R}^n \rightarrow \mathbb{R}^m\)

  • fdot (Callable[[ndarray, ndarray], ndarray]) – analytic derivative from \(\dot{f}\left(x,\dot{x}\right) : \mathbb{R}^n \times \mathbb{R}^n \rightarrow \mathbb{R}^m\)

  • x_generator (Callable) – generator for initial values, or specify shape of x

  • taus (Tuple[float, ...]) – range of step sizes. (Default = np.logspace(-9,2,num=10))

  • num_samples (int) – number of samples at each step size

  • norm (Callable) – norm function

  • fdot_gets_xdot (bool) – if true, then xdot will be supplied to fdot as second argument.

Return type:

Tuple[ndarray, ndarray]

Returns:

Arrays of errors and step sizes

ode

ode module for numerically solving ordinary differential equations

class hitman.ode.ButcherTableau(a, b, c)

Class for storing a Butcher Tableau with error-checking on construction.

Initialize the Butcher tableau [But16] with given coefficients.

Parameters:
  • a (ndarray) – The matrix of coefficients for the stages.

  • b (ndarray) – The weights for the stages.

  • c (ndarray) – The nodes (or time levels) for the stages.

Raises:

ValueError – If the sizes of a, b, or c are not compatible.

property a

Get a copy of the matrix of coefficients.

property b

Get a copy of the weights for the stages.

property c

Get a copy of the nodes for the stages.

expand()[source]

expand tableau as parameters a,b,c

hitman.ode.bortz_equation(t, phi, omega, Jinv=SO.J_r_inv)

Differential equation for rotation groups

Differential equation of the form

\[\dot{\phi} = J_{\phi}^{-1} \omega\]

We emphasize Jinv must be consistent with omega. For example, \(\left(J^r\right)^{-1}\) and \(\omega^r\). See [Chi12].

When functional omega is available, this function can be turned into an ODE using functools.partial. For example

bortz_ode = partial(bortz_equation, omega=eval_omega)
Parameters:
  • t (float) – independent variable

  • phi (ndarray) – dependent variable in \(\mathbb{R}^N\)

  • omega (Callable[[float], ndarray]) – functional \(\omega : \mathbb{R}\rightarrow \mathbb{R}^N\)

  • Jinv (Callable[[ndarray], ndarray]) – functional \(J^{-1} : \mathbb{R}^N\rightarrow \mathbb{R}^{N\times N}\)

Return type:

ndarray

Returns:

\(\dot{\phi}\in\mathbb{R}^N\).

hitman.ode.rk_fixed(fun, t_n, step_size, y_n, tableau=butcher_tableaux['RK4'])

Fixed step-size Runge-Kutta solver for ordinary differential equations

Solve differential equation of the form:

\[\dot{y}(t) = f(t, y)\]

Similar format to scipy.integrate.solve_ivp().

Parameters:
Return type:

ndarray

Returns:

Solution \(y(t_n + \tau)\)

hitman.ode.rkmk_fixed(omega, t_n, step_size, y_n, tableau=butcher_tableaux['RK4'], Jinv=SO.J_r_inv)

Fixed step-size Runge-Kutta-Munthe-Kaas solver for Lie-group differential equations

Solve differential equation of the form:

\[\dot{y} = J_{y}^{-1} \omega\]

Similar to rk_fixed() for Lie-group differential equations. Instead of supplying the ODE \(\mathbb{R}\times\mathbb{R}^N\rightarrow \mathbb{R}^N\), the functional omega represents \(\omega : \mathbb{R}\rightarrow \mathbb{R}^N\).

Parameters:
  • omega (Callable[[float], ndarray]) – functional \(\omega : \mathbb{R}\rightarrow \mathbb{R}^N\)

  • t_n (float) – initial time

  • step_size (float) – step size \(\tau\)

  • y_n (ndarray) – initial value

  • tableau (ButcherTableau) – method-specific tableau

  • Jinv (Callable[[ndarray], ndarray]) – functional \(J^{-1} : \mathbb{R}^N\rightarrow \mathbb{R}^{N\times N}\)

Return type:

ndarray

Returns:

Solution \(y(t_n + \tau)\)

hitman.ode.rkmk_fixed_discrete(tauomega, y_n, tableau=butcher_tableaux['RK4'], c_to_index={0.0: 0, 0.5: 1, 1.0: 2}, Jinv=SO.J_r_inv)

Runge-Kutta-Munthe-Kaas solver for discrete measurements \(\omega\)

Instead of supplying analytic function \(\omega : \mathbb{R}\rightarrow \mathbb{R}^N\), supply matrix of scaled samples \(\omega\).

Parameters:
  • tauomega (ndarray) – discrete samples of \(\omega\), scaled by step size \(\tau\)

  • y_n (ndarray) – initial value

  • tableau (ButcherTableau) – method-specific tableau

  • c_to_index (dict) – convert tableau \(c\) to index for homega

  • Jinv (Callable[[ndarray], ndarray]) – inverse Jacobian (user-defined left vs right corresponding with fun)

Return type:

ndarray

hitman.ode.solve_numeric(ode, t=0.0, step_size=1, y_t=np.zeros(3), **kwargs)

Numeric ODE IVP solver

High-fidelity, variable step-size, solver for ODE. This is a wrapper for scipy.integrate.solve_ivp() with adjusted signature and default arguments.

solves for \(y(t + \tau)\in \mathbb{R}^N\) from provided \(y(t)=0\) and \(\dot{y} : \mathbb{R}\rightarrow\mathbb{R}^N\)

Parameters:
Returns:

Final value \(y(t + \tau)\)

hitman.ode.verify_ivp_solve(ode, solution, t=np.random.uniform(0, 1, 10), step_size=np.logspace(-8, -1, num=15), solver=rk_fixed, norm=np.linalg.norm)

Evaluate solver error over step size

Contrast ivp_solve against the true solution as a function of step size

Parameters:
Return type:

Tuple[ndarray, ndarray]

Returns:

Summary dataframe

class hitman.ode.butcher.ButcherTableau(a, b, c)

Class for storing a Butcher Tableau with error-checking on construction.

Initialize the Butcher tableau [But16] with given coefficients.

Parameters:
  • a (ndarray) – The matrix of coefficients for the stages.

  • b (ndarray) – The weights for the stages.

  • c (ndarray) – The nodes (or time levels) for the stages.

Raises:

ValueError – If the sizes of a, b, or c are not compatible.

property a

Get a copy of the matrix of coefficients.

property b

Get a copy of the weights for the stages.

property c

Get a copy of the nodes for the stages.

expand()[source]

expand tableau as parameters a,b,c

hitman.ode.butcher.butcher_tableaux

Dictionary containing common ButcherTableau

Examples include forward-Euler, explicit midpoint, and RK4.