主动驾驶控制与规划——Project 4: MPC车辆控制

打印 上一主题 下一主题

主题 835|帖子 835|积分 2505

零、使命介绍

补全carla-ros-bridge/src/ros-bridge/carla_shenlan_projects/carla_shenlan_mpc_controller/src/mpc_controller.cpp中动力学模型和代价函数构造部分,实现车辆MPC控制。
一、情况设置

使用如下命令安装CppAD
  1. sudo apt install cppad
复制代码
ipopt的安装参考Linux | Ubuntu 20.04安装ipopt和cppAD | 安装全流程+报错解决,使用方法二源码安装即可。
CppAD库的使用可以参考CppAD优化问题求解
二、算法原理

本次使用的线性化模型与上一篇博客主动驾驶控制与规划——Project 3: LQR车辆横向控制的相同。使用欧拉前向法离散化,有如下的等式束缚:
                                                                                           x                                        (                                        k                                        +                                        1                                        )                                                                                                                       =                                        x                                        (                                        k                                        )                                        +                                                       v                                           x                                                      (                                        k                                        )                                        cos                                        ⁡                                        ψ                                        (                                        k                                        )                                        Δ                                        t                                        −                                                       v                                           y                                                      (                                        k                                        )                                        sin                                        ⁡                                        ψ                                        (                                        k                                        )                                        Δ                                        t                                                                                                                            y                                        (                                        k                                        +                                        1                                        )                                                                                                                       =                                        y                                        (                                        k                                        )                                        +                                                       v                                           y                                                      (                                        k                                        )                                        sin                                        ⁡                                        ψ                                        (                                        k                                        )                                        Δ                                        t                                        +                                                       v                                           y                                                      (                                        k                                        )                                        cos                                        ⁡                                        ψ                                        (                                        k                                        )                                        Δ                                        t                                                                                                                            ψ                                        (                                        k                                        +                                        1                                        )                                                                                                                       =                                        ψ                                        (                                        k                                        )                                        +                                        r                                        (                                        k                                        )                                        Δ                                        t                                                                                                                                           v                                           x                                                      (                                        k                                        +                                        1                                        )                                                                                                                       =                                                       v                                           x                                                      (                                        k                                        )                                        +                                                       a                                           x                                                      (                                        k                                        )                                        Δ                                        t                                                                                                                                           a                                           y                                                      (                                        k                                        )                                                                                                                       =                                        −                                                                                        c                                                 f                                                              +                                                               c                                                 r                                                                                          m                                                               v                                                 x                                                              (                                              k                                              )                                                                                    v                                           y                                                      (                                        k                                        )                                        +                                                       (                                                                                              l                                                    r                                                                                    c                                                    r                                                                  −                                                                   l                                                    f                                                                                    c                                                    f                                                                                                m                                                                   v                                                    x                                                                  (                                                 k                                                 )                                                                          −                                                           v                                              x                                                          (                                           k                                           )                                           )                                                      r                                        (                                        k                                        )                                                                                                                                           v                                           y                                                      (                                        k                                        +                                        1                                        )                                                                                                                       =                                                       v                                           y                                                      (                                        k                                        )                                        +                                                       a                                           y                                                      (                                        k                                        )                                        Δ                                        t                                                                                                                            α                                        (                                        k                                        )                                                                                                                       =                                                                                        l                                                 r                                                                               c                                                 r                                                              −                                                               l                                                 f                                                                               c                                                 f                                                                                                           I                                                 z                                                                               v                                                 x                                                              (                                              k                                              )                                                                                    v                                           y                                                      (                                        k                                        )                                        −                                                                                        l                                                 f                                                 2                                                                               c                                                 f                                                              +                                                               l                                                 r                                                 2                                                                               c                                                 r                                                                                                           I                                                 z                                                                               v                                                 x                                                              (                                              k                                              )                                                                     r                                        (                                        k                                        )                                                                                                                            r                                        (                                        k                                        +                                        1                                        )                                                                                                                       =                                        r                                        (                                        k                                        )                                        +                                        α                                        (                                        k                                        )                                        Δ                                        t                                                                                \begin{aligned} x(k+1) &= x(k) + v_x(k)\cos \psi(k) \Delta t - v_y(k) \sin \psi(k)\Delta t\\ y(k+1) &= y(k) + v_y(k)\sin\psi(k)\Delta t + v_y(k)\cos\psi(k)\Delta t \\ \psi(k+1) &= \psi(k)+r(k)\Delta t \\ v_x(k+1) &= v_x(k) + a_x(k)\Delta t \\ a_y(k) &= -\frac{c_f + c_r}{mv_x(k)} v_y(k) + \left(\frac{l_r c_r - l_f c_f}{m v_x(k)} - v_x(k)\right) r(k) \\ v_y(k+1) &= v_y(k) + a_y(k) \Delta t \\ \alpha(k) &= \frac{l_r c_r - l_f c_f}{I_z v_x(k)} v_y(k) - \frac{l_f^2c_f + l_r^2c_r}{I_z v_x(k)} r(k) \\ r(k+1)&= r(k) + \alpha(k)\Delta t\\ \end{aligned}                     x(k+1)y(k+1)ψ(k+1)vx​(k+1)ay​(k)vy​(k+1)α(k)r(k+1)​=x(k)+vx​(k)cosψ(k)Δt−vy​(k)sinψ(k)Δt=y(k)+vy​(k)sinψ(k)Δt+vy​(k)cosψ(k)Δt=ψ(k)+r(k)Δt=vx​(k)+ax​(k)Δt=−mvx​(k)cf​+cr​​vy​(k)+(mvx​(k)lr​cr​−lf​cf​​−vx​(k))r(k)=vy​(k)+ay​(k)Δt=Iz​vx​(k)lr​cr​−lf​cf​​vy​(k)−Iz​vx​(k)lf2​cf​+lr2​cr​​r(k)=r(k)+α(k)Δt​
