百度apollo自动驾驶planning代码学习-Apollo\modules\planning\constraint_checker\ConstraintChecker类代码详解

70 篇文章 246 订阅
42 篇文章 7 订阅

概述

ConstraintChecker类是apollo planning模块下modules\planning\constraint_checker\constraint_checker.cc/.h实现

从类名来看,应该是约束检查器类?

从代码来看ConstraintChecker类主要是实现:
检查一条离散轨迹对象是否有效?检查轨迹是否有效/纵向横向的速度加速度加加速度超出边界/曲率超出边界,推测该类主要是用于筛选规划轨迹,缩小优化搜索的空间。

constraint_checker.h

#pragma once

#include "modules/planning/common/trajectory/discretized_trajectory.h"

namespace apollo {
namespace planning {

class ConstraintChecker {
 public:
 //一个枚举类型
//Result类其包含值VALID/LON_VELOCITY_OUT_OF_BOUND/LON_ACCELERATION_OUT_OF_BOUND/LON_JERK_OUT_OF_BOUND/...等等,主要就是检查轨迹是否有效/纵向横向的速度加速度加加速度超出边界/曲率超出边界
  enum class Result {
    VALID,
    LON_VELOCITY_OUT_OF_BOUND,
    LON_ACCELERATION_OUT_OF_BOUND,
    LON_JERK_OUT_OF_BOUND,
    LAT_VELOCITY_OUT_OF_BOUND,
    LAT_ACCELERATION_OUT_OF_BOUND,
    LAT_JERK_OUT_OF_BOUND,
    CURVATURE_OUT_OF_BOUND,
  };
  //禁用默认构造函数
  ConstraintChecker() = delete;
  
  //检查轨迹是否有效?
//返回值是ConstraintChecker::Result,是constraint_checker.h里声明的一个枚举类型
//Result类其包含值VALID/LON_VELOCITY_OUT_OF_BOUND/LON_ACCELERATION_OUT_OF_BOUND/LON_JERK_OUT_OF_BOUND/...等等,主要就是检查轨迹是否有效/纵向横向的速度加速度加加速度超出边界/曲率超出边界
//输入的是一条离散轨迹类对象
//推测该函数主要是用于筛选规划轨迹,缩小优化搜索的空间
//返回的就是输入轨迹是否有效及无效的原因?
  static Result ValidTrajectory(const DiscretizedTrajectory& trajectory);
};

}  // namespace planning
}  // namespace apollo

constraint_checker.cc

#include "modules/planning/constraint_checker/constraint_checker.h"

#include "cyber/common/log.h"
#include "modules/planning/common/planning_gflags.h"

