blob: 453a6a517502e8865be5c5d9eed95dc62ae18476 [file] [log] [blame]
Austin Schuh9b881ae2019-01-04 07:29:20 +11001#ifndef FRC971_CONTROL_LOOPS_C2D_H_
2#define FRC971_CONTROL_LOOPS_C2D_H_
3
4#include <chrono>
5
6#include <Eigen/Dense>
7
8namespace frc971 {
9namespace controls {
10
11template <typename Scalar, int num_states, int num_inputs>
12void C2D(const ::Eigen::Matrix<Scalar, num_states, num_states> &A_continuous,
13 const ::Eigen::Matrix<Scalar, num_states, num_inputs> &B_continuous,
14 ::std::chrono::nanoseconds dt,
15 ::Eigen::Matrix<Scalar, num_states, num_states> *A,
16 ::Eigen::Matrix<Scalar, num_states, num_inputs> *B) {
17 // Trick from
18 // https://en.wikipedia.org/wiki/Discretization#Discretization_of_linear_state_space_models
19 // to solve for A and B more efficiently.
20 Eigen::Matrix<Scalar, num_states + num_inputs, num_states + num_inputs>
21 M_state_continuous;
22 M_state_continuous.setZero();
23 M_state_continuous.template block<num_states, num_states>(0, 0) =
24 A_continuous *
25 ::std::chrono::duration_cast<::std::chrono::duration<Scalar>>(dt).count();
26 M_state_continuous.template block<num_states, num_inputs>(0, num_states) =
27 B_continuous *
28 ::std::chrono::duration_cast<::std::chrono::duration<Scalar>>(dt).count();
29
30 Eigen::Matrix<Scalar, num_states + num_inputs, num_states + num_inputs>
31 M_state = M_state_continuous.exp();
32 *A = M_state.template block<num_states, num_states>(0, 0);
33 *B = M_state.template block<num_states, num_inputs>(0, num_states);
34}
35
36} // namespace controls
37} // namespace frc971
38
39#endif // FRC971_CONTROL_LOOPS_C2D_H_