百度apollo planning代码学习-Apollo\modules\planning\math\curve1d\QuarticPolynomialCurve1d类代码详解

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

概述

QuarticPolynomialCurve1d类是apollo planning模块下modules\planning\math\curve1d\quartic_polynomial_curve1d.cc /.h实现

从类名来看,应该是QuarticPolynomialCurve1d是四次多项式1维参数曲线类?

从代码来看QuarticPolynomialCurve1d类主要是实现:
1.根据起点处(参数param=0)的值,x0,dx0,ddx0,以及终点处(参数param=paramlength)的值,x1,dx1,ddx1,这里总共6个条件,只要其中5个就可以确定一条四次多项式;
2.根据五次多项式求导得到一条四次多项式;
3.根据3次多项式积分得到四次多项式;
4.储存四次多项式个各项系数;
5.对储存的四次多项式的插值,插值出指定参数处指定阶导数(0,1,2,3,4)的值

quartic_polynomial_curve1d.h

#pragma once

#include <array>
#include <string>

#include "modules/planning/math/curve1d/polynomial_curve1d.h"

namespace apollo {
namespace planning {

// 1D quartic polynomial curve: (x0, dx0, ddx0) -- [0, param] --> (dx1, ddx1)
//公有继承多项式1维参数曲线类
class QuarticPolynomialCurve1d : public PolynomialCurve1d {
 public:
 //默认构造函数
  QuarticPolynomialCurve1d() = default;

//四次多项式1维参数曲线类构造函数
//输入参数 初始状态3维(s,s',s''或d,d',d''), 终端状态2维(调用时只输入了d',d'')?这样的话就5个方程了就可以确定一条四次多项式,只适用于终点位置不固定类似巡航这种场景
  QuarticPolynomialCurve1d(const std::array<double, 3>& start,
                           const std::array<double, 2>& end,
                           const double param);

//这个构造函数就是被上面的构造函数调用,就是根据
//param=0 x0,dx0,ddx0
//param=paramlength dx1 ddx1 5个方程求出四次多项式的五个系数,调用函数ComputeCoefficients来求解多项式的系数
  QuarticPolynomialCurve1d(const double x0, const double dx0, const double ddx0,
                           const double dx1, const double ddx1,
                           const double param);

//这个构造函数?输入一个四次多项式,然后把其系数和参数的总长度拷贝给类成员?
  QuarticPolynomialCurve1d(const QuarticPolynomialCurve1d& other);

//默认析构函数
  virtual ~QuarticPolynomialCurve1d() = default;

//多项式插值,具体原理很简单就不详述了,就是多项式求导,可以插值出指定参数处四次多项式指定阶导数对应的值。
  double Evaluate(const std::uint32_t order, const double p) const override;

  /**
   * Interface with refine quartic polynomial by meets end first order
   * and start second order boundary condition:
   * @param  x0    init point x location
   * @param  dx0   init point derivative
   * @param  ddx0  init point second order derivative
   * @param  x1    end point x location
   * @param  dx1   end point derivative
   * @param  param parameter length
   * @return       self
   */
   //用终端的一阶条件求解四次多项式
//param=0时,x=x0,dx=dx0,ddx=ddx0
//param=paramlength(这里就是p)时, x=x1 dx=dx1
//5个条件求解四次多项式各个系数存入类成员array数组coef_中
  QuarticPolynomialCurve1d& FitWithEndPointFirstOrder(
      const double x0, const double dx0, const double ddx0, const double x1,
      const double dx1, const double param);

  /**
   * Interface with refine quartic polynomial by meets end point second order
   * and start point first order boundary condition
   */
   //用终端的二阶条件求解四次多项式
//param=0时,x=x0,dx=dx0
//param=paramlength(这里就是p)时, x=x1 dx=dx1,ddx=ddx1
//5个条件求解四次多项式各个系数存入类成员array数组coef_中
  QuarticPolynomialCurve1d& FitWithEndPointSecondOrder(
      const double x0, const double dx0, const double x1, const double dx1,
      const double ddx1, const double param);

  /*
   * Integrated from cubic curve with init value
   */
   //根据输入的3次多项式积分得到四次多项式
//输入参数3次多项式,还有四次多项式param=0时的x初值,最后的积分得到的四次多项式放入类成员coef_里
  QuarticPolynomialCurve1d& IntegratedFromCubicCurve(
      const PolynomialCurve1d& other, const double init_value);