其中                                   x                         (                         k                         )                              x(k)                  x(k)是                                   k                              k                  k时刻车辆在世界系下的                                   x                              x                  x坐标;                                   y                         (                         k                         )                              y(k)                  y(k)是                                   k                              k                  k时刻车辆在世界系下的                                   y                              y                  y坐标;                                             v                            x                                       v_x                  vx​是车辆纵向速率;                                             v                            y                                       v_y                  vy​是车辆横向速率;                                   ψ                              \psi                  ψ是偏航角;                                   r                              r                  r是偏航角速率;                                             a                            y                                       a_y                  ay​是车辆横向加速率;                                   α                              \alpha                  α是偏航角加速率;                                   Δ                         t                              \Delta t                  Δt是猜测的时间步长。其他车辆参数寄义可以参考上一期博客主动驾驶控制与规划——Project 3: LQR车辆横向控制。
除上述等式束缚以外,为了使求解速率加快,增长如下的束缚条件令
思量三个方面的代价函数:
  三、代码实现

构造函数,初始化状态、目标状态、权重等。
  1. FG_eval::FG_eval(const Eigen::VectorXd &state, VectorXd coeffs, const double &target_v, const int &cte_weight, const int &epsi_weight, const int &v_weight, const int &steer_actuator_cost_weight, const int &acc_actuator_cost_weight, const int &change_steer_cost_weight,
  2.                  const int &change_accel_cost_weight, const int &mpc_prediction_horizon_length, const int &mpc_control_horizon_length, const double &mpc_control_step_length, const double &kinamatic_para_Lf, const double &a_lateral, const double &old_steer_value, const double &old_throttle_value,
  3.                  const double &steer_ratio) {
  4.     this->steer_ratio = steer_ratio;
  5.     this->coeffs = coeffs;
  6.     this->ref_v = target_v;
  7.     this->cte_weight = cte_weight;
  8.     this->epsi_weight = epsi_weight;
  9.     this->v_weight = v_weight;
  10.     this->steer_actuator_cost_weight_fg = steer_actuator_cost_weight;
  11.     this->acc_actuator_cost_weight_fg = acc_actuator_cost_weight;
  12.     this->change_steer_cost_weight = change_steer_cost_weight;
  13.     this->change_accel_cost_weight = change_accel_cost_weight;
  14.     this->Np = mpc_prediction_horizon_length;
  15.     this->Nc = mpc_control_horizon_length;
  16.     this->dt = mpc_control_step_length;
  17.     this->Lf = kinamatic_para_Lf;
  18.     this->a_lateral = a_lateral;
  19.     /*Indexes on the 1-D vector for readability, These indexes are used for "vars"*/
  20.     this->x_start = 0;
  21.     this->y_start = x_start + Np;
  22.     this->psi_start = y_start + Np;
  23.     this->v_longitudinal_start = psi_start + Np;
  24.     this->v_lateral_start = v_longitudinal_start + Np;
  25.     this->yaw_rate_start = v_lateral_start + Np;
  26.     this->cte_start = yaw_rate_start + Np;
  27.     this->epsi_start = cte_start + Np;
  28.     this->front_wheel_angle_start = epsi_start + Np;
  29.     this->longitudinal_acceleration_start = front_wheel_angle_start + Nc;
  30.     //控制时域长度为25的时候,控制增量一共有24个,第一个时刻点控制量与控制增量相同
  31.     // this->front_wheel_angle_increment_start = epsi_start + Np;
  32.     // this->longitudinal_acceleration_increment_start = front_wheel_angle_increment_start + Nc - 1;
  33.     this->old_steer_value = old_steer_value;
  34.     this->old_throttle_value = old_throttle_value;
  35.     /* Explicitly gather state values for readability */
  36.     this->x = state[0];
  37.     this->y = state[1];
  38.     this->psi = state[2];
  39.     this->v_longitudinal = state[3];
  40.     this->v_lateral = state[4];
  41.     this->yaw_rate = state[5];
  42.     this->cte = state[6];
  43.     this->epsi = state[7];
  44. }
