blob: fe3c1573e44693e147b1f9ec326a1814ed461c53 [file] [log] [blame]
Austin Schuha647d602018-02-18 14:05:15 -08001#ifndef FRC971_CONTROL_LOOPS_JACOBIAN_H_
2#define FRC971_CONTROL_LOOPS_JACOBIAN_H_
3
4#include <Eigen/Dense>
5
6namespace frc971 {
7namespace control_loops {
8
9template <int num_states, int num_inputs, typename F>
10::Eigen::Matrix<double, num_states, num_inputs> NumericalJacobian(
11 const F &fn, ::Eigen::Matrix<double, num_inputs, 1> input) {
12 constexpr double kEpsilon = 1e-4;
13 ::Eigen::Matrix<double, num_states, num_inputs> result =
14 ::Eigen::Matrix<double, num_states, num_inputs>::Zero();
15
16 // It's more expensive, but +- epsilon will be more accurate
17 for (int i = 0; i < num_inputs; ++i) {
18 ::Eigen::Matrix<double, num_inputs, 1> dX_plus = input;
19 dX_plus(i, 0) += kEpsilon;
20 ::Eigen::Matrix<double, num_inputs, 1> dX_minus = input;
21 dX_minus(i, 0) -= kEpsilon;
22 result.col(i) = (fn(dX_plus) - fn(dX_minus)) / (kEpsilon * 2.0);
23 }
24 return result;
25}
26
27// Implements a numerical jacobian with respect to X for f(X, U, ...).
28template <int num_states, int num_u, typename F, typename... Args>
29::Eigen::Matrix<double, num_states, num_states> NumericalJacobianX(
30 const F &fn, ::Eigen::Matrix<double, num_states, 1> X,
31 ::Eigen::Matrix<double, num_u, 1> U, Args &&... args) {
32 return NumericalJacobian<num_states, num_states>(
33 [&](::Eigen::Matrix<double, num_states, 1> X) {
34 return fn(X, U, args...);
35 },
36 X);
37}
38
39// Implements a numerical jacobian with respect to U for f(X, U, ...).
40template <int num_states, int num_u, typename F, typename... Args>
41::Eigen::Matrix<double, num_states, num_u> NumericalJacobianU(
42 const F &fn, ::Eigen::Matrix<double, num_states, 1> X,
43 ::Eigen::Matrix<double, num_u, 1> U, Args &&... args) {
44 return NumericalJacobian<num_states, num_u>(
45 [&](::Eigen::Matrix<double, num_u, 1> U) { return fn(X, U, args...); },
46 U);
47}
48
49} // namespace control_loops
50} // namespace frc971
51
52#endif // FRC971_CONTROL_LOOPS_JACOBIAN_H_