Skip to content

MPC Autotuner

This page contains a guide on how to use the mpc_autotuner package, which implements Coat-MPC to tune the cost function weights of a Model Predictive Controller (MPC) for an autonomous system. The code uses ROS to communicate with the MPC via dynamic reconfigure. The goal is to minimize the lap time while ensuring that it will always be below a certain threshold. The code of Coat-MPC reuses parts of the code os SafeOpt. Furthermore, other methods such as Upper Confidence Bounds (UCB), Constrained Expected Improvement (EIC), Confidence Region BO (code resused from https://github.com/boschresearch/ConfidenceRegionBO), Weighted Maximum Likelihood (WML) and Metropolis-Hastings (MH). The pictures below show a comparison of the different algorithms tested on a real small-scale racing car.

The autotuner has been tested with the ACADOS Pacejka MPCC, tuning the lag and contour weights in simulation and at Technopark.

Usage

To use the algorithm, one should follow the steps below:

  1. Modify crs-2.0/src/ros4crs/ros_mpc_autotuner/config/interfaces.yaml with the correct CRS ROS message names. It is important to modify the velocity_estimation if the estimation node is bypassed.
topics:
  velocity_estimation: "/car_1/estimation_node/best_state"  # State estimation topic, change to /car_1/ros_simulator/gt_state if bypassing the estimation node
  lap_counter: "/car_1/lap_counter"  # Do NOT modify
  autotuner_state: "/car_1/curvilinear_state"  # Do NOT modify
  car_command: "/car_1/control_input"  # MPC command topic
  penalty_and_laps: "/car_1/mpc_autotuner/penalty_and_laps" # Do NOT modify
  autotuner_go: "/car_1/autotuner_go" # Do NOT modify
  track: "/track_info"  # Track information topic. Only modify if the track generation changes
  namespace: "track_center" # Track information namespace. Only modify if the track generation changes

# Simulation launch file
simulation: 
  package: "crs_launch"
  launch: "sim_single_car.launch"

# CRS launch file
crs:
  package: "crs_launch"
  launch: "run_single_car.launch"

frames:
  world: "world"
  base_link: "vehicle"
  1. Modify crs-2.0/src/ros4crs/ros_mpc_autotuner/config/tunable_weights.yaml with the MPC weights you want to tune. Include an initial set of values, upper and lower bounds and the MPC dynamic reconfigure server name. It is important that the initial values are within the given bounds. Additionally, these initial values must be stable (the car is able to finish laps). This is an assumption of the autotuner, otherwise it will not work properly.
  2. Modify crs-2.0/src/ros4crs/ros_mpc_autotuner/config/config.yaml with the desired optimization configuration. IMPORTANT: Add a rough estimate of the optimal lap time, a penalty time for cases where the MPC goes out of track (typically the average time*1.5), and the number of laps that you want to use for the optimization.By default, the config file is set to use Coat-MPC. The following paramerters are the most important:
# Optimization parameters
optimization_config:
  lipschitz_constant: 40.0            # Lipschitz continuity constant. Larger values will make the 
                                      # autotuner more cautious but the convergence speed will 
                                      # decrease (Not recommended to modify)

# Config parameters
interface_config:
  simulation: True                    # If set to true, the simulation interface will be used. 
                                      # If tuning at technopark: set to false

  max_time: 10.0                      # Max time allowed before ending iteration. 
                                      # Only used in simulation. The current run will stop 
                                      # after this many seconds.

  max_iterations: 72                  # Max algoritm iterations
  number_of_laps: 2                   # First lap isn't timed
  max_deviation: 0.35                 # Max deviation from centerline allowed. 
                                      # Only used in simulation. If the car deviation is larger 
                                      # than this value, the current run will stop.

  use_deviation_penalty: True         # Flag to penalize deviation, add a time penalty
  linear_penalty_slope: .1            # Deviation penalty scaling factor. This factor controls 
                                      # the importance of the deviation penalty. 
                                      # Do not set it too high.

  load_prior_data: False              # Set to true to load data from another run. 
                                      # This is important when not running in simulation. 
                                      # If the car goes out of the track, you will need to rerun 
                                      # the autotuner and set this flag to true to take 
                                      # into account the previous data.

  optimal_time: 4.5                   # Rough estimate of the optimal time of a lap

  prior_data_path: "/code/src/ros4crs/ros_mpc_autotuner/visualization/objects/26_08_2023_18_21_41/" 
                                      # Full path to prior data. Needed if load_prior_data is set to True
  1. Run the code:
roslaunch ros_mpc_autotuner autotuner.launch

The code will start communicating with the MPC via dynamic reconfigure and start tuning the cost function weights. The optimal laptimes and parameters will be saved in a folder inside src/ros4crs/ros_mpc_autotuner/visualization/objects. When the algorithm converges or reaches the maximum number of iterations, the optimal laptime and parameters will be printed in your terminal and the optimization will end.

Known issue in simulation

Sometimes, when running the autotuner in simulation, some parameters that are known to perform well might make the ACADOS solver fail at the beginning when starting the simulation. This makes the autotuner fail because it sets high laptimes to these values, which is wrong.

To avoid this, one can run the CRS interface instead of the simulation. To do so, one must set:

crs:
  package: "crs_launch"
  launch: "sim_single_car.launch"

in crs-2.0/src/ros4crs/ros_mpc_autotuner/config/interfaces.yaml and

interface_config:
  simulation: False 

in crs-2.0/src/ros4crs/ros_mpc_autotuner/config/config.yaml.

When using this setup, if the car goes out of track the autotuner will not be able to detect it. The autotuner has to be stopped manually, and restarted by setting the load_prior_data flag to true with the correct path. BEFORE restarting the autotuning, it is important to set the correct path of the current autotuning session object in src/ros4crs/ros_mpc_autotuner/visualization/config/params.yaml and run ONCE:

cd src/ros4crs/ros_mpc_autotuner/scripts
python add_penalty.py

This will add a penalty to the tuning parameters for going out of track and the autotuner will be aware of it. If this step is not done, the autotuner will retry those parameters and the car will go out of track again.

Visualization

The folder src/ros4crs/ros_mpc_autotuner/visualization contains multiple scripts to visualize the performance of the algorithms. One can use the scripts to plot the cumulative regret over time as well as the posterior of the GP. For instace, the scripts scripts/gp_visualization.py and scripts/regret.py plot the GP mean and samples, and the cumulative regret over time, respectively. Before running the scripts, it is important to set the relative path of the run you want to visualize (with respect to src/ros4crs/ros_mpc_autotuner/visualization/objects) in src/ros4crs/ros_mpc_autotuner/visualization/config/params.yaml.