blob: 7fa3f3eb650b0d262c8566cd1c68007b545158de [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 Schuhf7466732023-02-20 22:11:41 -080034// Implements Runge Kutta integration (4th order). This integrates dy/dt =
35// fn(t, y). It must have the call signature of fn(double t, T y). The
Austin Schuhca52a242018-12-23 09:19:29 +110036// 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 Schuhf7466732023-02-20 22:11:41 -080048template <typename F, typename T>
49T RungeKuttaSteps(const F &fn, T X, double t, double dt, int steps) {
50 dt = dt / steps;
51 for (int i = 0; i < steps; ++i) {
52 X = RungeKutta(fn, X, t + dt * i, dt);
53 }
54 return X;
55}
56
Austin Schuh268a94f2018-02-17 17:10:19 -080057// Implements Runge Kutta integration (4th order). fn is the function to
58// integrate. It must take 1 argument of type T. The integration starts at an
59// initial value X, and integrates for dt.
60template <typename F, typename T, typename Tu>
Austin Schuh9edb5df2018-12-23 09:03:15 +110061T RungeKuttaU(const F &fn, T X, Tu U, double dt) {
Austin Schuh268a94f2018-02-17 17:10:19 -080062 const double half_dt = dt * 0.5;
63 T k1 = fn(X, U);
64 T k2 = fn(X + half_dt * k1, U);
65 T k3 = fn(X + half_dt * k2, U);
66 T k4 = fn(X + dt * k3, U);
67 return X + dt / 6.0 * (k1 + 2.0 * k2 + 2.0 * k3 + k4);
68}
69
Austin Schuhacd335a2017-01-01 16:20:54 -080070} // namespace control_loops
71} // namespace frc971
72
73#endif // FRC971_CONTROL_LOOPS_RUNGE_KUTTA_H_