Skip to content

Acados MPCC Solver

The Acados implementation of the Pacejka MPCC solver uses the Pacejka Model and the Acados Solver to solve the nonlinear optimization problem.

Solver Scripts

The Acados solver is written in python (generate_acados_solver.py). In this file all constraints and costs are loaded from the pacejka_model.py file. This contains the model, a definition of the used constraints and the cost. The script create_solver.sh needs to be executed to generate the solver.

Recreating and building the C-Code

The C code is generated and built when the corresponding acados_pacejka_mpcc_solver package is built using catkin build acados_pacejka_mpcc_solver or crs build. Alternatively, one can manually generate code:

crs generate

CRS Interface

The file acados_pacejka_mpcc_solver.cpp formulates the interfaced between the solver and the CRS framework. This file is used to e.g. set model parameters used in the solver or formulate useful helper functions such as getHorizonLength(), which allow us to access solver specific information from CRS.

Solver Parameters

For each stage of the MPC formulation, the following parameters need to be provided.

tracking_costs

  • Q1 Contouring Cost : Punishes the lateral error to the reference track point
  • Q2 Lag Cost : Punishes the longitudinal error to the reference track point
  • R1 dTorque Cost : Punishes changes in torque
  • R2 dSteer Cost : Punishes changes in steering
  • R3 dArclength Cost : (Reference Sampling) punishes changes in distance between reference points
  • q Arclength Cost : (Reference Sampling) rewards longer distance of reference points

trajectory_track_point

  • x Reference point x coordinate
  • y Reference point y coordinate
  • grad_x Track gradient in x direction
  • grad_y Track gradient in y direction
  • theta Distance on centerline (from start of track)
  • phi Reference yaw angle

image

Example

The following code illustrates the usage of the solver interface

Example Code
// Last solution is a struct containing two arrays states_, inputs_
// x0, measured state
solver_->setInitialStateConstraint(x0);
// Run solver
for (int current_stage = 0; current_stage < solver_->getHorizonLength(); current_stage++)
{
   // next stage points to current_stage + 1. If current_stage is at end of horizon, next stage directy points to
   // current stage i.e. current_stage = 2 -> next_stage = 3, current_stage = 29 -> next_stage = 29, assuming
   // horizon of 30
   int next_stage = current_stage + (current_stage != solver_->getHorizonLength() - 1);
   mpc_solvers::pacejka_solvers::trajectory_track_point track_point;  // Calculate reference point for this stage
   // ...
   mpc_solvers::pacejka_solvers::tracking_costs mpc_costs  mpc_costs;  // Set mpc costs
   // ...

   solver_->updateParams(current_stage,
                        pacejka_params,      // Model Dynamics
                        mpc_costs,            // Costs
                        track_point           // Tracking point
   );

   // Use previous solution as initial guess this time
   solver_->setStateInitialGuess(current_stage, &last_solution.states_[next_stage * solver_->getStateDimension()]);
   solver_->setInputInitialGuess(current_stage, &last_solution.inputs_[next_stage * solver_->getInputDimension()]);
}
solver_->solve(&last_solution.states_[0], &last_solution.inputs_[0]);