10#include <quad_msgs/RobotPlanDiagnostics.h>
11#include <sys/resource.h>
14#include <Eigen/Sparse>
15#include <IpIpoptData.hpp>
16#include <grid_map_core/grid_map_core.hpp>
18#include <unordered_map>
22#include "nmpc_controller/gen/eval_g_a1.h"
23#include "nmpc_controller/gen/eval_g_leg_complex.h"
24#include "nmpc_controller/gen/eval_g_leg_complex_to_simple.h"
25#include "nmpc_controller/gen/eval_g_leg_simple.h"
26#include "nmpc_controller/gen/eval_g_leg_simple_to_complex.h"
27#include "nmpc_controller/gen/eval_g_spirit.h"
28#include "nmpc_controller/gen/eval_hess_g_a1.h"
29#include "nmpc_controller/gen/eval_hess_g_leg_complex.h"
30#include "nmpc_controller/gen/eval_hess_g_leg_complex_to_simple.h"
31#include "nmpc_controller/gen/eval_hess_g_leg_simple.h"
32#include "nmpc_controller/gen/eval_hess_g_leg_simple_to_complex.h"
33#include "nmpc_controller/gen/eval_hess_g_spirit.h"
34#include "nmpc_controller/gen/eval_jac_g_a1.h"
35#include "nmpc_controller/gen/eval_jac_g_leg_complex.h"
36#include "nmpc_controller/gen/eval_jac_g_leg_complex_to_simple.h"
37#include "nmpc_controller/gen/eval_jac_g_leg_simple.h"
38#include "nmpc_controller/gen/eval_jac_g_leg_simple_to_complex.h"
39#include "nmpc_controller/gen/eval_jac_g_spirit.h"
40#include "quad_utils/function_timer.h"
41#include "quad_utils/quad_kd.h"
54enum FunctionID { FUNC, JAC, HESS };
58 int x_dim_complex = 0;
59 int u_dim_complex = 0;
60 int g_dim_complex = 0;
61 int x_dim_cost_complex = 0;
62 int u_dim_cost_complex = 0;
66 int x_dim_cost_simple = 0;
67 int u_dim_cost_simple = 0;
71 Eigen::VectorXd Q_complex;
72 Eigen::VectorXd R_complex;
73 Eigen::VectorXd x_min_complex;
74 Eigen::VectorXd x_max_complex;
75 Eigen::VectorXd x_min_complex_soft;
76 Eigen::VectorXd x_max_complex_soft;
77 Eigen::VectorXd u_min_complex;
78 Eigen::VectorXd u_max_complex;
79 Eigen::VectorXd g_min_complex;
80 Eigen::VectorXd g_max_complex;
85 double compute_time, cost;
86 int iterations, horizon_length;
87 Eigen::VectorXi complexity_schedule;
88 Eigen::VectorXd element_times;
90 void loadDiagnosticsMsg(quad_msgs::RobotPlanDiagnostics &msg) {
91 msg.compute_time = compute_time;
93 msg.iterations = iterations;
94 msg.horizon_length = horizon_length;
96 msg.complexity_schedule.resize(complexity_schedule.size());
97 msg.element_times.resize(element_times.size());
98 for (
int i = 0; i < complexity_schedule.size(); i++) {
99 msg.complexity_schedule.at(i) = complexity_schedule[i];
100 msg.element_times.at(i) = element_times[i];
114 std::shared_ptr<quad_utils::QuadKD> quadKD_;
120 const int n_body_ = 12, n_foot_ = 24, n_joints_ = 24, n_tail_ = 4,
121 m_body_ = 12, m_foot_ = 24, m_tail_ = 2;
124 Eigen::VectorXi
n_vec_, n_slack_vec_, m_vec_, g_vec_, g_slack_vec_,
125 n_cost_vec_, m_cost_vec_;
136 const grid_map::InterpolationMethods interp_type_ =
137 grid_map::InterpolationMethods::INTER_LINEAR;
143 int n_vars_, n_vars_primal_, n_vars_slack_, n_constraints_;
160 double Q_temporal_factor_, R_temporal_factor_;
163 Eigen::MatrixXd foot_pos_body_;
166 Eigen::MatrixXd foot_pos_world_;
169 Eigen::MatrixXd foot_vel_world_;
192 Eigen::VectorXd g_min_complex_soft_, g_max_complex_soft_;
195 Eigen::MatrixXd ground_height_;
198 Eigen::VectorXd w0_, z_L0_, z_U0_, lambda0_, g0_;
205 Eigen::MatrixXd x_reference_;
208 Eigen::VectorXd x_current_;
211 Eigen::MatrixXi contact_sequence_;
216 std::vector<int> first_step_idx_jac_g_;
219 Eigen::VectorXi iRow_jac_g_, jCol_jac_g_;
223 int nnz_h_, nnz_compact_h_;
226 Eigen::VectorXi nnz_step_jac_g_, nnz_step_hess_;
228 std::vector<int> first_step_idx_hess_g_;
232 Eigen::VectorXi iRow_h_, jCol_h_, iRow_compact_h_, jCol_compact_h_;
235 double panic_weights_, constraint_panic_weights_;
238 double first_element_duration_;
247 Eigen::VectorXi
fe_idxs_, u_idxs_, x_idxs_, slack_state_var_idxs_,
248 slack_constraint_var_idxs_, primal_constraint_idxs_,
249 slack_var_constraint_idxs_, dynamic_jac_var_idxs_,
250 relaxed_dynamic_jac_var_idxs_, panic_jac_var_idxs_,
251 dynamic_hess_var_idxs_, cost_idxs_, relaxed_constraint_idxs_;
255 constraint_panic_weights_vec_;
261 Eigen::MatrixXi
nnz_mat_, nrow_mat_, ncol_mat_, first_step_idx_mat_,
265 std::vector<std::vector<Eigen::VectorXi>>
iRow_mat_, jCol_mat_;
266 std::vector<std::vector<Eigen::VectorXi>> iRow_mat_relaxed_,
267 jCol_mat_relaxed_, relaxed_idx_in_full_sparse_;
273 std::vector<std::vector<
decltype(eval_g_spirit) *>> eval_vec_;
274 std::vector<std::vector<
decltype(eval_g_spirit_work) *>> eval_work_vec_;
275 std::vector<std::vector<
decltype(eval_g_spirit_incref) *>> eval_incref_vec_;
276 std::vector<std::vector<
decltype(eval_g_spirit_decref) *>> eval_decref_vec_;
277 std::vector<std::vector<
decltype(eval_g_spirit_checkout) *>>
279 std::vector<std::vector<
decltype(eval_g_spirit_release) *>> eval_release_vec_;
280 std::vector<std::vector<
decltype(eval_g_spirit_sparsity_out) *>>
284 quadNLP(
int N,
double dt,
double mu,
double panic_weights,
285 double constraint_panic_weights,
double Q_temporal_factor,
286 double R_temporal_factor,
287 const Eigen::VectorXi &fixed_complexity_schedule,
302 virtual bool get_nlp_info(Index &n, Index &m, Index &nnz_jac_g,
303 Index &nnz_h_lag, IndexStyleEnum &index_style);
306 virtual bool get_bounds_info(Index n, Number *x_l, Number *x_u, Index m,
307 Number *g_l, Number *g_u);
311 Number *z_L, Number *z_U, Index m,
312 bool init_lambda, Number *lambda);
315 virtual bool eval_f(Index n,
const Number *x,
bool new_x, Number &obj_value);
318 virtual bool eval_grad_f(Index n,
const Number *x,
bool new_x,
323 const Eigen::VectorXd &u,
324 const Eigen::VectorXd &x1);
327 virtual bool eval_g(Index n,
const Number *x,
bool new_x, Index m, Number *g);
333 virtual bool eval_jac_g(Index n,
const Number *x,
bool new_x, Index m,
334 Index nele_jac, Index *iRow, Index *jCol,
337 virtual void compute_nnz_jac_g();
343 virtual bool eval_h(Index n,
const Number *x,
bool new_x, Number obj_factor,
344 Index m,
const Number *lambda,
bool new_lambda,
345 Index nele_hess, Index *iRow, Index *jCol,
348 virtual void compute_nnz_h();
353 const Number *z_L,
const Number *z_U, Index m,
354 const Number *g,
const Number *lambda,
355 Number obj_value,
const IpoptData *ip_data,
356 IpoptCalculatedQuantities *ip_cq);
358 virtual void update_initial_guess(
const quadNLP &nlp_prev,
int shift_idx);
360 virtual void update_solver(
361 const Eigen::VectorXd &initial_state,
const Eigen::MatrixXd &ref_traj,
362 const Eigen::MatrixXd &foot_positions,
363 const std::vector<std::vector<bool>> &contact_schedule,
364 const Eigen::VectorXi &adaptive_complexity_schedule,
365 const Eigen::VectorXd &ground_height,
366 const double &first_element_duration_,
const bool &same_plan_index,
369 void update_structure();
371 void get_lifted_trajectory(Eigen::MatrixXd &state_traj_lifted,
372 Eigen::MatrixXd &control_traj_lifted);
375 template <
typename T>
376 inline Eigen::Block<T> get_primal_state_var(T &decision_var,
377 const int &idx)
const {
378 return decision_var.block(x_idxs_[idx], 0,
n_vec_[idx], 1);
382 template <
typename T>
383 inline Eigen::Block<T> get_primal_body_state_var(T &decision_var,
384 const int &idx)
const {
385 return decision_var.block(x_idxs_[idx], 0, n_body_, 1);
389 template <
typename T>
390 inline Eigen::Block<T> get_primal_foot_state_var(T &decision_var,
391 const int &idx)
const {
392 return decision_var.block(x_idxs_[idx] + n_body_, 0, n_foot_, 1);
396 template <
typename T>
397 inline Eigen::Block<T> get_primal_joint_state_var(T &decision_var,
398 const int &idx)
const {
399 return decision_var.block(x_idxs_[idx] + n_body_ + n_foot_, 0, n_joints_,
404 template <
typename T>
405 inline Eigen::Block<T> get_primal_control_var(T &decision_var,
406 const int &idx)
const {
407 return decision_var.block(u_idxs_[idx], 0, m_vec_[idx], 1);
411 template <
typename T>
412 inline Eigen::Block<T> get_primal_body_control_var(T &decision_var,
413 const int &idx)
const {
414 return decision_var.block(u_idxs_[idx], 0, m_body_, 1);
418 template <
typename T>
419 inline Eigen::Block<T> get_primal_foot_control_var(T &decision_var,
420 const int &idx)
const {
421 return decision_var.block(u_idxs_[idx] + m_body_, 0, m_foot_, 1);
426 template <
typename T>
427 inline Eigen::Block<T> get_slack_state_var(T &decision_var,
428 const int &idx)
const {
429 return decision_var.block(slack_state_var_idxs_[idx], 0,
430 2 * n_slack_vec_[idx], 1);
435 template <
typename T>
436 inline Eigen::Block<T> get_slack_constraint_var(T &decision_var,
437 const int &idx)
const {
438 return decision_var.block(slack_constraint_var_idxs_[idx], 0,
439 2 * g_slack_vec_[idx], 1);
443 template <
typename T>
444 inline Eigen::Block<T> get_primal_constraint_vals(T &constraint_vals,
445 const int &idx)
const {
446 return constraint_vals.block(primal_constraint_idxs_[idx], 0, g_vec_[idx],
451 template <
typename T>
452 inline Eigen::Block<T> get_relaxed_primal_constraint_vals(
453 T &constraint_vals,
const int &idx)
const {
454 return constraint_vals.block(relaxed_constraint_idxs_[idx], 0,
455 2 * g_slack_vec_[idx], 1);
460 template <
typename T>
461 inline Eigen::Block<T> get_slack_constraint_vals(T &constraint_vals,
462 const int &idx)
const {
463 return constraint_vals.block(slack_var_constraint_idxs_[idx], 0,
464 2 * n_slack_vec_[idx], 1);
469 template <
typename T>
470 inline Eigen::Block<T> get_dynamic_var(T &decision_var,
471 const int &idx)
const {
472 return decision_var.block(
fe_idxs_[idx], 0,
477 template <
typename T>
478 inline Eigen::Block<T> get_dynamic_jac_var(T &jacobian_var,
479 const int &idx)
const {
480 return jacobian_var.block(dynamic_jac_var_idxs_[idx], 0,
485 template <
typename T>
486 inline Eigen::Block<T> get_relaxed_dynamic_jac_var(T &jacobian_var,
487 const int &idx)
const {
488 return jacobian_var.block(
489 relaxed_dynamic_jac_var_idxs_[idx], 0,
496 template <
typename T>
497 inline Eigen::Block<T> get_slack_jac_var(T &jacobian_var,
498 const int &idx)
const {
499 return jacobian_var.block(panic_jac_var_idxs_[idx], 0,
500 4 * n_slack_vec_[idx], 1);
504 template <
typename T>
505 inline Eigen::Block<T> get_dynamic_hess_var(T &hessian_var,
506 const int &idx)
const {
507 return hessian_var.block(dynamic_hess_var_idxs_[idx], 0,
512 template <
typename T>
513 inline Eigen::Block<T> get_state_cost_hess_var(T &hessian_var,
514 const int &idx)
const {
515 return hessian_var.block(cost_idxs_[idx], 0, n_cost_vec_[idx], 1);
519 template <
typename T>
520 inline Eigen::Block<T> get_control_cost_hess_var(T &hessian_var,
521 const int &idx)
const {
522 return hessian_var.block(cost_idxs_[idx] + n_cost_vec_[idx], 0,
523 m_cost_vec_[idx], 1);
534 return primal_constraint_idxs_[idx];
545 return slack_var_constraint_idxs_[idx];
556 return relaxed_constraint_idxs_[idx];
594 return slack_state_var_idxs_[idx];
605 return slack_constraint_var_idxs_[idx];
Definition: quad_nlp.h:105
virtual ~quadNLP()
Definition: quad_nlp.cpp:141
int get_primal_state_idx(int idx) const
Return the first index of the decision variable vector corresponding to the given finite element's st...
Definition: quad_nlp.h:575
virtual bool eval_grad_f(Index n, const Number *x, bool new_x, Number *grad_f)
Definition: quad_nlp.cpp:383
const double mass_
Mass of the platform (set to zero to ignore nominal ff)
Definition: quad_nlp.h:178
virtual bool get_starting_point(Index n, bool init_x, Number *x, bool init_z, Number *z_L, Number *z_U, Index m, bool init_lambda, Number *lambda)
Definition: quad_nlp.cpp:305
const bool use_terrain_constraint_
Boolean for whether to include the terrain in the foot height constraint.
Definition: quad_nlp.h:134
static const int num_sys_id_
Definition: quad_nlp.h:153
virtual bool eval_h(Index n, const Number *x, bool new_x, Number obj_factor, Index m, const Number *lambda, bool new_lambda, Index nele_hess, Index *iRow, Index *jCol, Number *values)
Definition: quad_nlp.cpp:880
virtual bool eval_f(Index n, const Number *x, bool new_x, Number &obj_value)
Definition: quad_nlp.cpp:329
virtual bool eval_g(Index n, const Number *x, bool new_x, Index m, Number *g)
Definition: quad_nlp.cpp:516
int n_vars_
Number of variables , primal variables, slack variables, and constraints.
Definition: quad_nlp.h:143
std::vector< casadi_int > nnz_jac_g_vec_
Vector of nonzero entries for constraint Jacobian and Hessian.
Definition: quad_nlp.h:270
Eigen::MatrixXi nnz_mat_
Matrix of function info.
Definition: quad_nlp.h:261
const int num_feet_
Number of feet.
Definition: quad_nlp.h:187
const bool apply_slack_to_complex_constr_
Boolean for whether to apply panic variables for complex constraints.
Definition: quad_nlp.h:128
int get_slack_var_constraint_idx(int idx) const
Return the first index of the slack constraint vector corresponding to the given finite element.
Definition: quad_nlp.h:544
Eigen::VectorXd eval_g_single_complex_fe(int i, const Eigen::VectorXd &x0, const Eigen::VectorXd &u, const Eigen::VectorXd &x1)
Definition: quad_nlp.cpp:443
void loadCasadiFuncs()
Load the casadi function pointers into map member vars.
Definition: quad_nlp_utils.cpp:10
quadNLP(int N, double dt, double mu, double panic_weights, double constraint_panic_weights, double Q_temporal_factor, double R_temporal_factor, const Eigen::VectorXi &fixed_complexity_schedule, const NLPConfig &config)
Definition: quad_nlp.cpp:13
int get_slack_constraint_var_idx(int idx) const
Return the first index of the decision variable vector corresponding to the slack variable for the gi...
Definition: quad_nlp.h:604
int get_primal_idx(int idx) const
Return the first index of the decision variable vector corresponding to the given finite element.
Definition: quad_nlp.h:566
Eigen::VectorXi adaptive_complexity_schedule_
Vector of ids for adaptive model complexity schedule.
Definition: quad_nlp.h:241
std::vector< std::vector< Eigen::VectorXi > > iRow_mat_
Matrix of function sparsity data.
Definition: quad_nlp.h:265
virtual bool eval_jac_g(Index n, const Number *x, bool new_x, Index m, Index nele_jac, Index *iRow, Index *jCol, Number *values)
Definition: quad_nlp.cpp:604
Eigen::VectorXi fe_idxs_
Vector of indices for relevant quantities.
Definition: quad_nlp.h:247
int n_null_
Number of state and control variables added in complex model.
Definition: quad_nlp.h:146
NLPDiagnostics diagnostics_
Diagnostics struct for gathering metadata.
Definition: quad_nlp.h:108
Eigen::VectorXd x_null_nom_
Nominal null state variables.
Definition: quad_nlp.h:149
int get_primal_constraint_idx(int idx) const
Return the first index of the constraint vector corresponding to the given finite element.
Definition: quad_nlp.h:533
grid_map::GridMap terrain_
Terrain map.
Definition: quad_nlp.h:190
Eigen::VectorXi n_vec_
Vectors of state and constraint dimension for each finite element.
Definition: quad_nlp.h:124
const double foot_mass_
Mass of the feet (as modeled in casadi)
Definition: quad_nlp.h:181
virtual void finalize_solution(SolverReturn status, Index n, const Number *x, const Number *z_L, const Number *z_U, Index m, const Number *g, const Number *lambda, Number obj_value, const IpoptData *ip_data, IpoptCalculatedQuantities *ip_cq)
Definition: quad_nlp.cpp:1071
Eigen::ArrayXi relaxed_primal_constraint_idxs_in_element_
Indices of relaxed constraints.
Definition: quad_nlp.h:254
const double grav_
Gravity constant.
Definition: quad_nlp.h:184
NLPConfig config_
Config struct for storing meta parameters.
Definition: quad_nlp.h:111
int get_slack_state_idx(int idx) const
Return the first index of the decision variable vector corresponding to the slack variable for the gi...
Definition: quad_nlp.h:593
Eigen::VectorXi sys_id_schedule_
Vector of system ids.
Definition: quad_nlp.h:258
const bool always_constrain_feet_
Boolean for whether to allow modifications of foot trajectory.
Definition: quad_nlp.h:131
std::vector< std::vector< std::string > > constr_names_
Map for constraint names.
Definition: quad_nlp.h:140
int get_primal_control_idx(int idx) const
Return the first index of the decision variable vector corresponding to the given finite element's co...
Definition: quad_nlp.h:584
void loadConstraintNames()
Load the constraint names for debugging.
Definition: quad_nlp_utils.cpp:287
int get_relaxed_constraint_idx(int idx) const
Return the first index of the slack constraint vector corresponding to the given finite element.
Definition: quad_nlp.h:555
virtual bool get_nlp_info(Index &n, Index &m, Index &nnz_jac_g, Index &nnz_h_lag, IndexStyleEnum &index_style)
Definition: quad_nlp.cpp:144
virtual bool get_bounds_info(Index n, Number *x_l, Number *x_u, Index m, Number *g_l, Number *g_u)
Definition: quad_nlp.cpp:165
Eigen::VectorXi fixed_complexity_schedule_
Vector of ids for fixed model complexity schedule.
Definition: quad_nlp.h:244
static const int num_func_id_
Definition: quad_nlp.h:157
Definition: quad_nlp.h:57
Definition: quad_nlp.h:84