复制代码
FG_eval:perator(),定义MPC的目标函数和束缚条件
  1. void FG_eval::operator()(ADvector &fg, ADvector &vars) {
  2.     // 部分代码已经给出,请同学们补全
  3.     fg[0] = 0;    // 0 is the index at which Ipopt expects fg to store the cost value,
  4.     /* TODO: Objective term 1: Keep close to reference values.*/
  5.     for (size_t t = 0; t < Np; t++) {
  6.         fg[0] += cte_weight * CppAD::pow(vars[cte_start + t] - ref_cte, 2);
  7.         fg[0] += epsi_weight * CppAD::pow(vars[epsi_start + t] - ref_epsi, 2);
  8.         // AD<double> speed = CppAD::sqrt(vars[v_longitudinal_start + t] * vars[v_longitudinal_start + t] + vars[v_lateral_start + t] * vars[v_lateral_start + t]);
  9.         // std::cout << "ref_v: " << ref_v << std::endl;
  10.         fg[0] += v_weight * CppAD::pow(vars[v_longitudinal_start + t] - ref_v, 2);
  11.     }
  12.     /* TODO: Objective term 2: Avoid to actuate as much as possible, minimize the use of actuators.*/
  13.     for (size_t t = 0; t < Nc; t++) {
  14.         fg[0] += steer_actuator_cost_weight_fg * CppAD::pow(vars[front_wheel_angle_start + t], 2);
  15.         fg[0] += acc_actuator_cost_weight_fg * CppAD::pow(vars[longitudinal_acceleration_start + t], 2);
  16.     }
  17.     /* TODO: Objective term 3: Enforce actuators smoothness in change, minimize the value gap between sequential actuation.*/
  18.     for (size_t t = 0; t < Nc - 1; t++) {
  19.         fg[0] += change_steer_cost_weight * CppAD::pow(vars[front_wheel_angle_start + t + 1] - vars[front_wheel_angle_start + t], 2);
  20.         fg[0] += change_accel_cost_weight * CppAD::pow(vars[longitudinal_acceleration_start + t + 1] - vars[longitudinal_acceleration_start + t], 2);
  21.     }
  22.     /* Initial constraints, initialize the model to the initial state*/
  23.     fg[1 + x_start] = vars[x_start];
  24.     fg[1 + y_start] = vars[y_start];
  25.     fg[1 + psi_start] = vars[psi_start];
  26.     fg[1 + v_longitudinal_start] = vars[v_longitudinal_start];
  27.     fg[1 + v_lateral_start] = vars[v_lateral_start];
  28.     fg[1 + yaw_rate_start] = vars[yaw_rate_start];
  29.     fg[1 + cte_start] = vars[cte_start];
  30.     fg[1 + epsi_start] = vars[epsi_start];
  31.     for (size_t t = 1; t < Np; t++)    // 预测模型
  32.     {
  33.         // Values at time (t),第一次进入该循环的时候,x_0...传入的是给MPC的系统状态的真实值,作为MPC求解的初始条件.
  34.         AD<double> x_0 = vars[x_start + t - 1];
  35.         AD<double> y_0 = vars[y_start + t - 1];
  36.         AD<double> psi_0 = vars[psi_start + t - 1];
  37.         AD<double> v_longitudinal_0 = vars[v_longitudinal_start + t - 1] + 0.00001;
  38.         AD<double> v_lateral_0 = vars[v_lateral_start + t - 1];
  39.         AD<double> yaw_rate_0 = vars[yaw_rate_start + t - 1];
  40.         AD<double> cte_0 = vars[cte_start + t - 1];
  41.         AD<double> epsi_0 = vars[epsi_start + t - 1];
  42.         // Values at time (t+1)
  43.         AD<double> x_1 = vars[x_start + t];
  44.         AD<double> y_1 = vars[y_start + t];
  45.         AD<double> psi_1 = vars[psi_start + t];
  46.         AD<double> v_longitudinal_1 = vars[v_longitudinal_start + t] + 0.00001;
  47.         AD<double> v_lateral_1 = vars[v_lateral_start + t];
  48.         AD<double> yaw_rate_1 = vars[yaw_rate_start + t];
  49.         AD<double> cte_1 = vars[cte_start + t];
  50.         AD<double> epsi_1 = vars[epsi_start + t];
  51.         // Only consider the actuation at time t.
  52.         AD<double> front_wheel_angle_0;
  53.         AD<double> longitudinal_acceleration_0;
  54.         front_wheel_angle_0 = vars[front_wheel_angle_start + t - 1];
  55.         longitudinal_acceleration_0 = vars[longitudinal_acceleration_start + t - 1];
  56.         // reference path
  57.         AD<double> f_0 = coeffs[0] + coeffs[1] * x_0 + coeffs[2] * CppAD::pow(x_0, 2) + coeffs[3] * CppAD::pow(x_0, 3) + coeffs[4] * CppAD::pow(x_0, 4) + coeffs[5] * CppAD::pow(x_0, 5);    // + coeffs[6] * CppAD::pow(x_0, 6);
  58.         // reference psi: can be calculated as the tangential angle of the polynomial f evaluated at x_0
  59.         AD<double> psi_des_0 = CppAD::atan(1 * coeffs[1] + 2 * coeffs[2] * x_0 + 3 * coeffs[3] * CppAD::pow(x_0, 2) + 4 * coeffs[4] * CppAD::pow(x_0, 3) + 5 * coeffs[5] * CppAD::pow(x_0, 4));    // + 6 * coeffs[6] * CppAD::pow(x_0, 5));
  60.         // TODO: 补全车辆动力学模型,作为MPC的等式约束条件,车辆动力学模型需要注意参数的正方向的定义
  61.         /*The idea here is to constraint this value to be 0.*/
  62.         /* 全局坐标系 */
  63.         fg[1 + x_start + t] = x_1 - (x_0 + (v_longitudinal_0 * CppAD::cos(psi_0) - v_lateral_0 * CppAD::sin(psi_0)) * dt);
  64.         fg[1 + y_start + t] = y_1 - (y_0 + (v_longitudinal_0 * CppAD::sin(psi_0) + v_lateral_0 * CppAD::cos(psi_0)) * dt);
  65.         /* 航向角变化 */
  66.         fg[1 + psi_start + t] = psi_1 - (psi_0 + yaw_rate_0 * dt);
  67.         /* 车辆纵向速度 */
  68.         fg[1 + v_longitudinal_start + t] = v_longitudinal_1 - (v_longitudinal_0 + longitudinal_acceleration_0 * dt);
  69.         /* 车辆侧向速度 */
  70.         // 注意这里front_wheel_angle_0符号和第四章推导中定义的delta方向相反
  71.         AD<double> a_lateral = -2 * (Cf + Cr) / (m * v_longitudinal_0) * v_lateral_0 + (2 * (lr * Cr - lf * Cf) / (m * v_longitudinal_0) - v_longitudinal_0) * yaw_rate_0 - 2 * Cf / m * front_wheel_angle_0;
  72.         fg[1 + v_lateral_start + t] = v_lateral_1 - (v_lateral_0 + a_lateral * dt);
  73.         /* 车辆横摆角速度 */
  74.         AD<double> yaw_acceleration = 2 * (lr * Cr - lf * Cf) / (I * v_longitudinal_0) * v_lateral_0 - 2 * (lf * lf * Cf + lr * lr * Cr) / (I * v_longitudinal_0) * psi_0 - 2 * lf * Cf / I * front_wheel_angle_0;
  75.         fg[1 + yaw_rate_start + t] = yaw_rate_1 - (yaw_rate_0 + yaw_acceleration * dt);
  76.         /* 横向位置跟踪误差 */
  77.         fg[1 + cte_start + t] = cte_1 - (f_0 - y_0 + v_longitudinal_0 * CppAD::tan(epsi_0) * dt);
  78.         /* 航向跟踪误差 */
  79.         fg[1 + epsi_start + t] = epsi_1 - (psi_0 - psi_des_0 - v_longitudinal_0 * (front_wheel_angle_0 / 1) / Lf * dt);
  80.     }
  81. }