  /*
   * Derived from quintic curve
   */
   //从五次多项式求导得到四次多项似乎,输入的就是一个五次多项式,最后求导的四次多项式放入类成员coef_里
  QuarticPolynomialCurve1d& DerivedFromQuinticCurve(
      const PolynomialCurve1d& other);

//返回类成员 参数总长度(时间t,或纵向长度s)
  double ParamLength() const override { return param_; }

//返回调试字符串,其实就是多项式的系数及其参数总长度
  std::string ToString() const override;

//获取四次多项式指定幂次项的系数
  double Coef(const size_t order) const override;

//四次多项式的最高幂次当然是4了
  size_t Order() const override { return 4; }

 private:
 //param=0时,x=x0,dx=dx0,ddx=ddx0
//param=paramlength(这里就是p)时, dx=dx1,ddx=ddx1
//5个条件求解四次多项式各个系数存入类成员array数组coef_中
  void ComputeCoefficients(const double x0, const double dx0, const double ddx0,
                           const double dx1, const double ddx1,
                           const double param);

  std::array<double, 5> coef_ = {{0.0, 0.0, 0.0, 0.0, 0.0}};
  std::array<double, 3> start_condition_ = {{0.0, 0.0, 0.0}};
  std::array<double, 2> end_condition_ = {{0.0, 0.0}};
};

}  // namespace planning
}  // namespace apollo

quartic_polynomial_curve1d.cc

#include "modules/planning/math/curve1d/quartic_polynomial_curve1d.h"

#include "absl/strings/str_cat.h"
#include "absl/strings/str_join.h"

#include "cyber/common/log.h"

