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
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)\]
- 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:
- 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 usinghitman.integrate.delta_functional().
- 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.
- 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 attitudet0 (
float) – Initial timeomega (
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:
- 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:
objectRotations 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}\]
- 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}\]
- class hitman.rotation.LieExponential(theta=None, M=None, **kwargs)
Bases:
LieGroupRotation 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:
- Return type:
Returns: algebra element \(so(3)\)
- static J_l(x, right=False)[source]
left-Jacobian for exponential coordinates
(See [Chi12] eq. 10.86)
- static J_l_dot(x, xdot, right=False)[source]
time-derivative of Jacobian for exponential coordinates
- 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 algebraright – optionally compute right-Jacobian
- Return type:
- Returns:
inverse-Jacobian of exp at x
- static J_r(theta)[source]
Right-Jacobian for exponential coordinates
See [Chi12] eq. 10.86
- Parameters:
x – vector representation of Lie algebra
- Return type:
- Returns:
Jacobian of exp at x
- 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:
- Returns:
Inverse right-Jacobian
- static hat(theta)[source]
hat operator mapping \(\mathbb{R}^n \rightarrow so(n)\)
- Parameters:
theta (
array) – exponential coordinate parameterization- Return type:
- Returns:
Element of Lie algebra (\(so(2)\) or \(so(3)\))
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].
- 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 elementX (
array) – algebra element
- Return type:
array
Returns: algebra element
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}\]
- 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 –
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 xtaus (
Tuple[float,...]) – range of step sizes. (Default =np.logspace(-9,2,num=10))num_samples (
int) – number of samples at each step sizenorm (
Callable) – norm functionfdot_gets_xdot (
bool) – if true, then xdot will be supplied to fdot as second argument.
- Return type:
- 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:
- 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.
- 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 examplebortz_ode = partial(bortz_equation, omega=eval_omega)
- Parameters:
- Return type:
- 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:
- 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 timestep_size (
float) – step size \(\tau\)y_n (
ndarray) – initial valuetableau (
ButcherTableau) – method-specific tableauJinv (
Callable[[ndarray],ndarray]) – functional \(J^{-1} : \mathbb{R}^N\rightarrow \mathbb{R}^{N\times N}\)
- Return type:
- 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 valuetableau (
ButcherTableau) – method-specific tableauc_to_index (
dict) – convert tableau \(c\) to index for homegaJinv (
Callable[[ndarray],ndarray]) – inverse Jacobian (user-defined left vs right corresponding with fun)
- Return type:
- 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:
ode (
Callable[[float,ndarray],ndarray]) – function handle for ordinary differential equationt (
ndarray) – Random vector of start points for integration.step_size (
ndarray) – Step sizes to evaluatesolver (
Callable) – functional accepting ode, t, step_size, and y_tnorm (
Callable) – norm function
- Return type:
- 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:
- 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.
- hitman.ode.butcher.butcher_tableaux
Dictionary containing common
ButcherTableauExamples include forward-Euler, explicit midpoint, and RK4.