apollo planning学习-Apollo\modules\planning\common\trajectory1d\PiecewiseAccelerationTrajectory1d类代码详解

概述

对piecewise_acceleration_trajectory1d.cc和.h进行解析,来了解PiecewiseAccelerationTrajectory1d类的使用。

从名字字面意义来看是 分段加速度1维轨迹类。

从代码来看该类实现的功能非常简单:
PiecewiseAccelerationTrajectory1d多段匀加速轨迹类对象,储存多段加速度不同的匀加速段终点的s,v,a,j,并增删改匀加速段,以及对于多段匀加速段构成的轨迹根据时间t插值出相应的s,v,a,j

piecewise_acceleration_trajectory1d.h

#pragma once

#include <array>
#include <string>
#include <vector>

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

namespace apollo {
namespace planning {

class PiecewiseAccelerationTrajectory1d : public Curve1d {
 public:
  //PiecewiseAccelerationTrajectory1d带参构造函数
  //参数:起始点纵向相对位置start_s,初速度start_v
  PiecewiseAccelerationTrajectory1d(const double start_s, const double start_v);

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

  //AppendSegment顾名思义就是增加一段匀加速段
  //参数加速度a,持续时间t_duration
  void AppendSegment(const double a, const double t_duration);
  //删除最后一个点,也就是在vector s_,v_,a_,t_里删去最后一段匀加速段的s,v,a,t
  void PopSegment();
  //返回分段匀加速轨迹类对象所覆盖的时间总长度
  double ParamLength() const override;
  //把数据成员v_,a_,s_,t_转化成字符串并连接起来返回
  std::string ToString() const override;
  //Evaluate插值函数
  //参数order阶数,param是时间,根据时间插值s,v,a,jerk
  //s_,v_,a_,t_储存了多段加速度不同的匀加速度段
  double Evaluate(const std::uint32_t order, const double param) const override;
  //多段匀加速段轨迹根据时间t插值对应的是s,v,a,j
  //返回值是一个4维的double数组
  std::array<double, 4> Evaluate(const double t) const;

 private:
  //下面主要是对数据成员根据时间进行插值
  double Evaluate_s(const double t) const;

  double Evaluate_v(const double t) const;

  double Evaluate_a(const double t) const;

  double Evaluate_j(const double t) const;

 private:
  //下面都是类的数据成员,其实就是vector的s,v,a,t
  // accumulated s
  std::vector<double> s_;

  std::vector<double> v_;

  // accumulated t
  std::vector<double> t_;

  std::vector<double> a_;
};

}  // namespace planning
}  // namespace apollo

piecewise_acceleration_trajectory1d.cc

#include "modules/planning/common/trajectory1d/piecewise_acceleration_trajectory1d.h"

#include <algorithm>

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

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

