In [5]:
%%HTML
<LINK rel=stylesheet type="text/css" href="files/defense.css">



In [6]:
from IPython.display import IFrame
import TSatPyViz
from TSatPy import State
%load_ext autoreload
%autoreload 2


The autoreload extension is already loaded. To reload it, use:
  %reload_ext autoreload

TableSat IA

Master's Thesis

Development of a Modular Application for Analyzing Observer-Based Control Systems for NASA's Spin-Stabilized MMS Mission Spacecraft

 

Math + Control Theory + Coding = years and years of fun

 

Daniel R. Couture

University of New Hampshire Mechanical Engineering

Prof. May-Win Thein

June 5th, 2014

NASA Goddard Space Flight Center

@MathYourLife

github.com/MathYourLife

vimeo.com/search?q=mathyourlife

Thanks

TableSat IA

 

 

Physical model to capture and quantify boom dynamics.

UNH TableSat IA

Analytical and Experimental ADCS

UNH TableSat IA

State Measurement

UNH TableSat IA

TableSat IA Experimental Boom Dynamics Blockers

  • Truster (Fan)
  • System Mass
  • Magnetometer Noise

 

4 Matlab ADCS Versions

  • Object-oriented classes
  • Actuator Logic
  • Run-time visualizations
  • Matlab issues
    • More complex coding = More Matlab "monkey patching"
    • Simulink doesn't play nice with experimental setups
    • Not open source ($, community, resources, ...)
    • Debugging is painful

Final Python ADCS Vesion

Feature Set

  • Concurrent Estimation/Control Algorithms
  • Run-time interface
  • Variable System Clock
  • Adaptive Step Algorithms
  • Modular Design
  • Source Agnostic Control System
  • Open Source - MIT License

Quaternion Additive Correction

Quaternon Propagation:

$$ \begin{align} \boldsymbol{\dot{q}} &= \frac{1}{2} \boldsymbol{q} \otimes \boldsymbol{\omega}\\ \boldsymbol{q}(k+1) &= \boldsymbol{q}(k) \color{red}{+} \boldsymbol{\dot{q}}(k) \Delta t \end{align} $$

Issues in:

  • State Error
  • Luenberger Gains
  • PID State Estimators
  • PID Controllers
  • Sliding Mode Observers
  • Sliding Mode Controllers
  • Kalman Filters
  • Extended Kalman Filters
  • Integrals / Derivatives
  • ...

In [7]:
TSatPyViz.dq_adjust()


/usr/lib/python3/dist-packages/gi/overrides/__init__.py:92: Warning: Source ID 2 was not found when attempting to remove it
  return fn(*args, **kwargs)

Quaternion Problems

SectionGivenProblem
PropagationPosition $\boldsymbol{q}(k)$ and velocity $\boldsymbol{\omega}(k)$Predict $\boldsymbol{q}(k+1)$
Estimator/ControllerWhere we are $\boldsymbol{\hat{q}}$ and where we should be $\boldsymbol{q}, \boldsymbol{q}_d$Calculate $k(\boldsymbol{q}^* \otimes \boldsymbol{\hat{q}})$ where $0 < k < 1$
ControllerEstimated attitude $\boldsymbol{\hat{q}}$Quantify nutation $\boldsymbol{q}_n$ where $\boldsymbol{\hat{q}} = \boldsymbol{q}_n \otimes \boldsymbol{q}_r$
Nutation $\boldsymbol{q}_n$Calculate nutation correction $\boldsymbol{M}$

Valid Quaternion Operations

Valid Quaternion Operation $\iff$ Never need to re-normalize

OperationDoes
$$ \boldsymbol{q} = \boldsymbol{a} \otimes \boldsymbol{b} = \boldsymbol{a}_v b_0 + \boldsymbol{b}_v a_0 + \boldsymbol{a}_v \times \boldsymbol{b}_v + a_0 b_0 - \boldsymbol{a}_v \cdot \boldsymbol{b}_v $$"Add" rotation $\boldsymbol{a}$ onto rotation $\boldsymbol{b}$
$$\boldsymbol{q}_e = \boldsymbol{q}^* \otimes \boldsymbol{\hat{q}}$$Gives the rotation that will move $\boldsymbol{\hat{q}}$ to $\boldsymbol{q}$

Quaternion Propagation

Nikolas Trawny and Stergios I. Roumeliotis

Indirect Kalman Filter for 3D Attitude Estimation A Tutorial for Quaternion Algebra

Taylor Series Expansion:

$$ \begin{aligned} \boldsymbol{q}(t_{k+1}) &= ( \boldsymbol{A} + \boldsymbol{B} ) \boldsymbol{q}(t_{k}) \\ \text{where } \boldsymbol{A} &= \exp \left( \frac{\Delta t_{k+1}}{2} \boldsymbol{\Omega} \left[ \boldsymbol{\bar{\omega}}(t_{k+1}) \right] \right)\\ \boldsymbol{B} &= \frac{1}{48} \Delta t_{k+1}^2 \Big( \boldsymbol{\Omega} \left[\boldsymbol{\omega}(t_{k+1}) \right] \boldsymbol{\Omega} \left[\boldsymbol{\omega}(t_{k}) \right] - \boldsymbol{\Omega} \left[\boldsymbol{\omega}(t_{k}) \right] \boldsymbol{\Omega} \left[\boldsymbol{\omega}(t_{k+1}) \right] \Big) \end{aligned} $$
Nikolas Trawny and Stergios I. Roumeliotis - Indirect Kalman Filter for 3D Attitude Estimation A Tutorial for Quaternion Algebra*