namespace apollo {
namespace planning {
//四次多项式1维参数曲线类构造函数
//输入参数 初始状态3维(s,s',s''或d,d',d''), 终端状态2维(调用时只输入了d',d'')?这样的话就5个方程了就可以确定一条四次多项式,只适用于终点位置不固定类似巡航这种场景
QuarticPolynomialCurve1d::QuarticPolynomialCurve1d(
    const std::array<double, 3>& start, const std::array<double, 2>& end,
    const double param)
    : QuarticPolynomialCurve1d(start[0], start[1], start[2], end[0], end[1],
                               param) {}

//这个构造函数就是被上面的构造函数调用,就是根据
//param=0 x0,dx0,ddx0
//param=paramlength dx1 ddx1 5个方程求出四次多项式的五个系数,调用函数ComputeCoefficients来求解多项式的系数
QuarticPolynomialCurve1d::QuarticPolynomialCurve1d(
    const double x0, const double dx0, const double ddx0, const double dx1,
    const double ddx1, const double param) {
  param_ = param;
  start_condition_[0] = x0;
  start_condition_[1] = dx0;
  start_condition_[2] = ddx0;
  end_condition_[0] = dx1;
  end_condition_[1] = ddx1;
  ComputeCoefficients(x0, dx0, ddx0, dx1, ddx1, param);
}

//这个构造函数?输入一个四次多项式,然后把其系数和参数的总长度拷贝给类成员?
QuarticPolynomialCurve1d::QuarticPolynomialCurve1d(
    const QuarticPolynomialCurve1d& other) {
  param_ = other.param_;
  coef_ = other.coef_;
}

//多项式插值,具体原理很简单就不详述了,就是多项式求导,可以插值出指定参数处四次多项式指定阶导数对应的值。
double QuarticPolynomialCurve1d::Evaluate(const std::uint32_t order,
                                          const double p) const {
  switch (order) {
    case 0: {
      return (((coef_[4] * p + coef_[3]) * p + coef_[2]) * p + coef_[1]) * p +
             coef_[0];
    }
    case 1: {
      return ((4.0 * coef_[4] * p + 3.0 * coef_[3]) * p + 2.0 * coef_[2]) * p +
             coef_[1];
    }
    case 2: {
      return (12.0 * coef_[4] * p + 6.0 * coef_[3]) * p + 2.0 * coef_[2];
    }
    case 3: {
      return 24.0 * coef_[4] * p + 6.0 * coef_[3];
    }
    case 4: {
      return 24.0 * coef_[4];
    }
    default:
      return 0.0;
  }
}

//用终端的一阶条件求解四次多项式
//param=0时,x=x0,dx=dx0,ddx=ddx0
//param=paramlength(这里就是p)时, x=x1 dx=dx1
//5个条件求解四次多项式各个系数存入类成员array数组coef_中
QuarticPolynomialCurve1d& QuarticPolynomialCurve1d::FitWithEndPointFirstOrder(
    const double x0, const double dx0, const double ddx0, const double x1,
    const double dx1, const double p) {
  CHECK_GT(p, 0.0);

  param_ = p;

  coef_[0] = x0;

  coef_[1] = dx0;

  coef_[2] = 0.5 * ddx0;

  double p2 = p * p;
  double p3 = p2 * p;
  double p4 = p3 * p;

  double b0 = x1 - coef_[0] - coef_[1] * p - coef_[2] * p2;
  double b1 = dx1 - dx0 - ddx0 * p;

  coef_[4] = (b1 * p - 3 * b0) / p4;
  coef_[3] = (4 * b0 - b1 * p) / p3;
  return *this;
}

//用终端的二阶条件求解四次多项式
//param=0时,x=x0,dx=dx0
//param=paramlength(这里就是p)时, x=x1 dx=dx1,ddx=ddx1
//5个条件求解四次多项式各个系数存入类成员array数组coef_中
QuarticPolynomialCurve1d& QuarticPolynomialCurve1d::FitWithEndPointSecondOrder(
    const double x0, const double dx0, const double x1, const double dx1,
    const double ddx1, const double p) {
  CHECK_GT(p, 0.0);

  param_ = p;

  coef_[0] = x0;

  coef_[1] = dx0;

  double p2 = p * p;
  double p3 = p2 * p;
  double p4 = p3 * p;

  double b0 = x1 - coef_[0] - coef_[1] * p;
  double b1 = dx1 - coef_[1];
  double c1 = b1 * p;
  double c2 = ddx1 * p2;

  coef_[2] = (0.5 * c2 - 3 * c1 + 6 * b0) / p2;
  coef_[3] = (-c2 + 5 * c1 - 8 * b0) / p3;
  coef_[4] = (0.5 * c2 - 2 * c1 + 3 * b0) / p4;

  return *this;
}

//根据输入的3次多项式积分得到四次多项式
//输入参数3次多项式,还有四次多项式param=0时的x初值,最后的积分得到的四次多项式放入类成员coef_里
QuarticPolynomialCurve1d& QuarticPolynomialCurve1d::IntegratedFromCubicCurve(
    const PolynomialCurve1d& other, const double init_value) {
  CHECK_EQ(other.Order(), 3U);
  param_ = other.ParamLength();
  coef_[0] = init_value;
  for (size_t i = 0; i < 4; ++i) {
    coef_[i + 1] = other.Coef(i) / (static_cast<double>(i) + 1);
  }
  return *this;
}

//从五次多项式求导得到四次多项似乎,输入的就是一个五次多项式,最后求导的四次多项式放入类成员coef_里
QuarticPolynomialCurve1d& QuarticPolynomialCurve1d::DerivedFromQuinticCurve(
    const PolynomialCurve1d& other) {
  CHECK_EQ(other.Order(), 5U);
  param_ = other.ParamLength();
  for (size_t i = 1; i < 6; ++i) {
    coef_[i - 1] = other.Coef(i) * static_cast<double>(i);
  }
  return *this;
}

//param=0时,x=x0,dx=dx0,ddx=ddx0
//param=paramlength(这里就是p)时, dx=dx1,ddx=ddx1
//5个条件求解四次多项式各个系数存入类成员array数组coef_中
void QuarticPolynomialCurve1d::ComputeCoefficients(
    const double x0, const double dx0, const double ddx0, const double dx1,
    const double ddx1, const double p) {
  CHECK_GT(p, 0.0);

  coef_[0] = x0;
  coef_[1] = dx0;
  coef_[2] = 0.5 * ddx0;

  double b0 = dx1 - ddx0 * p - dx0;
  double b1 = ddx1 - ddx0;

  double p2 = p * p;
  double p3 = p2 * p;

  coef_[3] = (3 * b0 - b1 * p) / (3 * p2);
  coef_[4] = (-2 * b0 + b1 * p) / (4 * p3);
}

//利用absl库将四次多项式的系数以及参数总长度转化成字符串并连接起来变成一个大的string并返回,便于调试
std::string QuarticPolynomialCurve1d::ToString() const {
  return absl::StrCat(absl::StrJoin(coef_, "\t"), param_, "\n");
}

//获取四次多项式指定幂次项的系数(例如4次项系数,3次项系数...)
double QuarticPolynomialCurve1d::Coef(const size_t order) const {
  CHECK_GT(5U, order);
  return coef_[order];
}

}  // namespace planning
}  // namespace apollo

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Apollo Planning是一个自动驾驶规划模块,它负责生成自动驾驶车辆的行驶路线和行驶轨迹。该模块的代码主要包括以下几个部分: 1. 地图数据处理:该部分代码主要负责处理地图数据,包括地图的加载、解析和存储等。 2. 车辆状态估计:该部分代码主要负责估计车辆的状态,包括车辆的位置、速度、加速度等。 3. 障碍物检测:该部分代码主要负责检测车辆周围的障碍物,包括车辆前方的障碍物、车辆后方的障碍物等。 4. 路径规划:该部分代码主要负责生成车辆的行驶路线,包括起点、终点、途经点等。 5. 轨迹规划:该部分代码主要负责生成车辆的行驶轨迹,包括车辆的速度、加速度、转向角度等。 总的来说,Apollo Planning代码解读需要对自动驾驶技术有一定的了解,需要熟悉相关的算法和数据结构。同时,还需要对C++编程语言有一定的掌握,能够理解和修改代码。 ### 回答2: Apollo PlanningApollo平台中的一部分,是一种规划算法,用于生成具有速度、加速度、路径跟踪、动态碰撞检测等约束条件的行驶路径。本文将对Apollo Planning中的代码进行解读。 Apollo Planning的核心代码包括两个部分:路径规划器和速度规划器。其中路径规划器的主要任务是在路网中寻找一条从起点到终点的路径,而速度规划器的主要任务则是为规划出的路径生成相应的速度规划和轨迹。 路径规划器中采用的主要算法是基于A*算法的全局规划器和基于Dijkstra算法的局部规划器。全局规划器用于从起点到终点寻找全局路径,而局部规划器则用于在全局路径的基础上进行优化,以生成最终的路径。 在速度规划器中,采用了二次规划、线性插值和基于速度和加速度约束的时间分配等算法,用于根据路网上提供的速度信息和预计的路况等因素生成规划速度和轨迹。 除此之外,还应用了动态碰撞检测算法,用于在行驶过程中实时检测障碍物,并调整行驶路径以避免碰撞。 总之,Apollo Planning代码实现了较为完善的路径规划和速度规划功能,并且综合应用了多种算法和约束条件,使得车辆行驶更加安全、稳定。 ### 回答3: Apollo Planning 代码百度自动驾驶平台 Apollo 中用于路径规划的组件。通过对代码的解读,我们可以了解到路径规划背后的一系列算法和原理。 首先,Apollo Planning 首先需要载入地图信息,以确定行驶的区域和道路网络。这些地图信息包括道路形状、道路宽度、车道数量、速度限制和限制规则等。 然后,Apollo Planning 根据车辆当前位置和目的地位置,通过 A*算法或 Dijkstra 算法等规划出车辆行驶的路径。这一过程中,Apollo Planning 需要考虑各种限制条件,如道路的长度、转弯半径、速度限制、停止标志和交通信号灯等。 接下来,Apollo Planning 将规划出的路径转换为轨迹,以让车辆根据轨迹规划进行动作。这一过程需要考虑车辆的动力学特性,比如加速度、最大速度限制和最大转弯速度等。 在最终生成的行驶轨迹中,需要包含一些基础信息,如轨迹的时间戳、各个点的速度和加速度信息等。这些信息有助于车辆在运行过程中准确地遵守路径规划,并在行驶中做出适时的调整。 总之,Apollo Planning 的核心功能是确定车辆行驶的路线、行驶轨迹和行驶速度等。该组件通过高效的算法和细致的条件考虑,实现自动驾驶车辆的稳定、安全和高效的路径规划。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

wujiangzhu_xjtu

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

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

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

打赏作者

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

抵扣说明:

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

余额充值