DirectTrajectoryOptimization  v0.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Pages
snopt.hpp
Go to the documentation of this file.
1 /***********************************************************************************
2 Copyright (c) 2017, Diego Pardo. All rights reserved.
3 
4 Redistribution and use in source and binary forms, with or without modification,
5 are permitted provided that the following conditions are met:
6  * Redistributions of source code must retain the above copyright notice,
7  this list of conditions and the following disclaimer.
8  * Redistributions in binary form must reproduce the above copyright notice,
9  this list of conditions and the following disclaimer in the documentation
10  and/or other materials provided with the distribution.
11  * Neither the name of ETH ZURICH nor the names of its contributors may be used
12  to endorse or promote products derived from this software without specific
13  prior written permission.
14 
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
16 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
18 SHALL ETH ZURICH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
19 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
23 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 ***************************************************************************************/
25 
31 #ifndef INCLUDE_DTO_SNOPT_INTERFACE_HPP_
32 #define INCLUDE_DTO_SNOPT_INTERFACE_HPP_
33 
34 #include <Eigen/Dense>
36 #include <snopt7/snoptProblem.hpp>
37 
38 namespace DirectTrajectoryOptimization {
39 
40 // forward declaration
41 template <typename DIMENSIONS>
42 class DTOMethodInterface;
43 
48 template <class DIMENSIONS>
49 class DTOSnoptInterface : public DTOSolverInterface<DIMENSIONS> , public std::enable_shared_from_this<DTOSnoptInterface <DIMENSIONS> >
50 {
51 
52 public:
53 
54  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
55 
56  typedef typename DIMENSIONS::state_vector_array_t state_vector_array_t;
57  typedef typename DIMENSIONS::control_vector_array_t control_vector_array_t;
58 
66  std::shared_ptr<DTOMethodInterface<DIMENSIONS> > method,
67  bool snopt_verbose, bool feasible_point_only) :
68  _method(method) {
69 
70  this->_verbose = snopt_verbose;
71 
72  if (this->_verbose) {
73  minor_print_level_param = 0;
74  major_print_level_param = 1;
75  }
76 
77  _feasible_point_only = feasible_point_only;
78  };
79 
80  virtual ~DTOSnoptInterface() {
81  //interface_pointer = NULL;
82 
83  // delete variables if allocated
84  if (use_computeJacobian) {
85  delete []spt_iGfun;
86  delete []spt_jGvar;
87  }
88  delete []spt_A;
89  delete []spt_iAfun;
90  delete []spt_jAvar;
91  //delete []spt_variable_names;
92  //delete []spt_Fnames;
93  };
94 
95 
96  static std::shared_ptr<DTOSnoptInterface <DIMENSIONS> > interface_pointer;
97  std::shared_ptr<DTOMethodInterface<DIMENSIONS> > _method;
98  std::shared_ptr<snoptProblemA> nlp_solver;
99  snFunA spt_constraints_function = NULL;
100  int status_output_flag = 0;
101  bool use_computeJacobian = false;
102  bool use_print_file = false;
103  bool _feasible_point_only = false;
104 
105 
106  static void NLP_function( int *Status, int *n, double x[],
107  int *needF, int *neF, double F[],
108  int *needG, int *neG, double G[],
109  char *cu, int *lencu,
110  int iu[], int *leniu,
111  double ru[], int *lenru );
112 
113  virtual void InitializeSolver(
114  const std::string & problem_name,
115  const std::string & output_file,
116  const std::string & param_file = "",
117  const bool & computeJacobian = false) override;
118  void setupSNOPTvariables();
119  void setupNLPsolver();
120  void setupWarmStart();
121 
122  void estimateJacobianStructure();
123  virtual void Solve(bool warminit=false) override;
124 
125  void setSparsityVariables();
126  void setSnoptFLimits();
127 
128  void readParametersFromFile(const std::string & param_file);
129  void SetupSolverParameters() override;
130 
131  void validateSNOPTStatus(const int & status,
132  const Eigen::Map<Eigen::VectorXd> & x, const Eigen::Map<Eigen::VectorXd> & F);
133 
134  virtual void GetDTOSolution(
135  state_vector_array_t &yTraj,
136  control_vector_array_t &uTraj,
137  Eigen::VectorXd &hTraj) override;
138  virtual void GetDTOSolution(
139  state_vector_array_t & y_trajectory,
140  control_vector_array_t & u_trajectory,
141  Eigen::VectorXd & h_trajectory,
142  std::vector<int> & phaseId) override;
143 
144  virtual void GetDTOSolution(state_vector_array_t &yTraj,
145  state_vector_array_t &ydotTraj, control_vector_array_t & uTraj,
146  Eigen::VectorXd &hTraj, std::vector<int> &phaseId) override;
147 
148  virtual void GetFVector(Eigen::VectorXd &fVec) override {fVec = F_vector;}
149 
151  Eigen::VectorXi & _x_state,
152  Eigen::VectorXd & _x_mul,
153  Eigen::VectorXi & _f_state,
154  Eigen::VectorXd & _f_mul) override;
155 
157  const state_vector_array_t & y_sol,
158  const control_vector_array_t & u_sol,
159  const Eigen::VectorXd & h_sol) override;
160 
161  void WarmSolverInitialization(const Eigen::VectorXi & x_state,
162  const Eigen::VectorXd & x_mul,
163  const Eigen::VectorXi & f_state,
164  const Eigen::VectorXd & f_mul) override;
165 
166  void SetVerifyLevel(const int & level) override {
167  if(level > -2 && level < 4)
168  verify_level_param = level;
169  else {
170  std::cout << "incorrect verification level!" << std::endl;
171  std::exit(EXIT_FAILURE);
172  }
173  }
174 
175  void UsePrintFile(const bool & flag) override {
176  use_print_file = flag;
177  }
178 
179 private:
180  char* spt_name_of_problem = NULL;
181  char* spt_name_of_output_file = NULL;
182  char* spt_name_of_print_file=NULL;
183  //char** spt_variable_names = NULL;
184  //char* spt_Fnames = NULL;
185 
186  int spt_n_vars = 0;
187  int spt_lenF = 0;
188  int spt_obj_row = 0;
189  int spt_obj_add = 0;
190  int spt_neG = 0;
191  int jgcost_size = 0;
192  int original_size_G = 0;
193 
194  int spt_neA = 0;
195  int spt_lenA = 1;
196 
197  double * spt_A = NULL;
198 
199  int * spt_iGfun = NULL;
200  int * spt_jGvar = NULL;
201 
202  int * spt_iAfun = NULL;
203  int * spt_jAvar = NULL;
204 
205  double * spt_xlb = NULL;
206  double * spt_xub = NULL;
207 
208  double * spt_Flb = NULL;
209  double * spt_Fub = NULL;
210 
211  Eigen::VectorXd x_variables;
212  Eigen::VectorXd x_variables_validation;
213  Eigen::VectorXd x_multipliers;
214  Eigen::VectorXi x_state;
215 
216  Eigen::VectorXd F_vector;
217  Eigen::VectorXd F_vector_validation;
218  Eigen::VectorXd F_multipliers;
219  Eigen::VectorXi F_state;
220 
221  int snopt_warm_flag = 0;
222 
223  Eigen::VectorXd snopt_Flb_v;
224  Eigen::VectorXd snopt_Fub_v;
225  Eigen::VectorXi snopt_iGfun;
226  Eigen::VectorXi snopt_jGvar;
227 
228  // Derivative option
229  // = 0 some or all of the gradient elements need not be assigned values in G
230  // = 1 subroutine usrfun should compute all derivatives of F(x)
231  int derivative_option_param = 0;
232 
233  int scale_option_param = 1;
234  int verify_level_param = -1;
235  int major_iteration_limit_param = 80000;
236  int minor_iteration_limit_param = 80000;
237  int iteration_limit_param = 40000000;
238  double major_optimality_tolerance_param = 1e-1;
239  double major_feasibility_tolerance_param = 1e-6;
240  double minor_feasibility_tolerance_param = 1e-6;
241  int print_file_param = 0;
242  int minor_print_level_param = 0;
243  int major_print_level_param = 0;
244  int backup_basis_file_param = 0;
245  double line_search_tolerance_param = 0.9;
246 
247  std::string print_solution_param = "No";
248 };
249 
250 template<class DIMENSIONS>
251 std::shared_ptr<DTOSnoptInterface<DIMENSIONS> > DTOSnoptInterface<DIMENSIONS>::interface_pointer;
252 
253 template <class DIMENSIONS>
254 void DTOSnoptInterface<DIMENSIONS>::InitializeSolver(const std::string & problem_name,
255  const std::string & output_file, const std::string & param_file /*= "" */,
256  const bool &computeJacobian) {
257 
258  use_computeJacobian = computeJacobian;
259 
260  // initialize Direct Transcription problem
261  _method->Initialize();
262 
263  std::string print_file_name = output_file;
264  std::string real_output_file = output_file + ".out";
265 
266  spt_name_of_problem = const_cast<char*>(problem_name.c_str());
267  spt_name_of_output_file = const_cast<char*>(real_output_file.c_str());
268  spt_name_of_print_file = const_cast<char*>(print_file_name.c_str());
269 
270  // Size of variables, limites, sparsity and names
271  setupSNOPTvariables();
272 
273  if (param_file!="") {
274  readParametersFromFile(param_file);
275  }
276 
277  nlp_solver = std::shared_ptr<snoptProblemA>(new snoptProblemA(spt_name_of_problem));
278 
279  // Tolerance, iterations, print level, verify level, line search
280  SetupSolverParameters();
281 }
282 
283 template<class DIMENSIONS>
285 
286  interface_pointer = std::enable_shared_from_this<DTOSnoptInterface<DIMENSIONS>>::shared_from_this();
287  spt_constraints_function = &this->DTOSnoptInterface::NLP_function;
288 
289  // number of decision variables
290  spt_n_vars = _method->myNLP.GetNumVars();
291 
292  // F includes the objective in SNOPT
293  spt_lenF = _method->myNLP.GetNumF() + 1;
294  spt_xlb = _method->myNLP.GetXlb_p();
295  spt_xub = _method->myNLP.GetXub_p();
296 
297  x_variables.resize(spt_n_vars);
298  x_variables_validation.resize(spt_n_vars);
299  x_variables.setZero();
300  x_multipliers.resize(spt_n_vars);
301  x_state.resize(spt_n_vars);
302  x_state.setZero();
303 
304  F_vector.resize(spt_lenF);
305  F_vector_validation.resize(spt_lenF);
306  F_multipliers.resize(spt_lenF);
307  F_state.resize(spt_lenF);
308 
309  setSnoptFLimits();
310  setSparsityVariables();
311 }
312 
313 template <class DIMENSIONS>
314 void DTOSnoptInterface<DIMENSIONS>::setSnoptFLimits() {
315 
316  Eigen::VectorXd local_Flb = _method->myNLP.GetFlb();
317  Eigen::VectorXd local_Fub = _method->myNLP.GetFub();
318 
319  snopt_Flb_v.resize(spt_lenF);
320  snopt_Fub_v.resize(spt_lenF);
321 
322  snopt_Flb_v(0) = -infy;
323  snopt_Fub_v(0) = infy;
324 
325  snopt_Flb_v.segment(1,spt_lenF-1) = local_Flb;
326  snopt_Fub_v.segment(1,spt_lenF-1) = local_Fub;
327 
328  spt_Flb = snopt_Flb_v.data();
329  spt_Fub = snopt_Fub_v.data();
330 
331  if (this->_verbose) {
332  std::cout << "[VERBOSE] spt_lenF : " << spt_lenF << std::endl;
333  std::cout << "[VERBOSE] snopt_Flb : " << snopt_Flb_v.transpose() << std::endl;
334  std::cout << "[VERBOSE] snopt_Fub : " << snopt_Fub_v.transpose() << std::endl;
335  std::getchar();
336  }
337 }
338 
339 template <class DIMENSIONS>
340 void DTOSnoptInterface<DIMENSIONS>::setSparsityVariables() {
341 
342  Eigen::VectorXi local_iGfun = _method->myNLP.GetiGfun();
343  Eigen::VectorXi local_jGvar = _method->myNLP.GetjGvar();
344  Eigen::VectorXi local_jGcost =_method->myNLP.GetjGvarCost();
345 
346  jgcost_size = local_jGcost.size();
347  original_size_G = _method->myNLP.GetDimG();
348 
349  /* linear parts are unknown */
350  spt_lenA = spt_lenF*spt_n_vars;
351  spt_iAfun = new int[spt_lenA];
352  spt_jAvar = new int[spt_lenA];
353  spt_A = new double[spt_lenA];
354 
355  if (use_computeJacobian) {
356 
357  spt_neG = spt_lenF*spt_n_vars;
358  spt_iGfun = new int[spt_neG];
359  spt_jGvar = new int[spt_neG];
360  } else {
361 
362  spt_neG = original_size_G + jgcost_size;
363  snopt_iGfun.resize(spt_neG);
364  snopt_jGvar.resize(spt_neG);
365 
366  snopt_iGfun.segment(0,jgcost_size) = Eigen::VectorXi::Zero(jgcost_size);
367  snopt_iGfun.segment(jgcost_size,original_size_G) = local_iGfun + Eigen::VectorXi::Ones(local_iGfun.size());
368  snopt_jGvar.segment(0,jgcost_size) = local_jGcost;
369  snopt_jGvar.segment(jgcost_size,original_size_G) = local_jGvar;
370 
371  spt_iGfun = snopt_iGfun.data();
372  spt_jGvar = snopt_jGvar.data();
373  }
374 
375  if (this->_verbose) {
376  std::cout << "[VERBOSE] jgcost_size : " << jgcost_size << std::endl;
377  std::cout << "[VERBOSE] spt_neG : " << spt_neG << std::endl;
378  std::getchar();
379  std::cout << "[VERBOSE] snopt_iGfun : " << snopt_iGfun.transpose() << std::endl;
380  std::getchar();
381  std::cout << "[VERBOSE] snopt_jGvar : " << snopt_jGvar.transpose() << std::endl;
382  std::getchar();
383  }
384 }
385 
386 template <class DIMENSIONS>
387 void DTOSnoptInterface<DIMENSIONS>::setupNLPsolver() {
388 
389 
390  nlp_solver->setProblemSize( spt_n_vars , spt_lenF );
391  nlp_solver->setObjective ( spt_obj_row , spt_obj_add );
392  nlp_solver->setA ( spt_lenA, spt_neA, spt_iAfun, spt_jAvar, spt_A);
393  nlp_solver->setG ( spt_neG, spt_neG, spt_iGfun, spt_jGvar );
394  nlp_solver->setX ( x_variables.data() , spt_xlb , spt_xub , x_multipliers.data() , x_state.data());
395  nlp_solver->setF ( F_vector.data(), spt_Flb , spt_Fub , F_multipliers.data(), F_state.data() );
396  //test removing this
397  //nlp_solver->setProbName (spt_name_of_problem);
398  nlp_solver->setUserFun (spt_constraints_function);
399 
400  if(use_print_file) {
401  nlp_solver->setPrintFile(spt_name_of_print_file);
402  }
403  if (use_computeJacobian) {
404  this->estimateJacobianStructure();
405  }
406 }
407 
408 template <class DIMENSIONS>
410 
411  std::cout << std::endl << "setting parameters..." << std::endl;
412 
413  nlp_solver->setIntParameter("Scale option" , scale_option_param);
414 
415  // Derivative option
416  // = 0 some or all of the gradient elements need not be assigned values in G
417  // = 1 subroutine usrfun should compute all derivatives of F(x)
418  if (use_computeJacobian)
419  derivative_option_param = 0;
420  else
421  derivative_option_param = 1;
422 
423  // tolerance for the nonlinear constraints
424  nlp_solver->setRealParameter("Major feasibility tolerance", major_feasibility_tolerance_param);
425 
426  // tolerance for the variables bounds and linear constraints
427  nlp_solver->setRealParameter("Minor feasibility tolerance", minor_feasibility_tolerance_param);
428 
429  nlp_solver->setIntParameter("Derivative option", derivative_option_param);
430  nlp_solver->setIntParameter("Verify level" , verify_level_param);
431  nlp_solver->setIntParameter("Major iterations limit", major_iteration_limit_param);
432  nlp_solver->setIntParameter("Minor iterations limit", minor_iteration_limit_param);
433  nlp_solver->setIntParameter("Iterations limit", iteration_limit_param);
434  nlp_solver->setRealParameter("Major optimality tolerance", major_optimality_tolerance_param);
435  nlp_solver->setIntParameter("Minor print level", minor_print_level_param);
436  nlp_solver->setIntParameter("Major print level", major_print_level_param);
437 
438  // reading and saving basis files
439  nlp_solver->setIntParameter("New basis file", this->new_basis_file_param);
440  nlp_solver->setIntParameter("Old basis file", this->old_basis_file_param);
441  nlp_solver->setIntParameter("Backup basis file", backup_basis_file_param);
442 
443  // only saving at the end
444  nlp_solver->setIntParameter("Save frequency",100000000);
445 
446  if(this->_totally_quiet_) {
447  nlp_solver->setParameter("Solution No");
448  nlp_solver->setIntParameter("Summary file",0);
449  }
450  // Do not set these parameters as they crash with the filename
451  // nlp_solver->setIntParameter("Solution file",0);
452  // nlp_solver->setIntParameter("Print file",print_file_param);
453 
454  nlp_solver->setRealParameter("Linesearch tolerance", line_search_tolerance_param);
455  //nlp_solver->setParameter("Hessian limited memory");
456  //nlp_solver->setParameter("Hessian full memory");
457 
458  if (_feasible_point_only) {
459  nlp_solver->setIntParameter("Feasible point only",1);
460  nlp_solver->setParameter("Feasible point");
461  }
462 
463 }
464 
465 
466 template <class DIMENSIONS>
468 
469  nlp_solver->computeJac(spt_neA,spt_neG);
470 
471  /* user may decide to stop here */
472  std::cout << "Jacobian Structure has been estimated" << std::endl;
473  std::cout << "please press [ENTER] if you want to continue with optimization" << std::endl;
474  getchar();
475 }
476 
477 template <class DIMENSIONS>
479  std::cout << "Ready to solve... " << std::endl;
480 
481  // Only setup the NLP solver just before solving
482  setupNLPsolver();
483 
484  if (warminit)
485  snopt_warm_flag = 2;
486 
487  nlp_solver->solve(snopt_warm_flag);
488 
489  if(this->x_variables_validation.size() < 1){
490  std::cout << "Internal error!" << std::endl;
491  return;
492  }
493  // just to be sure SNOPT is not making stupid things!
494  double epsilon_e = 1e-5;
495  for(auto i = 0 ; i < this->spt_n_vars ; ++i) {
496  if(std::fabs(this->x_variables(i) - this->x_variables_validation(i)) > epsilon_e) {
497  std::cout << "SNOPT BUG! : X_variables are not the same!" << std::endl;
498  std::cout << "x_variables("<< i <<") : " << x_variables(i) << std::endl;
499  std::cout << "x_validation("<< i <<") : " << x_variables_validation(i) << std::endl;
500  }
501  }
502 
503  for(auto i = 0 ; i < this->spt_lenF; ++i) {
504  if(std::fabs(this->F_vector(i) - this->F_vector_validation(i)) > epsilon_e) {
505  std::cout << "SNOPT BUG! : Constraints are not consistent" << std::endl;
506  std::cout << "F_vector("<< i <<") : " << F_vector(i) << std::endl;
507  std::cout << "F_validation("<< i <<") : " << F_vector_validation(i) << std::endl;
508  std::cout << "F_lb("<< i <<") : " << this->snopt_Flb_v(i) << std::endl;
509  std::cout << "F_ub("<< i <<") : " << this->snopt_Fub_v(i) << std::endl;
510  }
511  }
512 
513 }
514 
515 //This should be in "METHOD CLASS"
516 //template <class DIMENSIONS>
517 //void DTOSnoptInterface<DIMENSIONS>::setXVariableNames() {
518 //
519 // int names_array_length = spt_n_vars; // * 8;
520 //
521 // spt_variable_names = new char*[spt_n_vars];
522 //
523 //
524 // std::string base_index = "h_";
525 // std::string base_stat = "s_";
526 // std::string base_cont = "c_";
527 //
528 // Eigen::VectorXi h_indexes;
529 // Eigen::MatrixXi y_indexes;
530 // Eigen::MatrixXi u_indexes;
531 //
532 // _method->getTrajectoryIndexes(h_indexes,y_indexes,u_indexes);
533 //
534 // int increment = 0;
535 // int state = 0;
536 // int control = 0;
537 // int current_node = 0;
538 // // The indexes
539 //
540 // for (int i = 0; i < spt_n_vars; i++) {
541 //
542 // spt_variable_names[i] = new char[8];
543 //
544 // std::string name;
545 //
546 // if (i < y_indexes(0,0)) {
547 // name = base_index + std::to_string(increment);
548 // increment++;
549 //
550 // } else if (i < u_indexes(0,0)) {
551 // name = base_stat + std::to_string(state) + "_" + std::to_string(current_node);
552 // state++;
553 // if(state > y_indexes.rows()) {
554 // state = 0;
555 // current_node++;
556 // }
557 // if(current_node > y_indexes.cols())
558 // current_node=0;
559 //
560 // } else {
561 // name = base_cont + std::to_string(control) + "_" + std::to_string(current_node);
562 // control++;
563 // if(control > u_indexes.rows()) {
564 // control = 0;
565 // current_node++;
566 // }
567 // if(current_node > u_indexes.cols())
568 // current_node=0;
569 // }
570 //
571 // spt_variable_names[i] = const_cast<char*>(name.c_str());
572 // }
573 
574 // spt_Fnames = new char[8];
575 //}
576 
577 template <class DIMENSIONS>
578 void DTOSnoptInterface<DIMENSIONS>::readParametersFromFile(const std::string & param_file) {
579  //ToDo : update using cereal?
580 }
581 
582 template <class DIMENSIONS>
583 void DTOSnoptInterface<DIMENSIONS>::validateSNOPTStatus(const int & status,
584  const Eigen::Map<Eigen::VectorXd> & X, const Eigen::Map<Eigen::VectorXd> & F) {
585 
586  /*Status = 2 , optimal solution
587  Status = 3 , problem is infeasible
588  Status = 4 , unbounded
589  Status = 5 , iterations limit */
590 
591  std::string message;
592 
593  switch (status) {
594  case 2:
595  message = "OPTIMAL SOLUTION FOUND!!!!";
596  break;
597  case 3:
598  message = "Problem is Infeasible :-(";
599  break;
600  case 4:
601  message = "---> Unbounded <---";
602  break;
603  case 5:
604  message = "-> Iteration Limit <-";
605  break;
606  }
607 
608  std::cout << message << std::endl;
609 
610  this->F_vector_validation = F;
611  this->x_variables_validation = X;
612 }
613 
614 template <class DIMENSIONS>
616  Eigen::VectorXd & _x_mul, Eigen::VectorXi & _f_state, Eigen::VectorXd & _f_mul) {
617 
618  _x_state = this->x_state;
619  _x_mul = this->x_multipliers;
620 
621  _f_state = this->F_state;
622  _f_mul = this->F_multipliers;
623 }
624 
625 
626 template <class DIMENSIONS>
628  const control_vector_array_t & u_sol, const Eigen::VectorXd &h_sol) {
629 
630  _method->SetDecisionVariablesFromStateControlIncrementsTrajectories(this->x_variables,y_sol,u_sol,h_sol);
631 
632 }
633 
634 template <class DIMENSIONS>
635 void DTOSnoptInterface<DIMENSIONS>::WarmSolverInitialization(const Eigen::VectorXi & p_x_state,
636  const Eigen::VectorXd & p_x_mul, const Eigen::VectorXi & p_f_state,
637  const Eigen::VectorXd & p_f_mul) {
638 
639  if(p_x_state.size() == spt_n_vars) {
640  x_state = p_x_state;
641  x_multipliers = p_x_mul;
642  F_state = p_f_state;
643  F_multipliers = p_f_mul;
644  } else {
645  std::cout << "Error during SNOPT solver initialization" << std::endl;
646  std::exit(EXIT_FAILURE);
647  }
648 }
649 
650 template <class DIMENSIONS>
651 void DTOSnoptInterface<DIMENSIONS>::GetDTOSolution(state_vector_array_t & y_trajectory,
652  control_vector_array_t & u_trajectory, Eigen::VectorXd & h_trajectory) {
653  Eigen::Map<Eigen::VectorXd> x_vector(x_variables.data(),spt_n_vars);
654 
655  _method->getStateControlIncrementsTrajectoriesFromDecisionVariables(x_vector,y_trajectory,u_trajectory,h_trajectory);
656 }
657 
658 template <class DIMENSIONS>
659 void DTOSnoptInterface<DIMENSIONS>::GetDTOSolution(state_vector_array_t & y_trajectory,
660  control_vector_array_t & u_trajectory, Eigen::VectorXd & h_trajectory,
661  std::vector<int> & phaseId) {
662 
663  this->GetDTOSolution(y_trajectory, u_trajectory, h_trajectory);
664 
665  phaseId = _method->node_to_phase_map;
666 }
667 
668 template <class DIMENSIONS>
669 void DTOSnoptInterface<DIMENSIONS>::GetDTOSolution(state_vector_array_t &yTraj, state_vector_array_t &ydotTraj,
670  control_vector_array_t & uTraj, Eigen::VectorXd &hTraj, std::vector<int> &phaseId) {
671 
672  //Eigen::Map<Eigen::VectorXd> x_vector(x_variables.data(),spt_n_vars);
673 
674  _method->UpdateDecisionVariables(x_variables.data());
675  _method->getCompleteSolution(yTraj,ydotTraj,uTraj,hTraj,phaseId);
676 
677 }
678 
679 template <class DIMENSIONS>
680 void DTOSnoptInterface<DIMENSIONS>::NLP_function( int *Status, int *n, double x[],
681  int *needF, int *neF, double F[],
682  int *needG, int *neG, double G[],
683  char *cu, int *lencu,
684  int iu[], int *leniu,
685  double ru[], int *lenru ) {
686 
687  DTOSnoptInterface<DIMENSIONS>::interface_pointer->_method->UpdateDecisionVariables(x);
688 
689  // compute G(x)
690  if (*needG > 0 && !(DTOSnoptInterface<DIMENSIONS>::interface_pointer->use_computeJacobian)) {
691 
692  //This is here for debugging
693  // int size_of_gcost = DTOSnoptInterface<DIMENSIONS>::interface_pointer->jgcost_size;
694  // int size_of_G = DTOSnoptInterface<DIMENSIONS>::interface_pointer->original_size_G;
695  // int total_size_of_G = size_of_gcost + size_of_G;
696  // if(*neG > total_size_of_G || *neG < total_size_of_G) {
697  // std::cout << "BIG ERROR!" << std::endl;
698  // std::exit(EXIT_FAILURE);
699  // }
700 
701  DTOSnoptInterface<DIMENSIONS>::interface_pointer->_method->evalSparseJacobianCost(G);
703  }
704 
705  // compute F(x)
706  if (*needF > 0) {
707  DTOSnoptInterface<DIMENSIONS>::interface_pointer->_method->evalObjective(&F[0]);
708  DTOSnoptInterface<DIMENSIONS>::interface_pointer->_method->evalConstraintFct(&F[1], *neF - 1);
709  }
710 
711  /*
712  Status = 0 : there is nothing special about the current call to usrfun
713  Status = 1 : snOptA is calling your subroutine for the FIST time
714  Status >= 2 : snOptA is calling your subroutine for the LAST time
715  */
716  if (*Status > 1) {
717  Eigen::Map<Eigen::VectorXd> F_b(F,*neF);
718  Eigen::Map<Eigen::VectorXd> X_vector(x,*n);
719  DTOSnoptInterface<DIMENSIONS>::interface_pointer->status_output_flag = *Status;
720  DTOSnoptInterface<DIMENSIONS>::interface_pointer->validateSNOPTStatus(*Status,X_vector,F_b);
721  }
722 }
723 
724 } // namespace DirectTrajectoryOptimization
725 
726 #endif /*INCLUDE_DTO_SNOPT_INTERFACE_HPP_*/
virtual void InitializeSolver(const std::string &problem_name, const std::string &output_file, const std::string &param_file="", const bool &computeJacobian=false) override
DTO initializes the solver using this method.
Definition: snopt.hpp:254
This class serves as a base interface for inheriting classes.
Definition: base_method_interface.hpp:60
virtual void GetDTOSolution(state_vector_array_t &yTraj, control_vector_array_t &uTraj, Eigen::VectorXd &hTraj) override
Method to get the current values of the solution.
Definition: snopt.hpp:651
std::shared_ptr< DTOMethodInterface< DIMENSIONS > > _method
Definition: snopt.hpp:97
void InitializeDecisionVariablesFromTrajectory(const state_vector_array_t &y_sol, const control_vector_array_t &u_sol, const Eigen::VectorXd &h_sol) override
Initial solution point for the solver.
Definition: snopt.hpp:627
void SetupSolverParameters() override
Setting up solver parameters.
Definition: snopt.hpp:409
Base class for NLP Solvers interface.
virtual void Solve(bool warminit=false) override
DTO request the solver to proceed with the NLP.
Definition: snopt.hpp:478
This class serves as a base interface for inheriting classes.
Definition: base_solver_interface.hpp:47
Class interfacing SNOPT NLP with DTO Problem.
Definition: snopt.hpp:49
std::shared_ptr< snoptProblemA > nlp_solver
Definition: snopt.hpp:98
virtual void GetFVector(Eigen::VectorXd &fVec) override
Returns the vector of NLP-constraints.
Definition: snopt.hpp:148
void GetSolverSolutionVariables(Eigen::VectorXi &_x_state, Eigen::VectorXd &_x_mul, Eigen::VectorXi &_f_state, Eigen::VectorXd &_f_mul) override
Method to get final values of internal solver variables.
Definition: snopt.hpp:615
static std::shared_ptr< DTOSnoptInterface< DIMENSIONS > > interface_pointer
Definition: snopt.hpp:93
DTOSnoptInterface(std::shared_ptr< DTOMethodInterface< DIMENSIONS > > method, bool snopt_verbose, bool feasible_point_only)
Constructor.
Definition: snopt.hpp:65
void WarmSolverInitialization(const Eigen::VectorXi &x_state, const Eigen::VectorXd &x_mul, const Eigen::VectorXi &f_state, const Eigen::VectorXd &f_mul) override
Warm Initialization of NLP Solver.
Definition: snopt.hpp:635