blob: 61d674e710dae04ae46dd45435641fa43261069b [file] [log] [blame]
Austin Schuhacd335a2017-01-01 16:20:54 -08001#ifndef FRC971_CONTROL_LOOPS_RUNGE_KUTTA_H_
2#define FRC971_CONTROL_LOOPS_RUNGE_KUTTA_H_
3
4#include <Eigen/Dense>
5
6namespace frc971 {
7namespace control_loops {
8
9// Implements Runge Kutta integration (4th order). fn is the function to
10// integrate. It must take 1 argument of type T. The integration starts at an
11// initial value X, and integrates for dt.
12template <typename F, typename T>
13T RungeKutta(const F &fn, T X, double dt) {
14 const double half_dt = dt * 0.5;
Austin Schuh92ebcbb2018-01-23 11:17:08 -080015 T k1 = fn(X);
16 T k2 = fn(X + half_dt * k1);
17 T k3 = fn(X + half_dt * k2);
18 T k4 = fn(X + dt * k3);
Austin Schuhacd335a2017-01-01 16:20:54 -080019 return X + dt / 6.0 * (k1 + 2.0 * k2 + 2.0 * k3 + k4);
20}
21
Austin Schuhca52a242018-12-23 09:19:29 +110022// Implements Runge Kutta integration (4th order). This integrates dy/dt = fn(t,
23// y). It must have the call signature of fn(double t, T y). The
24// integration starts at an initial value y, and integrates for dt.
25template <typename F, typename T>
26T RungeKutta(const F &fn, T y, double t, double dt) {
27 const double half_dt = dt * 0.5;
28 T k1 = dt * fn(t, y);
29 T k2 = dt * fn(t + half_dt, y + k1 / 2.0);
30 T k3 = dt * fn(t + half_dt, y + k2 / 2.0);
31 T k4 = dt * fn(t + dt, y + k3);
32
33 return y + (k1 + 2.0 * k2 + 2.0 * k3 + k4) / 6.0;
34}
35
Austin Schuh268a94f2018-02-17 17:10:19 -080036// Implements Runge Kutta integration (4th order). fn is the function to
37// integrate. It must take 1 argument of type T. The integration starts at an
38// initial value X, and integrates for dt.
39template <typename F, typename T, typename Tu>
Austin Schuh9edb5df2018-12-23 09:03:15 +110040T RungeKuttaU(const F &fn, T X, Tu U, double dt) {
Austin Schuh268a94f2018-02-17 17:10:19 -080041 const double half_dt = dt * 0.5;
42 T k1 = fn(X, U);
43 T k2 = fn(X + half_dt * k1, U);
44 T k3 = fn(X + half_dt * k2, U);
45 T k4 = fn(X + dt * k3, U);
46 return X + dt / 6.0 * (k1 + 2.0 * k2 + 2.0 * k3 + k4);
47}
48
Austin Schuhacd335a2017-01-01 16:20:54 -080049} // namespace control_loops
50} // namespace frc971
51
52#endif // FRC971_CONTROL_LOOPS_RUNGE_KUTTA_H_