namespace apollo {
namespace planning {

namespace {
//定义了个模板函数,判断输入参数v的大小是否在同类型的lower,upper范围之间
template <typename T>
bool WithinRange(const T v, const T lower, const T upper) {
  return lower <= v && v <= upper;
}
}  // namespace

//检查轨迹是否有效?
//返回值是ConstraintChecker::Result,是constraint_checker.h里声明的一个枚举类型
//Result类其包含值VALID/LON_VELOCITY_OUT_OF_BOUND/LON_ACCELERATION_OUT_OF_BOUND/LON_JERK_OUT_OF_BOUND/...等等,主要就是检查轨迹是否有效/纵向横向的速度加速度加加速度超出边界/曲率超出边界
//输入的是一条离散轨迹类对象
//推测该函数主要是用于筛选规划轨迹,缩小优化搜索的空间
ConstraintChecker::Result ConstraintChecker::ValidTrajectory(
    const DiscretizedTrajectory& trajectory) {
  //定义一个常数最大检查的的相对时间为 planning_gflags.cc里定义的trajectory_time_length也就是轨迹时间长度8.0s
  const double kMaxCheckRelativeTime = FLAGS_trajectory_time_length;
  //遍历输入的离散轨迹
  for (const auto& p : trajectory) {
    //获取遍历的第i个轨迹点的相对时间 t
    double t = p.relative_time();
    //如果t已经大于8s则直接跳出for循环
    if (t > kMaxCheckRelativeTime) {
      break;
    }
    //获取遍历的第i个轨迹点的速度
    double lon_v = p.v();
    //判断遍历的第i个轨迹点的速度是否在planning_gflags里定义的速度上下限范围内
    //速度下限-0.1,上限40.0
    //轨迹点速度不在该范围内,报debug信息,返回LON_VELOCITY_OUT_OF_BOUND纵向速度超出边界
    if (!WithinRange(lon_v, FLAGS_speed_lower_bound, FLAGS_speed_upper_bound)) {
      ADEBUG << "Velocity at relative time " << t
             << " exceeds bound, value: " << lon_v << ", bound ["
             << FLAGS_speed_lower_bound << ", " << FLAGS_speed_upper_bound
             << "].";
      return Result::LON_VELOCITY_OUT_OF_BOUND;
    }

//遍历的第i个轨迹点的检查加速度是否超限,同理
//planning_gflags里定义的加速度上下限范围[-6.0,4.0]
    double lon_a = p.a();
    if (!WithinRange(lon_a, FLAGS_longitudinal_acceleration_lower_bound,
                     FLAGS_longitudinal_acceleration_upper_bound)) {
      ADEBUG << "Longitudinal acceleration at relative time " << t
             << " exceeds bound, value: " << lon_a << ", bound ["
             << FLAGS_longitudinal_acceleration_lower_bound << ", "
             << FLAGS_longitudinal_acceleration_upper_bound << "].";
      return Result::LON_ACCELERATION_OUT_OF_BOUND;
    }

//遍历的第i个轨迹点的检查曲率是否超限,同理
//planning_gflags里定义的曲率上下限范围[-0.1979,0.1979]
    double kappa = p.path_point().kappa();
    if (!WithinRange(kappa, -FLAGS_kappa_bound, FLAGS_kappa_bound)) {
      ADEBUG << "Kappa at relative time " << t
             << " exceeds bound, value: " << kappa << ", bound ["
             << -FLAGS_kappa_bound << ", " << FLAGS_kappa_bound << "].";
      return Result::CURVATURE_OUT_OF_BOUND;
    }
  }

//又开始遍历输入的轨迹的轨迹点?从第2个点开始,因为要用到前一个点
  for (size_t i = 1; i < trajectory.NumOfPoints(); ++i) {
    //获取第i-1个轨迹点p0
    const auto& p0 = trajectory.TrajectoryPointAt(static_cast<uint32_t>(i - 1));
    //获取第i个轨迹点p1
    const auto& p1 = trajectory.TrajectoryPointAt(static_cast<uint32_t>(i));

//如果第i个轨迹点p1的相对时间大于最大检查时间8s直接break跳出循环
    if (p1.relative_time() > kMaxCheckRelativeTime) {
      break;
    }

//获取第i-1个轨迹点p0的相对时间
    double t = p0.relative_time();

//求出p0p1轨迹点的时间间隔
    double dt = p1.relative_time() - p0.relative_time();
    //计算p0p1轨迹点的加速度的差值
    double d_lon_a = p1.a() - p0.a();
    //差分法计算第i个轨迹i点加加速度,是因为规划轨迹点上没有jerk,所以只能再高一个for循环做差分判断
    double lon_jerk = d_lon_a / dt;
    //判断第i个轨迹点处的加加速度是否超限[-4.0,2.0],planning_gflags里定义的
    if (!WithinRange(lon_jerk, FLAGS_longitudinal_jerk_lower_bound,
                     FLAGS_longitudinal_jerk_upper_bound)) {
      ADEBUG << "Longitudinal jerk at relative time " << t
             << " exceeds bound, value: " << lon_jerk << ", bound ["
             << FLAGS_longitudinal_jerk_lower_bound << ", "
             << FLAGS_longitudinal_jerk_upper_bound << "].";
      return Result::LON_JERK_OUT_OF_BOUND;
    }

//检查横向加速度是否超限,planning_gflags里定义的范围[-4.0,4.0]
//横向加速度轨迹点上也没有,用公式v^2/R=V^2*kappa
    double lat_a = p1.v() * p1.v() * p1.path_point().kappa();
    if (!WithinRange(lat_a, -FLAGS_lateral_acceleration_bound,
                     FLAGS_lateral_acceleration_bound)) {
      ADEBUG << "Lateral acceleration at relative time " << t
             << " exceeds bound, value: " << lat_a << ", bound ["
             << -FLAGS_lateral_acceleration_bound << ", "
             << FLAGS_lateral_acceleration_bound << "].";
      return Result::LAT_ACCELERATION_OUT_OF_BOUND;
    }

//横向的jerk检查注释掉了?其实横向jerk也蛮影响舒适性的
    // TODO(zhangyajia): this is temporarily disabled
    // due to low quality reference line.
    /**
    double d_lat_a = p1.v() * p1.v() * p1.path_point().kappa() -
                     p0.v() * p0.v() * p0.path_point().kappa();
    double lat_jerk = d_lat_a / dt;
    if (!WithinRange(lat_jerk, -FLAGS_lateral_jerk_bound,
                     FLAGS_lateral_jerk_bound)) {
      ADEBUG << "Lateral jerk at relative time " << t
             << " exceeds bound, value: " << lat_jerk << ", bound ["
             << -FLAGS_lateral_jerk_bound << ", " << FLAGS_lateral_jerk_bound
             << "].";
      return Result::LAT_JERK_OUT_OF_BOUND;
    }
    **/
  }

//上面都没返回,说明轨迹是有效的
  return Result::VALID;
}

}  // namespace planning
}  // namespace apollo

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wujiangzhu_xjtu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值