Controller.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <array>
7 #include <cstddef>
8 
9 #include "DataStructures/DataVector.hpp"
10 
11 /// \ingroup ControlSystemGroup
12 /// A PND (proportional to Q and N derivatives of Q) controller that computes
13 /// the control signal:
14 /// \f[ U(t) = \sum_{k=0}^{N} a_{k} \frac{d^kQ}{dt^k} \f]
15 /// where N is specified by the template parameter `DerivOrder`.
16 ///
17 /// If an averager is used for `q_and_derivs` (as we typically do), there is an
18 /// induced time offset, \f$\Delta t\f$, due to the time-weighted averaging.
19 /// Therefore, the `q_and_derivs` that we have in hand are at some time
20 /// \f$t_{0}\f$. However, we desire `q_and_derivs` at the current time
21 /// \f$t = t_{0} + \Delta t\f$ to determine the appropriate control
22 /// signal. We accomplish this by Taylor expanding
23 /// \f$Q(t_{0} + \Delta t)\f$. The averager allows for averaging of
24 /// \f$Q\f$ and its derivatives OR to not average \f$Q\f$ while still averaging
25 /// the derivatives (the derivatives are always averaged in order to reduce
26 /// noise due to numerical differentiation). When they are both averaged, the
27 /// time offset will be identical for \f$Q\f$ and the derivatives,
28 /// i.e. `q_time_offset` = `deriv_time_offset`. If an unaveraged \f$Q\f$ is
29 /// used, then the time offset associated with \f$Q\f$ is zero,
30 /// i.e. `q_time_offset`=0. and the derivative time offset, `deriv_time_offset`,
31 /// remains non-zero.
32 template <size_t DerivOrder>
33 class Controller {
34  public:
35  DataVector operator()(
36  const DataVector& timescales,
37  const std::array<DataVector, DerivOrder + 1>& q_and_derivs,
38  double q_time_offset, double deriv_time_offset) const noexcept;
39 };
A PND (proportional to Q and N derivatives of Q) controller that computes the control signal: where ...
Definition: Controller.hpp:33
Stores a collection of function values.
Definition: DataVector.hpp:46