36 void AnalyticDDPSolver::Instantiate(
const AnalyticDDPSolverInitializer& init)
39 base_parameters_ = AbstractDDPSolverInitializer(AnalyticDDPSolverInitializer(parameters_));
42 void AnalyticDDPSolver::BackwardPass()
46 Vx_.back() = prob_->GetStateCostJacobian(T_ - 1);
47 Vxx_.back() = prob_->GetStateCostHessian(T_ - 1);
52 Vxx_.back().diagonal().array() += lambda_;
57 const Eigen::array<Eigen::IndexPair<int>, 1> dims = {Eigen::IndexPair<int>(1, 0)};
58 Eigen::Tensor<double, 1> Vx_tensor;
60 Eigen::VectorXd
x(NX_), u(NU_);
62 for (
int t = T_ - 2; t >= 0; t--)
68 dynamics_solver_->ComputeDerivatives(
x, u);
69 fx_[t].noalias() = dynamics_solver_->get_Fx();
70 fu_[t].noalias() = dynamics_solver_->get_Fu();
76 Qx_[t].noalias() = dt_ * prob_->GetStateCostJacobian(t);
77 Qx_[t].noalias() += fx_[t].transpose() * Vx_[t + 1];
78 Qu_[t].noalias() = dt_ * prob_->GetControlCostJacobian(t);
79 Qu_[t].noalias() += fu_[t].transpose() * Vx_[t + 1];
81 Qxx_[t].noalias() = dt_ * prob_->GetStateCostHessian(t);
82 Qxx_[t].noalias() += fx_[t].transpose() * Vxx_[t + 1] * fx_[t];
83 Quu_[t].noalias() = dt_ * prob_->GetControlCostHessian(t);
84 Quu_[t].noalias() += fu_[t].transpose() * Vxx_[t + 1] * fu_[t];
87 Qux_[t].noalias() = fu_[t].transpose() * Vxx_[t + 1] * fx_[t];
90 if (parameters_.UseSecondOrderDynamics && dynamics_solver_->get_has_second_order_derivatives())
92 Vx_tensor = Eigen::TensorMap<Eigen::Tensor<double, 1>>(Vx_[t + 1].data(), NDX_);
94 Qxx_[t] +=
Eigen::TensorToMatrix((Eigen::Tensor<double, 2>)dynamics_solver_->fxx(
x, u).contract(Vx_tensor, dims), NDX_, NDX_) * dt_;
96 Quu_[t] +=
Eigen::TensorToMatrix((Eigen::Tensor<double, 2>)dynamics_solver_->fuu(
x, u).contract(Vx_tensor, dims), NU_, NU_) * dt_;
98 Qux_[t] +=
Eigen::TensorToMatrix((Eigen::Tensor<double, 2>)dynamics_solver_->fxu(
x, u).contract(Vx_tensor, dims), NU_, NDX_) * dt_;
102 Quu_[t].diagonal().array() += lambda_;
105 Quu_inv_[t] = Quu_[t].llt().solve(Eigen::MatrixXd::Identity(NU_, NU_));
106 k_[t].noalias() = -Quu_inv_[t] * Qu_[t];
107 K_[t].noalias() = -Quu_inv_[t] * Qux_[t];
119 Vx_[t] = Qx_[t] + K_[t].transpose() * Quu_[t] * k_[t] + K_[t].transpose() * Qu_[t] + Qux_[t].transpose() * k_[t];
120 Vxx_[t] = Qxx_[t] + K_[t].transpose() * Quu_[t] * K_[t] + K_[t].transpose() * Qux_[t] + Qux_[t].transpose() * K_[t];
121 Vxx_[t] = 0.5 * (Vxx_[t] + Vxx_[t].transpose()).eval();
126 Vxx_[t].diagonal().array() += lambda_;
#define REGISTER_MOTIONSOLVER_TYPE(TYPE, DERIV)
MatrixType< Scalar > TensorToMatrix(const Eigen::Tensor< Scalar, rank > &tensor, const sizeType rows, const sizeType cols)