#pragma once
#include <unsupported/Eigen/MatrixFunctions>
#include "frc/EigenCore.h"
#include "units/time.h"
namespace frc {
template <int States>
void DiscretizeA(const Matrixd<States, States>& contA, units::second_t dt,
Matrixd<States, States>* discA) {
*discA = (contA * dt.value()).exp();
}
template <int States, int Inputs>
void DiscretizeAB(const Matrixd<States, States>& contA,
const Matrixd<States, Inputs>& contB, units::second_t dt,
Matrixd<States, States>* discA,
Matrixd<States, Inputs>* discB) {
Matrixd<States + Inputs, States + Inputs> M;
M.template block<States, States>(0, 0) = contA;
M.template block<States, Inputs>(0, States) = contB;
M.template block<Inputs, States + Inputs>(States, 0).setZero();
Matrixd<States + Inputs, States + Inputs> phi = (M * dt.value()).exp();
*discA = phi.template block<States, States>(0, 0);
*discB = phi.template block<States, Inputs>(0, States);
}
template <int States>
void DiscretizeAQ(const Matrixd<States, States>& contA,
const Matrixd<States, States>& contQ, units::second_t dt,
Matrixd<States, States>* discA,
Matrixd<States, States>* discQ) {
Matrixd<States, States> Q = (contQ + contQ.transpose()) / 2.0;
Matrixd<2 * States, 2 * States> M;
M.template block<States, States>(0, 0) = -contA;
M.template block<States, States>(0, States) = Q;
M.template block<States, States>(States, 0).setZero();
M.template block<States, States>(States, States) = contA.transpose();
Matrixd<2 * States, 2 * States> phi = (M * dt.value()).exp();
Matrixd<States, States> phi12 = phi.block(0, States, States, States);
Matrixd<States, States> phi22 = phi.block(States, States, States, States);
*discA = phi22.transpose();
Q = *discA * phi12;
*discQ = (Q + Q.transpose()) / 2.0;
}
template <int Outputs>
Matrixd<Outputs, Outputs> DiscretizeR(const Matrixd<Outputs, Outputs>& R,
units::second_t dt) {
return R / dt.value();
}
}