MonitorMPC.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. #include "MonitorMPC.h"
  2. #include <cppad/cppad.hpp>
  3. #include <cppad/ipopt/solve.hpp>
  4. #include "Eigen/Core"
  5. #include "Eigen/QR"
  6. using CppAD::AD;
  7. // Set the timestep length and duration
  8. // Currently tuned to predict 1 second worth
  9. size_t N = 10;
  10. // The solver takes all the state variables and actuator
  11. // variables in a singular vector. Thus, we should to establish
  12. // when one variable starts and another ends to make our lifes easier.
  13. size_t nx = 0;
  14. size_t ny = nx + N;
  15. size_t nth = ny + N;
  16. size_t nv = nth + N;
  17. size_t nvth = nv + N;
  18. class FG_eval {
  19. public:
  20. // Fitted polynomial coefficients
  21. Eigen::VectorXd coeffs;
  22. double m_ref_v,m_dt;
  23. double m_v,m_vth;
  24. FG_eval(Eigen::VectorXd coeffs,double v,double vth,double ref_v,double dt) {
  25. this->coeffs = coeffs;
  26. m_v=v;
  27. m_vth=vth;
  28. m_ref_v=ref_v;
  29. m_dt=dt;
  30. }
  31. typedef CPPAD_TESTVECTOR(AD<double>) ADvector;
  32. void operator()(ADvector& fg, const ADvector& vars) {
  33. // Implementing MPC below
  34. // `fg` a vector of the cost constraints, `vars` is a vector of variable values (state & actuators)
  35. // The cost is stored is the first element of `fg`.
  36. // Any additions to the cost should be added to `fg[0]`.
  37. fg[0] = 0;
  38. double dt=m_dt;
  39. // Reference State Cost
  40. // Below defines the cost related the reference state and
  41. // any anything you think may be beneficial.
  42. // Weights for how "important" each cost is - can be tuned
  43. const int y_cost_weight = 1500;
  44. const int th_cost_weight = 1000;
  45. const int v_cost_weight = 20;
  46. const int vth_cost_weight = 100;
  47. const int a_cost_weight = 1;
  48. const int ath_cost_weight=100;
  49. // Cost for CTE, psi error and velocity
  50. for (int t = 0; t < N; t++) {
  51. AD<double> xt=vars[nx+t];
  52. AD<double> fx = coeffs[0] + coeffs[1] * xt + coeffs[2] * pow(xt, 2) + coeffs[3] * pow(xt, 3);
  53. fg[0] += y_cost_weight * CppAD::pow(vars[ny + t]-fx, 2);
  54. AD<double> fth = CppAD::atan(coeffs[1] + 2*coeffs[2]*xt + 3*coeffs[3]*pow(xt,2));
  55. fg[0] += th_cost_weight * CppAD::pow(vars[nth + t]-fth, 2);
  56. fg[0]+=v_cost_weight*CppAD::pow(vars[nv+t]-m_ref_v,2);
  57. }
  58. // Costs for steering (delta) and acceleration (a)
  59. for (int t = 0; t < N-1; t++) {
  60. fg[0] += vth_cost_weight * CppAD::pow(vars[nvth + t], 2);
  61. fg[0] += a_cost_weight * CppAD::pow(vars[nv + t+1]-vars[nv+t], 2);
  62. fg[0] += ath_cost_weight * CppAD::pow(vars[nvth + t+1]-vars[nvth+t], 2);
  63. }
  64. /////////////////////
  65. fg[1 + nx] = vars[nx]-vars[nv]*dt;
  66. fg[1 + ny] = vars[ny];
  67. fg[1 + nth] = vars[nth]-vars[nvth]*dt;
  68. // The rest of the constraints
  69. for (int t = 1; t < N; t++) {
  70. // State at time t + 1
  71. AD<double> x1 = vars[nx + t];
  72. AD<double> y1 = vars[ny + t];
  73. AD<double> th1 = vars[nth + t];
  74. AD<double> v1 = vars[nv + t];
  75. AD<double> vth1 = vars[nvth + t];
  76. // State at time t
  77. AD<double> x0 = vars[nx + t -1];
  78. AD<double> y0 = vars[ny + t -1];
  79. AD<double> th0 = vars[nth + t-1];
  80. AD<double> v0 = vars[nv + t-1];
  81. AD<double> vth0 = vars[nvth + t-1];
  82. // Actuator constraints at time t only
  83. // Setting up the rest of the model constraints
  84. fg[1 + nx + t] = x1 - (x0 + v0 * CppAD::cos(th0) * dt);
  85. fg[1 + ny + t] = y1 - (y0 + v0 * CppAD::sin(th0) * dt);
  86. fg[1 + nth + t] = th1 - (th0 + vth0 * dt);
  87. }
  88. fg[1 + nv]=(vars[nv]-m_v)/dt;
  89. fg[1+nvth]=(vars[nvth]-m_vth)/dt;
  90. for(int t=1;t<N;++t)
  91. {
  92. fg[1+nv+t]=(vars[nv+t]-vars[nv+t-1])/dt;
  93. fg[1+nvth+t]=(vars[nvth+t]-vars[nvth+t-1])/dt;
  94. }
  95. //// add
  96. }
  97. };
  98. //
  99. // MPC class definition implementation.
  100. //
  101. MonitorMPC::MonitorMPC() {}
  102. MonitorMPC::~MonitorMPC() {}
  103. bool MonitorMPC::Solve(Eigen::VectorXd state, Eigen::VectorXd coeffs, std::vector<double>& out) {
  104. bool ok = true;
  105. typedef CPPAD_TESTVECTOR(double) Dvector;
  106. // State vector holds all current values neede for vars below
  107. double v = state[0];
  108. double vth = state[1];
  109. double ref_v = state[2];
  110. double max_v=state[3];
  111. double dt=state[4];
  112. // Setting the number of model variables (includes both states and inputs).
  113. // N * state vector size + (N - 1) * 2 actuators (For steering & acceleration)
  114. size_t n_vars = N * 5;
  115. // Setting the number of constraints
  116. size_t n_constraints = N * 5;
  117. // Initial value of the independent variables.
  118. // SHOULD BE 0 besides initial state.
  119. Dvector vars(n_vars);
  120. for (int i = 0; i < n_vars; i++) {
  121. vars[i] = 0.0;
  122. }
  123. Dvector vars_lowerbound(n_vars);
  124. Dvector vars_upperbound(n_vars);
  125. // Sets lower and upper limits for variables.
  126. // Set all non-actuators upper and lowerlimits
  127. // to the max negative and positive values.
  128. for (int i = 0; i < n_vars; i++) {
  129. vars_lowerbound[i] = -1.0e19;
  130. vars_upperbound[i] = 1.0e19;
  131. }
  132. //// limit v
  133. for (int i = nv; i < nv+N; i++) {
  134. vars_lowerbound[i] = -max_v;
  135. vars_upperbound[i] = max_v;
  136. }
  137. ////limint vth
  138. for (int i = nvth; i < nvth+N; i++) {
  139. vars_lowerbound[i] = -0.5;
  140. vars_upperbound[i] = 0.5;
  141. }
  142. // Lower and upper limits for the constraints
  143. // Should be 0 besides initial state.
  144. Dvector constraints_lowerbound(n_constraints);
  145. Dvector constraints_upperbound(n_constraints);
  146. for (int i = 0; i < n_constraints; i++) {
  147. constraints_lowerbound[i] = 0;
  148. constraints_upperbound[i] = 0;
  149. }
  150. //// acc v
  151. for (int i = nv; i < nv+N; i++) {
  152. constraints_lowerbound[i] = -5.0;
  153. constraints_upperbound[i] = 5.0;
  154. }
  155. //// acc vth
  156. for (int i = nvth; i < nvth+N; i++) {
  157. constraints_lowerbound[i] = -2.5;
  158. constraints_upperbound[i] = 2.5;
  159. }
  160. // object that computes objective and constraints
  161. FG_eval fg_eval(coeffs,v,vth,ref_v,dt);
  162. //
  163. // NOTE: You don't have to worry about these options
  164. //
  165. // options for IPOPT solver
  166. std::string options;
  167. // Uncomment this if you'd like more print information
  168. options += "Integer print_level 0\n";
  169. // NOTE: Setting sparse to true allows the solver to take advantage
  170. // of sparse routines, this makes the computation MUCH FASTER. If you
  171. // can uncomment 1 of these and see if it makes a difference or not but
  172. // if you uncomment both the computation time should go up in orders of
  173. // magnitude.
  174. options += "Sparse true forward\n";
  175. options += "Sparse true reverse\n";
  176. // NOTE: Currently the solver has a maximum time limit of 0.5 seconds.
  177. // Change this as you see fit.
  178. options += "Numeric max_cpu_time 0.5\n";
  179. // place to return solution
  180. CppAD::ipopt::solve_result<Dvector> solution;
  181. // solve the problem
  182. CppAD::ipopt::solve<Dvector, FG_eval>(
  183. options, vars, vars_lowerbound, vars_upperbound, constraints_lowerbound,
  184. constraints_upperbound, fg_eval, solution);
  185. // Check some of the solution values
  186. ok &= solution.status == CppAD::ipopt::solve_result<Dvector>::success;
  187. // Cost
  188. auto cost = solution.obj_value;
  189. //std::cout << "Cost " << cost << std::endl;
  190. // Return the first actuator values, along with predicted x and y values to plot in the simulator.
  191. out.clear();
  192. m_trajectory.clear();
  193. out.push_back(solution.x[nv]);
  194. out.push_back(solution.x[nvth]);
  195. for (int i = 0; i < N; ++i) {
  196. out.push_back(solution.x[nx + i]);
  197. out.push_back(solution.x[ny + i]);
  198. tf::Pose pose;
  199. pose.setOrigin(tf::Vector3(solution.x[nx+i],solution.x[ny+i],0));
  200. m_trajectory.push_back(pose);
  201. }
  202. printf(" cost : %.3f\n",cost);
  203. return ok;
  204. }