blob: ed5a35905e3e1cf5ab232736d8a9125996280319 [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
Stephan Pleinesd99b1ee2024-02-02 20:56:44 -08006namespace frc971::control_loops {
Austin Schuhacd335a2017-01-01 16:20:54 -08007
8// Implements Runge Kutta integration (4th order). fn is the function to
9// integrate. It must take 1 argument of type T. The integration starts at an
10// initial value X, and integrates for dt.
11template <typename F, typename T>
12T RungeKutta(const F &fn, T X, double dt) {
13 const double half_dt = dt * 0.5;
Austin Schuh92ebcbb2018-01-23 11:17:08 -080014 T k1 = fn(X);
15 T k2 = fn(X + half_dt * k1);
16 T k3 = fn(X + half_dt * k2);
17 T k4 = fn(X + dt * k3);
Austin Schuhacd335a2017-01-01 16:20:54 -080018 return X + dt / 6.0 * (k1 + 2.0 * k2 + 2.0 * k3 + k4);
19}
20
milind-ue53bf552021-12-11 14:42:00 -080021// Implements Runge Kutta integration (4th order) split up into steps steps. fn
22// is the function to integrate. It must take 1 argument of type T. The
23// integration starts at an initial value X, and integrates for dt.
24template <typename F, typename T>
25T RungeKuttaSteps(const F &fn, T X, double dt, int steps) {
26 dt = dt / steps;
27 for (int i = 0; i < steps; ++i) {
28 X = RungeKutta(fn, X, dt);
29 }
30 return X;
31}
32
Austin Schuhf7466732023-02-20 22:11:41 -080033// Implements Runge Kutta integration (4th order). This integrates dy/dt =
34// fn(t, y). It must have the call signature of fn(double t, T y). The
Austin Schuhca52a242018-12-23 09:19:29 +110035// integration starts at an initial value y, and integrates for dt.
36template <typename F, typename T>
37T RungeKutta(const F &fn, T y, double t, double dt) {
38 const double half_dt = dt * 0.5;
39 T k1 = dt * fn(t, y);
40 T k2 = dt * fn(t + half_dt, y + k1 / 2.0);
41 T k3 = dt * fn(t + half_dt, y + k2 / 2.0);
42 T k4 = dt * fn(t + dt, y + k3);
43
44 return y + (k1 + 2.0 * k2 + 2.0 * k3 + k4) / 6.0;
45}
46
Austin Schuhf7466732023-02-20 22:11:41 -080047template <typename F, typename T>
48T RungeKuttaSteps(const F &fn, T X, double t, double dt, int steps) {
49 dt = dt / steps;
50 for (int i = 0; i < steps; ++i) {
51 X = RungeKutta(fn, X, t + dt * i, dt);
52 }
53 return X;
54}
55
Austin Schuh268a94f2018-02-17 17:10:19 -080056// Implements Runge Kutta integration (4th order). fn is the function to
57// integrate. It must take 1 argument of type T. The integration starts at an
58// initial value X, and integrates for dt.
59template <typename F, typename T, typename Tu>
Austin Schuh9edb5df2018-12-23 09:03:15 +110060T RungeKuttaU(const F &fn, T X, Tu U, double dt) {
Austin Schuh268a94f2018-02-17 17:10:19 -080061 const double half_dt = dt * 0.5;
62 T k1 = fn(X, U);
63 T k2 = fn(X + half_dt * k1, U);
64 T k3 = fn(X + half_dt * k2, U);
65 T k4 = fn(X + dt * k3, U);
66 return X + dt / 6.0 * (k1 + 2.0 * k2 + 2.0 * k3 + k4);
67}
68
Stephan Pleinesd99b1ee2024-02-02 20:56:44 -080069} // namespace frc971::control_loops
Austin Schuhacd335a2017-01-01 16:20:54 -080070
71#endif // FRC971_CONTROL_LOOPS_RUNGE_KUTTA_H_