Theta Multiplier with Quaternion Vector Balancing

  • Adhere to the unit rotational quaternion restriction. (i.e. NEVER* re-normalize)
  • Do not modify the direction of the $\boldsymbol{\hat{e}}$ axis
  • Scale $\theta$ (not $q_0$) so a $4^o$ error can be intuitively scaled to down to a $1^o$ adjustment with a selected gain value of 0.25.
$$ \begin{aligned} \boldsymbol{\psi}(\boldsymbol{q}, K) &= \begin{bmatrix} \boldsymbol{v} / \gamma \\ \cos ( K \cdot \cos^{-1} (q_0)) \end{bmatrix} \\ \text{where } \gamma &= \sqrt{\frac{\boldsymbol{v} \bullet \boldsymbol{v}}{\sin^2 ( K \cdot \cos^{-1} (q_0))}} \\ \end{aligned} $$

Luenberger Observer

$$ \begin{aligned} \boldsymbol{\hat{q}}(t_{k+1}) &= \boldsymbol{\psi}(\boldsymbol{q}_e(t_{k}), K) \otimes f(\boldsymbol{\hat{q}}(t_{k})) \\ \text{where } K &= \text{scalar gain} \end{aligned} $$

In [8]:
q = State.Quaternion(vector=[1, 1, 0], radians=1)
TSatPyViz.show_tmqvb(q)


/usr/lib/python3/dist-packages/gi/overrides/__init__.py:92: Warning: Source ID 571 was not found when attempting to remove it
  return fn(*args, **kwargs)

PID State Estimator

$$ \begin{align} \boldsymbol{\hat{q}}(t_{k+1}) &= f(\boldsymbol{\hat{q}}(t_{k})) + K_{qp} \boldsymbol{q}_{e}(t_k) + K_{qi} \sum^k_0 \boldsymbol{q}_{e}(t_k) + K_{qd}( \boldsymbol{q}_{e}(t_{k-1}) - \boldsymbol{q}_{e}(t_k))\\ & \\ \boldsymbol{\hat{q}}(t_{k+1}) &= \boldsymbol{\psi}\left(\boldsymbol{q}_{ed}(t_k), K_{qd}\right) \otimes \boldsymbol{\psi}\big(\boldsymbol{q}_{ei}(t_k), K_{qi}\big) \otimes \boldsymbol{\psi}(\boldsymbol{q}_e(t_{k}), K_{qp}) \otimes f(\boldsymbol{\hat{q}}(t_{k})) \end{align} $$

Sliding Mode Observer

$$ \begin{align} \boldsymbol{\hat{q}}(t_{k+1}) &= f(\boldsymbol{q}(t_k)) + \boldsymbol{L} \boldsymbol{q}_{e}(t_k) + \boldsymbol{K}\boldsymbol{1}_s \big(\boldsymbol{q}_{e}(t_k) \big) \\ & \\ \boldsymbol{\hat{q}}(t_{k+1}) &= \boldsymbol{\psi} (\boldsymbol{1}_s\big(\boldsymbol{q}_{e}(t_k)\big), K) \otimes \boldsymbol{\psi}(\boldsymbol{q}_e(t_{k}), L) \otimes f(\boldsymbol{q}(t_k)) \\ \end{align} $$

Adaptive Time Step Quaternion Integral

$$ \boldsymbol{q}_{ei}(t_k) = \boldsymbol{\psi}(\boldsymbol{q}_e(t_{k}), \Delta t_{k}) \otimes \boldsymbol{q}_{ei}(t_{k-1}) $$

Adaptive Time Step Quaternion Derivative

$$ \boldsymbol{q}_{ed}(t_k) = \boldsymbol{\psi}\left(\boldsymbol{q}_e(t_{k-1})^* \otimes \boldsymbol{q}_e(t_{k}), \frac{1}{\Delta t_{k}}\right) $$

In [9]:
TSatPyViz.show_pid()


/usr/lib/python3/dist-packages/gi/overrides/__init__.py:92: Warning: Source ID 1167 was not found when attempting to remove it
  return fn(*args, **kwargs)

Quaternion Nutation Control

SectionGivenProblem
ControllerEstimated attitude $\boldsymbol{\hat{q}}$Quantify nutation $\boldsymbol{q}_n$ where $\boldsymbol{\hat{q}} = \boldsymbol{q}_n \otimes \boldsymbol{q}_r$

Quaternion $\boldsymbol{\hat{q}}$ defines the attitude as:

Controller should only care about nutation $\boldsymbol{q}_n$:

Decompose an Attitude into Rotation and Nutation Quaternions