复制代码
mpc_controller::Solve求解MPC优化问题,返回最优控制量以及猜测的状态轨迹。
  1. std::vector<double> mpc_controller::Solve(const Eigen::VectorXd &state, const Eigen::VectorXd &coeffs, const double &target_v, const int &cte_weight, const int &epsi_weight, const int &v_weight, const int &steer_actuator_cost_weight, const int &acc_actuator_cost_weight,
  2.                                           const int &change_steer_cost_weight, const int &change_accel_cost_weight,
  3.                                           //   const int &mpc_prediction_horizon_length,
  4.                                           const int &mpc_control_horizon_length, const double &mpc_control_step_length, const double &kinamatic_para_Lf, const double &a_lateral, const double &old_steer_value, const double &old_throttle_value, const double &steer_ratio) {
  5.     this->Nc = mpc_control_horizon_length;
  6.     this->Np = Nc + 1;
  7.     this->x_start = 0;
  8.     this->y_start = x_start + Np;
  9.     this->psi_start = y_start + Np;
  10.     this->v_longitudinal_start = psi_start + Np;
  11.     this->v_lateral_start = v_longitudinal_start + Np;
  12.     this->yaw_rate_start = v_lateral_start + Np;
  13.     this->cte_start = yaw_rate_start + Np;
  14.     this->epsi_start = cte_start + Np;
  15.     this->front_wheel_angle_start = epsi_start + Np;
  16.     this->longitudinal_acceleration_start = front_wheel_angle_start + Nc;    //控制时域长度为25的时候,控制量一共有24个。
  17.     // this->front_wheel_angle_increment_start = epsi_start + Np;
  18.     // this->longitudinal_acceleration_increment_start = front_wheel_angle_increment_start + Nc - 1;
  19.     this->a_lateral = a_lateral;
  20.     bool ok = true;
  21.     typedef CPPAD_TESTVECTOR(double) Dvector;
  22.     /* Explicitly gather state values for readability */
  23.     double x = state[0];
  24.     double y = state[1];
  25.     double psi = state[2];
  26.     double v_longitudinal = state[3];
  27.     double v_lateral = state[4];
  28.     double yaw_rate = state[5];
  29.     double cte = state[6];
  30.     double epsi = state[7];
  31.     /* Set the number of model variables (includes both states and inputs). */
  32.     /* 系统状态量 + 系统控制增量 */
  33.     size_t n_vars = Np * 8 + Nc * 2;
  34.     /* Set the number of contraints */
  35.     size_t n_constraints = Np * 8;
  36.     /* Initialize all of independent variables to zero. */
  37.     Dvector vars(n_vars);
  38.     for (size_t i = 0; i < n_vars; i++) {
  39.         vars[i] = 0.0;
  40.     }
  41.     // Set the initial variable values**初始化变量及变量上下限**
  42.     vars[x_start] = x;
  43.     vars[y_start] = y;
  44.     vars[psi_start] = psi;
  45.     vars[v_longitudinal_start] = v_longitudinal;
  46.     vars[v_lateral_start] = v_lateral;
  47.     vars[yaw_rate_start] = yaw_rate;
  48.     vars[cte_start] = cte;
  49.     vars[epsi_start] = epsi;
  50.     Dvector vars_lower_bounds(n_vars);
  51.     Dvector vars_upper_bounds(n_vars);
  52.     /* Set limits for non-actuators (avoid numerical issues during optimization). */
  53.     for (size_t i = 0; i < front_wheel_angle_start; i++) {
  54.         vars_lower_bounds[i] = -std::numeric_limits<float>::max();
  55.         vars_upper_bounds[i] = +std::numeric_limits<float>::max();
  56.     }
  57.     /* Set upper and lower constraints for steering. */
  58.     double max_degree = 24;
  59.     double max_radians = max_degree * M_PI / 180;
  60.     for (size_t i = front_wheel_angle_start; i < longitudinal_acceleration_start; i++) {
  61.         vars_lower_bounds[i] = -max_radians;
  62.         vars_upper_bounds[i] = +max_radians;
  63.     }
  64.     /* Set uppper and lower constraints for acceleration. */
  65.     double max_acceleration_value = 1.0;
  66.     for (size_t i = longitudinal_acceleration_start; i < n_vars; i++) {
  67.         vars_lower_bounds[i] = -max_acceleration_value;
  68.         vars_upper_bounds[i] = +max_acceleration_value;
  69.     }
  70.     /* Initialize to zero lower and upper limits for the constraints*/
  71.     Dvector constraints_lower_bounds(n_constraints);
  72.     Dvector constraints_upper_bounds(n_constraints);
  73.     for (size_t i = 0; i < n_constraints; i++) {
  74.         constraints_lower_bounds[i] = 0;
  75.         constraints_upper_bounds[i] = 0;
  76.     }
  77.     /* Force the solver to start from current state in optimization space. */
  78.     /* 约束条件的形式为 [x(0); x(1) = f(x(0)); ... x(N) = f(x(N-1)); , 每一个约束的第一项其实就是系统当前状态,所以直接约束该量的第一项。
  79.        不能直接给状态 vars 的第一项赋值来限制求解起点,因为状态和控制量理论上都是自由的,所以这里通过设置约束条件第一项的方式来指定优化求解起点,从而加速求解。*/
  80.     constraints_lower_bounds[x_start] = x;
  81.     constraints_lower_bounds[y_start] = y;
  82.     constraints_lower_bounds[psi_start] = psi;
  83.     constraints_lower_bounds[v_longitudinal_start] = v_longitudinal;
  84.     constraints_lower_bounds[v_lateral_start] = v_lateral;
  85.     constraints_lower_bounds[yaw_rate_start] = yaw_rate;
  86.     constraints_lower_bounds[cte_start] = cte;
  87.     constraints_lower_bounds[epsi_start] = epsi;
  88.     constraints_upper_bounds[x_start] = x;
  89.     constraints_upper_bounds[y_start] = y;
  90.     constraints_upper_bounds[psi_start] = psi;
  91.     constraints_upper_bounds[v_longitudinal_start] = v_longitudinal;
  92.     constraints_upper_bounds[v_lateral_start] = v_lateral;
  93.     constraints_upper_bounds[yaw_rate_start] = yaw_rate;
  94.     constraints_upper_bounds[cte_start] = cte;
  95.     constraints_upper_bounds[epsi_start] = epsi;
  96.     /* Object that computes objective and constraints. */
  97.     FG_eval fg_eval(state, coeffs, target_v, cte_weight, epsi_weight, v_weight, steer_actuator_cost_weight, acc_actuator_cost_weight, change_steer_cost_weight, change_accel_cost_weight, Np, Nc, mpc_control_step_length, kinamatic_para_Lf, a_lateral, old_steer_value, old_throttle_value, steer_ratio);
  98.     /* NOTE: You don't have to worry about these options. options for IPOPT solver. */
  99.     std::string options;
  100.     /* Uncomment this if you'd like more print information. */
  101.     options += "Integer print_level  0\n";
  102.     /* NOTE: Setting sparse to true allows the solver to take advantage
  103.        of sparse routines, this makes the computation MUCH FASTER. If you can
  104.        uncomment 1 of these and see if it makes a difference or not but if you
  105.        uncomment both the computation time should go up in orders of magnitude. */
  106.     options += "Sparse  true        forward\n";
  107.     options += "Sparse  true        reverse\n";
  108.     /* NOTE: Currently the solver has a maximum time limit of 0.5 seconds. */
  109.     /* Change this as you see fit. */
  110.     options += "Numeric max_cpu_time          0.5\n";    // 单位:s
  111.     /* Place to return solution. */
  112.     CppAD::ipopt::solve_result<Dvector> solution;
  113.     /* Solve the problem. */
  114.     // cout << "Solve the problem......" << endl;
  115.     CppAD::ipopt::solve<Dvector, FG_eval>(options, vars, vars_lower_bounds, vars_upper_bounds, constraints_lower_bounds, constraints_upper_bounds, fg_eval, solution);
  116.     /* Check some of the solution values. */
  117.     ok &= solution.status == CppAD::ipopt::solve_result<Dvector>::success;
  118.     /* Cost! */
  119.     // auto cost = solution.obj_value;
  120.     // std::cout << "Cost: " << cost << std::endl;
  121.     /* Return the first actuator values. The variables can be accessed with 'solution.x[i]'. */
  122.     std::vector<double> result;
  123.     result.clear();
  124.     // cout << solution.x << endl;
  125.     // cout << front_wheel_angle_start << endl;
  126.     result.push_back(solution.x[front_wheel_angle_start]);
  127.     result.push_back(solution.x[longitudinal_acceleration_start]);
  128.     /* Add 'future' solutions (where MPC is going). */
  129.     for (size_t i = 0; i < Np - 1; i++) {
  130.         result.push_back(solution.x[x_start + i]);
  131.         result.push_back(solution.x[y_start + i]);
  132.     }
  133.     // std::cout << "end now" << std::endl;
  134.     return result;
  135. }
