60 #include <ilqgames/dynamics/multi_player_integrable_system.h> 61 #include <ilqgames/solver/lq_feedback_solver.h> 62 #include <ilqgames/solver/lq_open_loop_solver.h> 63 #include <ilqgames/utils/linear_dynamics_approximation.h> 64 #include <ilqgames/utils/quadratic_cost_approximation.h> 65 #include <ilqgames/utils/strategy.h> 67 #include <glog/logging.h> 73 std::vector<Strategy> LQOpenLoopSolver::Solve(
74 const std::vector<LinearDynamicsApproximation>& linearization,
75 const std::vector<std::vector<QuadraticCostApproximation>>&
77 const VectorXf& x0, std::vector<VectorXf>* delta_xs,
78 std::vector<std::vector<VectorXf>>* costates) {
79 CHECK_EQ(linearization.size(), num_time_steps_);
80 CHECK_EQ(quadraticization.size(), num_time_steps_);
83 if (delta_xs) CHECK_NOTNULL(costates);
84 if (costates) CHECK_NOTNULL(delta_xs);
86 delta_xs->resize(num_time_steps_);
87 costates->resize(num_time_steps_);
88 for (
size_t kk = 0; kk < num_time_steps_; kk++) {
89 (*delta_xs)[kk].resize(dynamics_->XDim());
90 (*costates)[kk].resize(dynamics_->NumPlayers());
91 for (PlayerIndex ii = 0; ii < dynamics_->NumPlayers(); ii++)
92 (*costates)[kk][ii].resize(dynamics_->XDim());
99 std::vector<Strategy> strategies;
100 for (PlayerIndex ii = 0; ii < dynamics_->NumPlayers(); ii++)
101 strategies.emplace_back(num_time_steps_, dynamics_->XDim(),
102 dynamics_->UDim(ii));
105 for (PlayerIndex ii = 0; ii < dynamics_->NumPlayers(); ii++) {
106 ms_.back()[ii] = quadraticization.back()[ii].state.grad;
107 Ms_.back()[ii] = quadraticization.back()[ii].state.hess;
113 for (
int kk = num_time_steps_ - 2; kk >= 0; kk--) {
115 const auto& lin = linearization[kk];
116 const auto& quad = quadraticization[kk];
119 capital_lambdas_[kk].setIdentity();
120 for (PlayerIndex ii = 0; ii < dynamics_->NumPlayers(); ii++) {
121 const auto control_iter = quad[ii].control.find(ii);
122 CHECK(control_iter != quad[ii].control.end());
124 chol_Rs_[kk][ii].compute(control_iter->second.hess);
125 warped_Bs_[kk][ii] = chol_Rs_[kk][ii].solve(lin.Bs[ii].transpose());
126 warped_rs_[kk][ii] = chol_Rs_[kk][ii].solve(control_iter->second.grad);
127 capital_lambdas_[kk] += lin.Bs[ii] * warped_Bs_[kk][ii] * Ms_[kk + 1][ii];
131 qr_capital_lambdas_[kk].compute(capital_lambdas_[kk]);
134 intermediate_terms_[kk].setZero();
135 for (PlayerIndex ii = 0; ii < dynamics_->NumPlayers(); ii++) {
136 intermediate_terms_[kk] -=
138 (warped_Bs_[kk][ii] * ms_[kk + 1][ii] + warped_rs_[kk][ii]);
141 for (PlayerIndex ii = 0; ii < dynamics_->NumPlayers(); ii++) {
143 quad[ii].state.hess + lin.A.transpose() * Ms_[kk + 1][ii] *
144 qr_capital_lambdas_[kk].solve(lin.A);
146 quad[ii].state.grad +
147 lin.A.transpose() * (ms_[kk + 1][ii] +
148 Ms_[kk + 1][ii] * qr_capital_lambdas_[kk].solve(
149 intermediate_terms_[kk]));
154 VectorXf x_star = x0;
155 VectorXf last_x_star;
156 for (
size_t kk = 0; kk < num_time_steps_ - 1; kk++) {
158 if (delta_xs) (*delta_xs)[kk] = x_star;
161 const auto& lin = linearization[kk];
164 last_x_star = x_star;
165 x_star = qr_capital_lambdas_[kk].solve(lin.A * last_x_star +
166 intermediate_terms_[kk]);
170 for (PlayerIndex ii = 0; ii < dynamics_->NumPlayers(); ii++) {
171 const VectorXf intermediate_term =
172 Ms_[kk + 1][ii] * x_star + ms_[kk + 1][ii];
173 strategies[ii].alphas[kk] =
174 warped_Bs_[kk][ii] * intermediate_term + warped_rs_[kk][ii];
176 if (costates) (*costates)[kk][ii] = lin.A.transpose() * intermediate_term;
189 delta_xs->back() = x_star;
190 for (PlayerIndex ii = 0; ii < dynamics_->NumPlayers(); ii++)
191 costates->back()[ii].setZero();