$$ \begin{aligned} \boldsymbol{q} &= \boldsymbol{q}_n \otimes \boldsymbol{q}_r \\ q_1 \boldsymbol{i} + q_2 \boldsymbol{j} + q_3 \boldsymbol{k} + q_0 &= (q_{1n} \boldsymbol{i} + q_{2n} \boldsymbol{j} + q_{3n} \boldsymbol{k} + q_{0n}) \otimes (q_{1r} \boldsymbol{i} + q_{2r} \boldsymbol{j} + q_{3r} \boldsymbol{k} + q_{0r}) \\ \\ \text{where } & \\ \\ \boldsymbol{q}_r &= \begin{bmatrix} 0 \\ 0 \\ q_{3r} = \frac{q_3}{q_{0n}} \\ q_{0r} = \frac{q_0}{q_{0n}} \end{bmatrix}, \boldsymbol{q}_n = \begin{bmatrix} q_{1n} = Q \cdot q_{2n} \\ q_{2n} = \sqrt{ \frac{1 - q_3^2 - q_0^2}{Q^2 + 1} } \\ 0 \\ q_{0n} = \sqrt{q_3^2 + q_0^2} \end{bmatrix} \\ Q &= \frac{q_{0}q_{1} - q_{2}q_{3}}{q_{0}q_{2} + q_{1}q_{3}} \end{aligned} $$

In [10]:
from TSatPy.State import Quaternion

yaw = 0.2
pitch = 0.1
print("Creating an attitude with %g rad yaw and %g rad pitch.\n" % (yaw, pitch))

q = Quaternion([0,1,0], radians=pitch) * Quaternion([0,0,1], radians=yaw)
print("Estimator reports an attitude quaternion of:")
print("q:     %s\n" % (q))

q_r, q_n = q.decompose()
print("Controller decomposes the attitude and ignores the rotational component")
print("q_r:   %s" % (q_r))
print("q_n:   %s" % (q_n))


Creating an attitude with 0.2 rad yaw and 0.1 rad pitch.

Estimator reports an attitude quaternion of:
q:     <Quaternion [0.00498959 -0.0497295 -0.0997087], 0.993761>

Controller decomposes the attitude and ignores the rotational component
q_r:   <Quaternion [0 0 -0.0998334], 0.995004>
q_n:   <Quaternion [-0 0.0499792 0], -0.99875>

Quaternion Attitude Control (Nutation Control)

SectionGivenProblem
ControllerAttitude error $\boldsymbol{q}_e$Calculate nutation correction $\boldsymbol{M}$

 

 

TableSat controller should only care about nutation $\boldsymbol{q}_n$:

The proportional moment correction term is

$$ \begin{align} \boldsymbol{M} &= \left[- 2k \cdot \cos^{-1} (q_{0e}) \right] \boldsymbol{\hat{e}}_e \\ \text{Where } &= \boldsymbol{\hat{e}} \text{ is the Euler axis } \boldsymbol{v}/| \boldsymbol{v}|\end{align} $$

PID Controller

$$ \boldsymbol{M} = \left[- 2K_{p} \cos^{-1} (q_{0e}) \right] \boldsymbol{\hat{e}}_e + \left[- 2K_{i} \cos^{-1} (q_{0ei}) \right] \boldsymbol{\hat{e}}_{ei} + \left[- 2K_{d} \cos^{-1} (q_{0ed}) \right] \boldsymbol{\hat{e}}_{ed} $$

SMC

$$ \begin{aligned} \boldsymbol{M} &= \left[- 2L \cos^{-1} (q_{0e}) \right] \boldsymbol{\hat{e}}_e + \left[ K sat \left( \frac{-2\cos^{-1} (q_{0e})}{S_q} \right) \right] \boldsymbol{\hat{e}}_e \\ \end{aligned} $$

Future Work

  • Quantify benefits to $\boldsymbol{\psi}(\boldsymbol{q}, K)$ over traditional matrix control methods
  • EKF with scalar gain and $\boldsymbol{\psi}(\boldsymbol{q}, K)$
  • Extend functionality of python system visualization
  • Apply ADCS to TableSat $N$ and other spin stabilized systems
  • More research into observer based controllers with $\boldsymbol{\psi}(\boldsymbol{q}, K)$ and quaternion decomposition
  • Release TSatPy to https://github.com/MathYourLife under MIT open source license
  • Estimator / Controller scheduling
  • Improve unit test coverage for TSatPy
  • Coarse Sun Sensors sensor improvements

Summary

  • Windows/Matlab boo
  • Linux/Python yay
  • TSat IA
    • thrusters :(
    • CSS :)
    • TAM need better accuracy
  • Matlab plotting library (tPlot)
  • Robust ADCS in Python
  • $\boldsymbol{\psi}(\boldsymbol{q}, K)$
  • Quaternion decomposition $\boldsymbol{q} = \boldsymbol{q}_n \otimes \boldsymbol{q}_r$
  • $\boldsymbol{\psi}(\boldsymbol{q}, K)$-based PID state estimator, SMO, PID controller, SMC
  • $\boldsymbol{\psi}(\boldsymbol{q}, K)$-based observer-based controller (SMO+SMC) with $\boldsymbol{q}_n$