10 #ifdef CROCODDYL_WITH_MULTITHREADING
14 #include "crocoddyl/core/solver-base.hpp"
47 const std::size_t ndx =
problem_->get_ndx();
48 const std::size_t T =
problem_->get_T();
49 const std::size_t ng_T =
problem_->get_terminalModel()->get_ng_T();
54 const std::vector<std::shared_ptr<ActionModelAbstract> >& models =
56 for (std::size_t t = 0; t < T; ++t) {
57 const std::shared_ptr<ActionModelAbstract>& model = models[t];
58 const std::size_t nu = model->get_nu();
59 const std::size_t ng = model->get_ng();
60 xs_[t] = model->get_state()->zero();
61 us_[t] = Eigen::VectorXd::Zero(nu);
62 fs_[t] = Eigen::VectorXd::Zero(ndx);
63 g_adj_[t] = Eigen::VectorXd::Zero(ng);
65 xs_.back() =
problem_->get_terminalModel()->get_state()->zero();
66 fs_.back() = Eigen::VectorXd::Zero(ndx);
67 g_adj_.back() = Eigen::VectorXd::Zero(ng_T);
70 SolverAbstract::~SolverAbstract() {}
73 START_PROFILER(
"SolverAbstract::resizeData");
74 const std::size_t T =
problem_->get_T();
75 const std::size_t ng_T =
problem_->get_terminalModel()->get_ng_T();
76 const std::vector<std::shared_ptr<ActionModelAbstract> >& models =
78 for (std::size_t t = 0; t < T; ++t) {
79 const std::shared_ptr<ActionModelAbstract>& model = models[t];
80 const std::size_t nu = model->get_nu();
81 const std::size_t ng = model->get_ng();
82 us_[t].conservativeResize(nu);
83 g_adj_[t].conservativeResize(ng);
86 g_adj_.back().conservativeResize(ng_T);
88 STOP_PROFILER(
"SolverAbstract::resizeData");
93 const std::size_t T =
problem_->get_T();
94 const Eigen::VectorXd& x0 =
problem_->get_x0();
95 const std::vector<std::shared_ptr<ActionModelAbstract> >& models =
97 const std::vector<std::shared_ptr<ActionDataAbstract> >& datas =
100 models[0]->get_state()->diff(
xs_[0], x0,
fs_[0]);
101 #ifdef CROCODDYL_WITH_MULTITHREADING
102 #pragma omp parallel for num_threads(problem_->get_nthreads())
104 for (std::size_t t = 0; t < T; ++t) {
105 const std::shared_ptr<ActionModelAbstract>& m = models[t];
106 const std::shared_ptr<ActionDataAbstract>& d = datas[t];
107 m->get_state()->diff(
xs_[t + 1], d->xnext,
fs_[t + 1]);
112 for (std::size_t t = 0; t < T; ++t) {
118 for (std::size_t t = 0; t < T; ++t) {
128 const std::size_t T =
problem_->get_T();
129 const std::vector<std::shared_ptr<ActionModelAbstract> >& models =
131 const std::vector<std::shared_ptr<ActionDataAbstract> >& datas =
136 for (std::size_t t = 0; t < T; ++t) {
137 if (models[t]->get_ng() > 0) {
139 ->g.cwiseMax(models[t]->get_g_lb())
140 .cwiseMin(models[t]->get_g_ub());
145 if (
problem_->get_terminalModel()->get_ng_T() > 0) {
148 ->g.cwiseMax(
problem_->get_terminalModel()->get_g_lb())
149 .cwiseMin(
problem_->get_terminalModel()->get_g_ub());
151 .lpNorm<Eigen::Infinity>();
155 for (std::size_t t = 0; t < T; ++t) {
156 if (models[t]->get_ng() > 0) {
158 ->g.cwiseMax(models[t]->get_g_lb())
159 .cwiseMin(models[t]->get_g_ub());
164 if (
problem_->get_terminalModel()->get_ng_T() > 0) {
167 ->g.cwiseMax(
problem_->get_terminalModel()->get_g_lb())
168 .cwiseMin(
problem_->get_terminalModel()->get_g_ub());
179 const std::size_t T =
problem_->get_T();
180 const std::vector<std::shared_ptr<ActionModelAbstract> >& models =
182 const std::vector<std::shared_ptr<ActionDataAbstract> >& datas =
186 for (std::size_t t = 0; t < T; ++t) {
187 if (models[t]->get_nh() > 0) {
189 std::max(
tmp_feas_, datas[t]->h.lpNorm<Eigen::Infinity>());
192 if (
problem_->get_terminalModel()->get_nh_T() > 0) {
195 problem_->get_terminalData()->h.lpNorm<Eigen::Infinity>());
199 for (std::size_t t = 0; t < T; ++t) {
200 if (models[t]->get_nh() > 0) {
204 if (
problem_->get_terminalModel()->get_nh_T() > 0) {
213 const std::vector<Eigen::VectorXd>& us_warm,
215 const std::size_t T =
problem_->get_T();
217 const std::vector<std::shared_ptr<ActionModelAbstract> >& models =
219 if (xs_warm.size() == 0) {
220 for (std::size_t t = 0; t < T; ++t) {
221 const std::shared_ptr<ActionModelAbstract>& model = models[t];
222 xs_[t] = model->get_state()->zero();
224 xs_.back() =
problem_->get_terminalModel()->get_state()->zero();
226 if (xs_warm.size() != T + 1) {
227 throw_pretty(
"Warm start state vector has wrong dimension, got "
228 << xs_warm.size() <<
" expecting " << (T + 1));
230 for (std::size_t t = 0; t < T; ++t) {
231 const std::size_t nx = models[t]->get_state()->get_nx();
232 if (
static_cast<std::size_t
>(xs_warm[t].size()) != nx) {
233 throw_pretty(
"Invalid argument: "
234 <<
"xs_init[" + std::to_string(t) +
235 "] has wrong dimension ("
237 <<
" provided - it should be equal to " +
238 std::to_string(nx) +
"). ActionModel: "
242 const std::size_t nx =
problem_->get_terminalModel()->get_state()->get_nx();
243 if (
static_cast<std::size_t
>(xs_warm[T].size()) != nx) {
244 throw_pretty(
"Invalid argument: "
245 <<
"xs_init[" + std::to_string(T) +
246 "] (terminal state) has wrong dimension ("
248 <<
" provided - it should be equal to " +
249 std::to_string(nx) +
"). ActionModel: "
252 std::copy(xs_warm.begin(), xs_warm.end(),
xs_.begin());
255 if (us_warm.size() == 0) {
256 for (std::size_t t = 0; t < T; ++t) {
257 const std::shared_ptr<ActionModelAbstract>& model = models[t];
258 const std::size_t nu = model->get_nu();
259 us_[t] = Eigen::VectorXd::Zero(nu);
262 if (us_warm.size() != T) {
263 throw_pretty(
"Warm start control has wrong dimension, got "
264 << us_warm.size() <<
" expecting " << T);
266 for (std::size_t t = 0; t < T; ++t) {
267 const std::shared_ptr<ActionModelAbstract>& model = models[t];
268 const std::size_t nu = model->get_nu();
269 if (
static_cast<std::size_t
>(us_warm[t].size()) != nu) {
270 throw_pretty(
"Invalid argument: "
271 <<
"us_init[" + std::to_string(t) +
272 "] has wrong dimension ("
274 <<
" provided - it should be equal to " +
275 std::to_string(nu) +
"). ActionModel: "
279 std::copy(us_warm.begin(), us_warm.end(),
us_.begin());
285 const std::vector<std::shared_ptr<CallbackAbstract> >& callbacks) {
289 const std::vector<std::shared_ptr<CallbackAbstract> >&
349 "Use get_preg for gettting the primal-dual regularization",
350 double SolverAbstract::get_xreg()
const {
return preg_; })
353 "Use get_preg for gettting the primal-dual regularization",
354 double SolverAbstract::get_ureg()
const {
return preg_; })
369 const std::size_t T =
problem_->get_T();
370 if (xs.size() != T + 1) {
371 throw_pretty(
"Invalid argument: " <<
"xs list has to be of length " +
372 std::to_string(T + 1));
375 const std::size_t nx =
problem_->get_nx();
376 for (std::size_t t = 0; t < T; ++t) {
377 if (
static_cast<std::size_t
>(xs[t].size()) != nx) {
378 throw_pretty(
"Invalid argument: "
379 <<
"xs[" + std::to_string(t) +
"] has wrong dimension ("
381 <<
" provided - it should be " + std::to_string(nx) +
")")
384 if (
static_cast<std::size_t
>(xs[T].size()) != nx) {
385 throw_pretty(
"Invalid argument: "
386 <<
"xs[" + std::to_string(T) +
387 "] (terminal state) has wrong dimension ("
389 <<
" provided - it should be " + std::to_string(nx) +
")")
395 const std::size_t T =
problem_->get_T();
396 if (us.size() != T) {
397 throw_pretty(
"Invalid argument: " <<
"us list has to be of length " +
401 const std::vector<std::shared_ptr<ActionModelAbstract> >& models =
403 for (std::size_t t = 0; t < T; ++t) {
404 const std::shared_ptr<ActionModelAbstract>& model = models[t];
405 const std::size_t nu = model->get_nu();
406 if (
static_cast<std::size_t
>(us[t].size()) != nu) {
407 throw_pretty(
"Invalid argument: "
408 <<
"us[" + std::to_string(t) +
"] has wrong dimension ("
410 <<
" provided - it should be " + std::to_string(nu) +
")")
418 throw_pretty(
"Invalid argument: " <<
"preg value has to be positive.");
425 throw_pretty(
"Invalid argument: " <<
"dreg value has to be positive.");
431 "Use set_preg for gettting the primal-variable regularization",
432 void SolverAbstract::set_xreg(
const double xreg) {
434 throw_pretty(
"Invalid argument: " <<
"xreg value has to be positive.");
441 "Use set_preg for gettting the primal-variable regularization",
442 void SolverAbstract::set_ureg(
const double ureg) {
444 throw_pretty(
"Invalid argument: " <<
"ureg value has to be positive.");
451 if (0. >= th_acceptstep || th_acceptstep > 1) {
453 "Invalid argument: " <<
"th_acceptstep value should between 0 and 1.");
455 th_acceptstep_ = th_acceptstep;
460 throw_pretty(
"Invalid argument: " <<
"th_stop value has to higher than 0.");
466 if (0. > th_gaptol) {
467 throw_pretty(
"Invalid argument: " <<
"th_gaptol value has to be positive.");
476 bool raiseIfNaN(
const double value) {
477 if (std::isnan(value) || std::isinf(value) || value >= 1e30) {
double get_cost() const
Return the cost for the current guess.
std::vector< Eigen::VectorXd > g_adj_
Adjusted inequality bound.
double get_dPhi() const
Return the reduction in the merit function .
double get_th_gaptol() const
Return the threshold for accepting a gap as non-zero.
double dVexp_
Expected reduction in the cost function.
std::vector< Eigen::VectorXd > xs_
State trajectory.
std::size_t get_iter() const
Return the number of iterations performed by the solver.
double get_hfeas() const
Return the equality feasibility for the current guess.
void set_th_stop(const double th_stop)
Modify the tolerance for stopping the algorithm.
double stop_
Value computed by stoppingCriteria()
void set_xs(const std::vector< Eigen::VectorXd > &xs)
Modify the state trajectory .
double get_dVexp() const
Return the expected reduction in the cost function .
double dreg_
Current dual-variable regularization value.
double feas_
Total feasibility for the current guess.
bool is_feasible_
Label that indicates is the iteration is feasible.
EIGEN_MAKE_ALIGNED_OPERATOR_NEW SolverAbstract(std::shared_ptr< ShootingProblem > problem)
Initialize the solver.
std::shared_ptr< ShootingProblem > problem_
optimal control problem
std::vector< Eigen::VectorXd > us_
Control trajectory.
double get_dPhiexp() const
Return the expected reduction in the merit function .
double th_acceptstep_
Threshold used for accepting step.
double get_steplength() const
Return the step length .
void set_th_gaptol(const double th_gaptol)
Modify the threshold for accepting a gap as non-zero.
double get_merit() const
Return the merit for the current guess.
double dPhi_
Reduction in the merit function computed by tryStep()
const std::vector< std::shared_ptr< CallbackAbstract > > & getCallbacks() const
Return the list of callback functions using for diagnostic.
double computeInequalityFeasibility()
Compute the feasibility of the inequality constraints for the current guess.
double get_preg() const
Return the primal-variable regularization.
double get_hfeas_try() const
Return the equality feasibility for the current step length.
double th_stop_
Tolerance for stopping the algorithm.
double computeDynamicFeasibility()
Compute the dynamic feasibility for the current guess .
const Eigen::Vector2d & get_d() const
Return the linear and quadratic terms of the expected improvement.
double dPhiexp_
Expected reduction in the merit function.
enum FeasibilityNorm feasnorm_
void setCandidate(const std::vector< Eigen::VectorXd > &xs_warm=DEFAULT_VECTOR, const std::vector< Eigen::VectorXd > &us_warm=DEFAULT_VECTOR, const bool is_feasible=false)
Set the solver candidate trajectories .
double get_th_stop() const
Return the tolerance for stopping the algorithm.
double dfeas_
Reduction in the feasibility.
void set_feasnorm(const FeasibilityNorm feas_norm)
Modify the current norm used for computed the dynamic and constraint feasibility.
double get_ffeas() const
Return the dynamic feasibility for the current guess.
double get_gfeas() const
Return the inequality feasibility for the current guess.
double cost_
Cost for the current guess.
std::vector< std::shared_ptr< CallbackAbstract > > callbacks_
Callback functions.
void set_us(const std::vector< Eigen::VectorXd > &us)
Modify the control trajectory .
void setCallbacks(const std::vector< std::shared_ptr< CallbackAbstract > > &callbacks)
Set a list of callback functions using for the solver diagnostic.
double th_gaptol_
Threshold limit to check non-zero gaps.
std::size_t iter_
Number of iteration performed by the solver.
double get_feas() const
Return the total feasibility for the current guess.
double dV_
Reduction in the cost function computed by tryStep()
double get_stop() const
Return the stopping-criteria value computed by stoppingCriteria()
double get_ffeas_try() const
Return the dynamic feasibility for the current step length.
void set_dreg(const double dreg)
Modify the dual-variable regularization value.
Eigen::Vector2d d_
LQ approximation of the expected improvement.
double get_dV() const
Return the reduction in the cost function .
const std::vector< Eigen::VectorXd > & get_fs() const
Return the dynamic infeasibility .
const std::vector< Eigen::VectorXd > & get_xs() const
Return the state trajectory .
double get_dfeas() const
Return the reduction in the feasibility.
void set_preg(const double preg)
Modify the primal-variable regularization value.
double ffeas_
Feasibility of the dynamic constraints for the current guess.
double get_gfeas_try() const
Return the inequality feasibility for the current step length.
bool get_is_feasible() const
Return the feasibility status of the trajectory.
double preg_
Current primal-variable regularization value.
const std::vector< Eigen::VectorXd > & get_us() const
Return the control trajectory .
double merit_
Merit for the current guess.
virtual void resizeData()
Resizing the solver data.
std::vector< Eigen::VectorXd > fs_
Gaps/defects between shooting nodes.
void set_th_acceptstep(const double th_acceptstep)
Modify the threshold used for accepting step.
const std::shared_ptr< ShootingProblem > & get_problem() const
Return the shooting problem.
double tmp_feas_
Temporal variables used for computed the feasibility.
double get_th_acceptstep() const
Return the threshold used for accepting a step.
FeasibilityNorm get_feasnorm() const
Return the type of norm used to evaluate the dynamic and constraints feasibility.
double get_dreg() const
Return the dual-variable regularization.
double computeEqualityFeasibility()
Compute the feasibility of the equality constraints for the current guess.