namespace apollo {
namespace planning {

//PiecewiseAccelerationTrajectory1d带参构造函数
//参数:起始点纵向相对位置start_s,初速度start_v
PiecewiseAccelerationTrajectory1d::PiecewiseAccelerationTrajectory1d(
    const double start_s, const double start_v) {
  //用参数来初始化类数据成员s,v,a,t 
  //其中a,t初始化塞入0.0
  s_.push_back(start_s);
  v_.push_back(start_v);
  a_.push_back(0.0);
  t_.push_back(0.0);
}

//AppendSegment顾名思义就是增加一段匀加速段
//参数加速度a,持续时间t_duration
void PiecewiseAccelerationTrajectory1d::AppendSegment(const double a,
                                                      const double t_duration) {
  //定义初始的纵向相对位置s0为类数据成员s_里的最后一个(上一段的终点位置)
  double s0 = s_.back();
  //定义初速度v0为类数据成员v_里的最后一个(上一段的终点速度)
  double v0 = v_.back();
  //定义初始点的时间t0为类数据成员t_里的最后一个(上一段的终点时间)
  double t0 = t_.back();

  //新增的这段匀加速运动的终点速度v1
  double v1 = v0 + a * t_duration;
  //检查v1 >= 1e-6?  否则报错
  //FLAGS_numerical_epsilon是gflags的用法FLAGS_去
  //modules\planning\common\planning_gflags.cc取出numerical_epsilon的值1e-6
  ACHECK(v1 >= -FLAGS_numerical_epsilon);

  //定义新增的匀加速段走过的纵向距离delta_s 计算公式高中物理公式
  double delta_s = (v0 + v1) * t_duration * 0.5;
  //定义新增的匀加速段终点的纵向相对位置s1
  double s1 = s0 + delta_s;
  //定义新增的匀加速段的终点时间t1
  double t1 = t0 + t_duration;

  //检查新增的匀加速段终点的纵向相对位置s1是否大于初始的纵向相对位置s0,否则报错
  ACHECK(s1 >= s0 - FLAGS_numerical_epsilon);
  //s1取s1,s0里较大的那一个,这个是为了防止一些错误的清空发生
  s1 = std::max(s1, s0);
  //将新增的匀加速段的终点s,v,a,t塞入类数据成员
  //s_,v_,a_,t_都是vector
  s_.push_back(s1); 
  v_.push_back(v1);
  a_.push_back(a);
  t_.push_back(t1);
}

//删除最后一个点,也就是在vector s_,v_,a_,t_里删去最后一段匀加速段的s,v,a,t
void PiecewiseAccelerationTrajectory1d::PopSegment() {
  if (a_.size() > 0) {
    s_.pop_back();
    v_.pop_back();
    a_.pop_back();
    t_.pop_back();
  }
}

//返回分段匀加速轨迹类对象所覆盖的时间总长度
double PiecewiseAccelerationTrajectory1d::ParamLength() const {
  CHECK_GT(t_.size(), 1U);
  return t_.back() - t_.front();
}

//把数据成员v_,a_,s_,t_转化成字符串并连接起来返回
std::string PiecewiseAccelerationTrajectory1d::ToString() const {
  return absl::StrCat(absl::StrJoin(s_, "\t"), absl::StrJoin(t_, "\t"),
                      absl::StrJoin(v_, "\t"), absl::StrJoin(a_, "\t"), "\n");
}

//Evaluate插值函数
//参数order阶数,param是时间,根据时间插值s,v,a,jerk
//s_,v_,a_,t_储存了多段加速度不同的匀加速度段
double PiecewiseAccelerationTrajectory1d::Evaluate(const std::uint32_t order,
                                                   const double param) const {
  CHECK_GT(t_.size(), 1U);
  ACHECK(t_.front() <= param && param <= t_.back());

  switch (order) {
    case 0:
      return Evaluate_s(param);
    case 1:
      return Evaluate_v(param);
    case 2:
      return Evaluate_a(param);
    case 3:
      return Evaluate_j(param);
  }
  return 0.0;
}
//多段匀加速段轨迹根据时间t插值对应的纵向相对位置s
double PiecewiseAccelerationTrajectory1d::Evaluate_s(const double t) const {
  //先根据时间t找到其在t_中所处的index从而确定所处区间然后进行插值
  auto it_lower = std::lower_bound(t_.begin(), t_.end(), t);
  auto index = std::distance(t_.begin(), it_lower);

  double s0 = s_[index - 1];
  double v0 = v_[index - 1];
  double t0 = t_[index - 1];

  double v1 = v_[index];
  double t1 = t_[index];

  double v = common::math::lerp(v0, t0, v1, t1, t);
  double s = (v0 + v) * (t - t0) * 0.5 + s0;
  return s;
}
//多段匀加速段轨迹根据时间t插值对应的速度v
double PiecewiseAccelerationTrajectory1d::Evaluate_v(const double t) const {
  auto it_lower = std::lower_bound(t_.begin(), t_.end(), t);
  auto index = std::distance(t_.begin(), it_lower);

  double v0 = v_[index - 1];
  double t0 = t_[index - 1];

  double v1 = v_[index];
  double t1 = t_[index];

  double v = apollo::common::math::lerp(v0, t0, v1, t1, t);
  return v;
}
//多段匀加速段轨迹根据时间t插值对应的速度a
double PiecewiseAccelerationTrajectory1d::Evaluate_a(const double t) const {
  auto it_lower = std::lower_bound(t_.begin(), t_.end(), t);
  auto index = std::distance(t_.begin(), it_lower);
  return a_[index - 1];
}
//多段匀加速段轨迹根据时间t插值对应的加加速度jerk,因为是多段匀加速度段,jerk=0.0
double PiecewiseAccelerationTrajectory1d::Evaluate_j(const double t) const {
  return 0.0;
}

//多段匀加速段轨迹根据时间t插值对应的是s,v,a,j
//返回值是一个4维的double数组
std::array<double, 4> PiecewiseAccelerationTrajectory1d::Evaluate(
    const double t) const {
  CHECK_GT(t_.size(), 1U);
  ACHECK(t_.front() <= t && t <= t_.back());

  auto it_lower = std::lower_bound(t_.begin(), t_.end(), t);
  auto index = std::distance(t_.begin(), it_lower);

  double s0 = s_[index - 1];
  double v0 = v_[index - 1];
  double t0 = t_[index - 1];

  double v1 = v_[index];
  double t1 = t_[index];

  double v = common::math::lerp(v0, t0, v1, t1, t);
  double s = (v0 + v) * (t - t0) * 0.5 + s0;

  double a = a_[index - 1];
  double j = 0.0;

  return {{s, v, a, j}};
}

}  // namespace planning
}  // namespace apollo

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

wujiangzhu_xjtu

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

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

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

打赏作者

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

抵扣说明:

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

余额充值