blob: 963f4633b4ead8482e48c4586e51f03fda145f73 [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
milind-ue53bf552021-12-11 14:42:00 -080022// Implements Runge Kutta integration (4th order) split up into steps steps. fn
23// is the function to integrate. It must take 1 argument of type T. The
24// integration starts at an initial value X, and integrates for dt.
25template <typename F, typename T>
26T RungeKuttaSteps(const F &fn, T X, double dt, int steps) {
27 dt = dt / steps;
28 for (int i = 0; i < steps; ++i) {
29 X = RungeKutta(fn, X, dt);
30 }
31 return X;
32}
33
Austin Schuhca52a242018-12-23 09:19:29 +110034// Implements Runge Kutta integration (4th order). This integrates dy/dt = fn(t,
35// y). It must have the call signature of fn(double t, T y). The
36// integration starts at an initial value y, and integrates for dt.
37template <typename F, typename T>
38T RungeKutta(const F &fn, T y, double t, double dt) {
39 const double half_dt = dt * 0.5;
40 T k1 = dt * fn(t, y);
41 T k2 = dt * fn(t + half_dt, y + k1 / 2.0);
42 T k3 = dt * fn(t + half_dt, y + k2 / 2.0);
43 T k4 = dt * fn(t + dt, y + k3);
44
45 return y + (k1 + 2.0 * k2 + 2.0 * k3 + k4) / 6.0;
46}
47
Austin Schuh268a94f2018-02-17 17:10:19 -080048// Implements Runge Kutta integration (4th order). fn is the function to
49// integrate. It must take 1 argument of type T. The integration starts at an
50// initial value X, and integrates for dt.
51template <typename F, typename T, typename Tu>
Austin Schuh9edb5df2018-12-23 09:03:15 +110052T RungeKuttaU(const F &fn, T X, Tu U, double dt) {
Austin Schuh268a94f2018-02-17 17:10:19 -080053 const double half_dt = dt * 0.5;
54 T k1 = fn(X, U);
55 T k2 = fn(X + half_dt * k1, U);
56 T k3 = fn(X + half_dt * k2, U);
57 T k4 = fn(X + dt * k3, U);
58 return X + dt / 6.0 * (k1 + 2.0 * k2 + 2.0 * k3 + k4);
59}
60
Austin Schuhacd335a2017-01-01 16:20:54 -080061} // namespace control_loops
62} // namespace frc971
63
64#endif // FRC971_CONTROL_LOOPS_RUNGE_KUTTA_H_