blob: 298b813fa4d8b3b7031857b0107165f92a5306b0 [file] [log] [blame]
Austin Schuh7400da02018-01-28 19:54:58 -08001/**********************************************************************************************************************
2This file is part of the Control Toolbox (https://adrlab.bitbucket.io/ct), copyright by ETH Zurich, Google Inc.
3Authors: Michael Neunert, Markus Giftthaler, Markus Stäuble, Diego Pardo, Farbod Farshidian
4Licensed under Apache2 license (see LICENSE file in main directory)
5**********************************************************************************************************************/
6
7#include <ct/optcon/optcon.h>
8#include <ct/rbd/rbd.h>
9#include "../exampleDir.h"
10
11#include <ct/models/InvertedPendulum/InvertedPendulum.h>
12
13using namespace ct::rbd;
14
15const size_t njoints = ct::rbd::InvertedPendulum::Kinematics::NJOINTS;
16const size_t actuator_state_dim = 1;
17
18typedef ct::rbd::InvertedPendulum::tpl::Dynamics<double> IPDynamics;
19typedef ct::rbd::FixBaseFDSystem<IPDynamics, actuator_state_dim, false> IPSystem;
20
21typedef ct::core::LinearSystem<IPSystem::STATE_DIM, IPSystem::CONTROL_DIM, double> LinearSystem;
22
23using InvertedPendulumNLOC = FixBaseNLOC<IPSystem, actuator_state_dim, double>;
24
25class MPCSimulator : public ct::core::ControlSimulator<IPSystem>
26{
27public:
28 MPCSimulator(ct::core::Time sim_dt,
29 ct::core::Time control_dt,
30 const ct::core::StateVector<STATE_DIM>& x0,
31 std::shared_ptr<IPSystem> ip_system,
32 ct::optcon::MPC<ct::optcon::NLOptConSolver<STATE_DIM, CONTROL_DIM>>& mpc)
33 : ct::core::ControlSimulator<IPSystem>(sim_dt, control_dt, x0, ip_system), mpc_(mpc)
34 {
35 controller_.reset(new ct::core::StateFeedbackController<STATE_DIM, CONTROL_DIM>);
36 }
37
38 void finishSystemIteration(ct::core::Time sim_time) override
39 {
40 control_mtx_.lock();
41 system_->setController(controller_);
42 control_mtx_.unlock();
43 }
44
45 void prepareControllerIteration(ct::core::Time sim_time) override
46 {
47 mpc_.prepareIteration(sim_time);
48 }
49
50 void finishControllerIteration(ct::core::Time sim_time) override
51 {
52 state_mtx_.lock();
53 ct::core::StateVector<STATE_DIM> x_temp = x_;
54 state_mtx_.unlock();
55
56 std::shared_ptr<ct::core::StateFeedbackController<STATE_DIM, CONTROL_DIM>> new_controller(
57 new ct::core::StateFeedbackController<STATE_DIM, CONTROL_DIM>);
58 bool success = mpc_.finishIteration(x_temp, sim_time, *new_controller, controller_ts_);
59 if (!success) throw std::runtime_error("Failed to finish iteration.");
60
61 control_mtx_.lock();
62 controller_ = new_controller;
63 control_mtx_.unlock();
64 }
65
66private:
67 ct::optcon::MPC<ct::optcon::NLOptConSolver<STATE_DIM, CONTROL_DIM>>& mpc_;
68 ct::core::Time controller_ts_;
69};
70
71int main(int argc, char* argv[])
72{
73 const bool verbose = true;
74 try
75 {
76 std::string workingDirectory = ct::models::exampleDir + "/InvertedPendulum";
77
78 std::string configFile = workingDirectory + "/solver.info";
79 std::string costFunctionFile = workingDirectory + "/cost.info";
80
81 std::shared_ptr<ct::rbd::SEADynamicsFirstOrder<njoints, double>> actuatorDynamics(
82 new ct::rbd::SEADynamicsFirstOrder<njoints, double>(160.0));
83 std::shared_ptr<IPSystem> ipSystem(new IPSystem(actuatorDynamics));
84
85 // NLOC settings
86 ct::optcon::NLOptConSettings nloc_settings;
87 nloc_settings.load(configFile, verbose, "ilqr");
88
89 std::shared_ptr<ct::optcon::TermQuadratic<IPSystem::STATE_DIM, IPSystem::CONTROL_DIM, double, double>>
90 termQuadInterm(new ct::optcon::TermQuadratic<IPSystem::STATE_DIM, IPSystem::CONTROL_DIM, double, double>);
91 termQuadInterm->loadConfigFile(costFunctionFile, "term0", verbose);
92
93 std::shared_ptr<ct::optcon::TermQuadratic<IPSystem::STATE_DIM, IPSystem::CONTROL_DIM, double, double>>
94 termQuadFinal(new ct::optcon::TermQuadratic<IPSystem::STATE_DIM, IPSystem::CONTROL_DIM, double, double>);
95 termQuadFinal->loadConfigFile(costFunctionFile, "term1", verbose);
96
97 std::shared_ptr<ct::optcon::CostFunctionAnalytical<IPSystem::STATE_DIM, IPSystem::CONTROL_DIM>> newCost(
98 new ct::optcon::CostFunctionAnalytical<IPSystem::STATE_DIM, IPSystem::CONTROL_DIM>);
99 size_t intTermID = newCost->addIntermediateTerm(termQuadInterm);
100 size_t finalTermID = newCost->addFinalTerm(termQuadFinal);
101
102 ct::core::Time timeHorizon;
103 InvertedPendulumNLOC::FeedbackArray::value_type fbD;
104 ct::rbd::tpl::JointState<njoints, double> x0;
105 ct::rbd::tpl::JointState<njoints, double> xf;
106
107 ct::core::loadScalar(configFile, "timeHorizon", timeHorizon);
108 ct::core::loadMatrix(costFunctionFile, "K_init", fbD);
109 ct::core::loadMatrix(costFunctionFile, "x_0", x0.toImplementation());
110 ct::core::loadMatrix(costFunctionFile, "term1.weights.x_des", xf.toImplementation());
111 ct::core::StateVector<IPSystem::STATE_DIM> x0full = IPSystem::toFullState(x0.toImplementation());
112
113 std::shared_ptr<LinearSystem> linSystem = nullptr;
114 ct::optcon::OptConProblem<IPSystem::STATE_DIM, IPSystem::CONTROL_DIM> optConProblem(
115 timeHorizon, x0full, ipSystem, newCost, linSystem);
116 InvertedPendulumNLOC nloc_solver(newCost, nloc_settings, ipSystem, verbose, linSystem);
117
118 int K = nloc_solver.getSettings().computeK(timeHorizon);
119
120 InvertedPendulumNLOC::StateVectorArray stateRefTraj(K + 1, x0full);
121 InvertedPendulumNLOC::FeedbackArray fbTrajectory(K, -fbD);
122 InvertedPendulumNLOC::ControlVectorArray ffTrajectory(K, InvertedPendulumNLOC::ControlVector::Zero());
123
124 int initType = 0;
125 ct::core::loadScalar(configFile, "initType", initType);
126
127 switch (initType)
128 {
129 case 0: // steady state
130 {
131 ct::core::ControlVector<IPSystem::CONTROL_DIM> uff_ref;
132 nloc_solver.initializeSteadyPose(x0, timeHorizon, K, uff_ref, -fbD);
133
134 std::vector<
135 std::shared_ptr<ct::optcon::CostFunctionQuadratic<IPSystem::STATE_DIM, IPSystem::CONTROL_DIM>>>&
136 inst1 = nloc_solver.getSolver()->getCostFunctionInstances();
137
138 for (size_t i = 0; i < inst1.size(); i++)
139 {
140 inst1[i]->getIntermediateTermById(intTermID)->updateReferenceControl(uff_ref);
141 }
142 break;
143 }
144 case 1: // linear interpolation
145 {
146 nloc_solver.initializeDirectInterpolation(x0, xf, timeHorizon, K, -fbD);
147 break;
148 }
149 default:
150 {
151 throw std::runtime_error("illegal init type");
152 break;
153 }
154 }
155
156 std::cout << "waiting 1 second for begin" << std::endl;
157 std::this_thread::sleep_for(std::chrono::seconds(1));
158
159 nloc_solver.solve();
160 ct::core::StateFeedbackController<IPSystem::STATE_DIM, IPSystem::CONTROL_DIM> initialSolution =
161 nloc_solver.getSolution();
162 InvertedPendulumNLOC::StateVectorArray x_nloc = initialSolution.x_ref();
163
164 // nloc_solver.retrieveLastRollout();
165
166 ct::optcon::NLOptConSettings ilqr_settings_mpc(nloc_solver.getSettings());
167 ilqr_settings_mpc.max_iterations = 1;
168 ilqr_settings_mpc.printSummary = false;
169
170 ct::optcon::mpc_settings mpc_settings;
171 mpc_settings.stateForwardIntegration_ = false;
172 mpc_settings.postTruncation_ = false;
173 mpc_settings.measureDelay_ = false;
174 mpc_settings.delayMeasurementMultiplier_ = 1.0;
175 mpc_settings.mpc_mode = ct::optcon::MPC_MODE::CONSTANT_RECEDING_HORIZON;
176 mpc_settings.coldStart_ = false;
177 mpc_settings.minimumTimeHorizonMpc_ = 3.0;
178
179 ct::optcon::MPC<ct::optcon::NLOptConSolver<IPSystem::STATE_DIM, IPSystem::CONTROL_DIM>> ilqr_mpc(
180 optConProblem, ilqr_settings_mpc, mpc_settings);
181 ilqr_mpc.setInitialGuess(initialSolution);
182
183 MPCSimulator mpc_sim(1e-3, 1e-2, x0full, ipSystem, ilqr_mpc);
184 std::cout << "simulating 3 seconds" << std::endl;
185 mpc_sim.simulate(3);
186 mpc_sim.finish();
187
188 ilqr_mpc.printMpcSummary();
189
190 } catch (std::runtime_error& e)
191 {
192 std::cout << "Exception caught: " << e.what() << std::endl;
193 }
194}