Austin Schuh | 7400da0 | 2018-01-28 19:54:58 -0800 | [diff] [blame^] | 1 | /*! |
| 2 | * Simple example how to linearize a system and design an LQR controller. |
| 3 | * |
| 4 | * \example LQR.cpp |
| 5 | */ |
| 6 | |
| 7 | |
| 8 | #include <ct/optcon/optcon.h> // also includes ct_core |
| 9 | #include "exampleDir.h" |
| 10 | |
| 11 | int main(int argc, char** argv) |
| 12 | { |
| 13 | // get the state and control input dimension of the oscillator |
| 14 | const size_t state_dim = ct::core::SecondOrderSystem::STATE_DIM; |
| 15 | const size_t control_dim = ct::core::SecondOrderSystem::CONTROL_DIM; |
| 16 | |
| 17 | // create an auto-differentiable instance of the oscillator dynamics |
| 18 | ct::core::ADCGScalar w_n(50.0); |
| 19 | std::shared_ptr<ct::core::ControlledSystem<state_dim, control_dim, ct::core::ADCGScalar>> oscillatorDynamics( |
| 20 | new ct::core::tpl::SecondOrderSystem<ct::core::ADCGScalar>(w_n)); |
| 21 | |
| 22 | // create an Auto-Differentiation Linearizer with code generation on the quadrotor model |
| 23 | ct::core::ADCodegenLinearizer<state_dim, control_dim> adLinearizer(oscillatorDynamics); |
| 24 | |
| 25 | // compile the linearized model just-in-time |
| 26 | adLinearizer.compileJIT(); |
| 27 | |
| 28 | // define the linearization point around steady state |
| 29 | ct::core::StateVector<state_dim> x; |
| 30 | x.setZero(); |
| 31 | ct::core::ControlVector<control_dim> u; |
| 32 | u.setZero(); |
| 33 | double t = 0.0; |
| 34 | |
| 35 | // compute the linearization around the nominal state using the Auto-Diff Linearizer |
| 36 | auto A = adLinearizer.getDerivativeState(x, u, t); |
| 37 | auto B = adLinearizer.getDerivativeControl(x, u, t); |
| 38 | |
| 39 | // load the weighting matrices |
| 40 | ct::optcon::TermQuadratic<state_dim, control_dim> quadraticCost; |
| 41 | quadraticCost.loadConfigFile(ct::optcon::exampleDir + "/lqrCost.info", "termLQR"); |
| 42 | auto Q = quadraticCost.stateSecondDerivative(x, u, t); // x, u and t can be arbitrary here |
| 43 | auto R = quadraticCost.controlSecondDerivative(x, u, t); // x, u and t can be arbitrary here |
| 44 | |
| 45 | // design the LQR controller |
| 46 | ct::optcon::LQR<state_dim, control_dim> lqrSolver; |
| 47 | ct::core::FeedbackMatrix<state_dim, control_dim> K; |
| 48 | |
| 49 | std::cout << "A: " << std::endl << A << std::endl << std::endl; |
| 50 | std::cout << "B: " << std::endl << B << std::endl << std::endl; |
| 51 | std::cout << "Q: " << std::endl << Q << std::endl << std::endl; |
| 52 | std::cout << "R: " << std::endl << R << std::endl << std::endl; |
| 53 | |
| 54 | lqrSolver.compute(Q, R, A, B, K); |
| 55 | |
| 56 | std::cout << "LQR gain matrix:" << std::endl << K << std::endl; |
| 57 | |
| 58 | return 1; |
| 59 | } |