复制代码
代价的权重:
  1. # MPC 目标函数里面可以调节的权重
  2.     mpc_cte_weight_int:  600 # ok
  3.     mpc_epsi_weight_int: 1000 # ok
  4.     mpc_v_weight_int: 200 # ok real 100
  5.     # 控制量幅值代价权重
  6.     mpc_steer_actuator_cost_weight_int: 400 # ok
  7.     mpc_acc_actuator_cost_weight_int: 100 # ok
  8.     # 前后两次控制量变化的代价权重
  9.     mpc_change_steer_cost_weight_int: 200 # ok
  10.     mpc_change_accel_cost_weight_int: 200 # ok
复制代码
四、效果展示

实验过程中发如今相同的权重下,给定不同的求解时间,会对MPC的性能产生较大的影响:
  1. options += "Numeric max_cpu_time          0.5\n";    // 单位:s
复制代码
求解时间为0.5s的效果,计时发现求解一次的时间在50ms左右,但是偶然会到200-300ms,跟踪效果良好,无振荡。

求解时间为0.2s的效果,求解时间在50ms左右,最大求解时间被限制在200ms左右。

跟踪直线轨迹时出现了轻微振荡。

求解时间为0.05s的效果,最大求解时间被限制在50ms-70ms之间。

跟踪直线轨迹时出现显着振荡:

实际工程实现中,需要权衡求解精度与实时性,应当通过实验和工程束缚确定最大求解时间等参数。

     主动驾驶控制与规划——Project 4: MPC车辆控制
  

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

美食家大橙子

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表