当前位置:   article > 正文

梯形速度规划算法原理及代码_梯形加减速算法 c语言

梯形加减速算法 c语言

梯形速度规划的原理:梯形速度规划算法
对应的代码如下:

#pragma once
#include <cmath>
#include <iostream>
#include <vector>
struct SpeedPoint {
  SpeedPoint() {
    s = 0;
    speed = 0;
    t = 0;
  }
  double s;      // m
  double speed;  // m/s
  double t;      // s
};
inline std::tuple<double, double, double> trapezoidalSpeedPlanningGetS(
    const double& max_speed, const double& init_speed,
    const double& aim_distance, const double& aim_speed,
    const double& aim_acc) {
  // 分类讨论,初始车速&最高速度的大小
  double valid_aim_speed = aim_speed;
  if (aim_speed > max_speed) {
    valid_aim_speed = max_speed;
  }
  double s1 =
      (std::pow(max_speed, 2) - std::pow(init_speed, 2)) / (2 * aim_acc);
  double s3 =
      (std::pow(max_speed, 2) - std::pow(valid_aim_speed, 2)) / (2 * aim_acc);
  double s2 = aim_distance - fabs(s1) - s3;

  if (s2 < 0) {
    s2 = 0;
    s1 = (2 * aim_acc * aim_distance - std::pow(init_speed, 2) +
          std::pow(valid_aim_speed, 2)) /
         (4 * aim_acc);
    if (fabs(s1) > aim_distance) {
      s1 = std::copysign(aim_distance, s1);
      s2 = s3 = 0;
    } else
      s3 = aim_distance - fabs(s1);
  }
  return std::tuple<double, double, double>(s1, s2, s3);
}

inline SpeedPoint trapezoidalSpeedPlanningPointByS(
    const double& s1, const double& s2, const double& s3, const double& s,
    const double& init_speed, const double& aim_acc) {
  SpeedPoint speed_point;
  double speed_m = std::sqrt(2 * aim_acc * s1 + init_speed * init_speed);
  speed_point.s = s;
  double s1_sign = std::copysign(1, s1);
  if (s <= fabs(s1)) {
    double vt = sqrt(2 * aim_acc * s1_sign * s + init_speed * init_speed);
    speed_point.speed = vt;
    speed_point.t = (vt - init_speed) / (aim_acc * s1_sign);
  } else if (s < fabs(s1) + s2) {
    double v1_t = speed_m;
    speed_point.speed = v1_t;
    // s1_t + (s - fabs(s1)) / v1_t;
    speed_point.t =
        (v1_t - init_speed) / (aim_acc * s1_sign) + (s - fabs(s1)) / v1_t;
  } else {
    // 减速段
    double v1_t = speed_m;
    double t1 = fabs(speed_m - init_speed) / aim_acc;
    double t2 = s2 / v1_t;
    double end_speed_2 = v1_t * v1_t - 2 * aim_acc * (s - s2 - fabs(s1));
    if (end_speed_2 < 1e-2)
      speed_point.speed = 0;
    else
      speed_point.speed = sqrt(end_speed_2);
    speed_point.t = t1 + t2 + (v1_t - speed_point.speed) / aim_acc;
  }
  return speed_point;
}

/**
 * @brief trapezoidalSpeedPlanning: 梯形速度规划
 * @param max_speed
 * @param init_speed
 * @param aim_distance
 * @param aim_speed
 * @param aim_acc
 * s1: 加速段
 * s2: 匀速段
 * s3: 减速段
 * @return
 */
inline std::vector<SpeedPoint> trapezoidalSpeedPlanning(
    const double& max_speed, const double& init_speed,
    const double& aim_distance, const double& aim_speed,
    const double& aim_acc) {
  std::vector<SpeedPoint> results;
  if (max_speed <= 0) {
    // to zero.
    return results;
  }
  double s1, s2, sk, s3;
  std::tuple<double, double, double> result_ss = trapezoidalSpeedPlanningGetS(
      max_speed, init_speed, aim_distance, aim_speed, aim_acc);
  s1 = std::get<0>(result_ss);
  s2 = std::get<1>(result_ss);
  s3 = std::get<2>(result_ss);
  sk = fabs(s1) + s2;
  const double delta_t = 0.1;
  double acculate_s = 0;
  double acculate_v = init_speed;
  double acculate_t = 0;
  SpeedPoint speed_point;
  double s1_sign = std::copysign(1, s1);
  double speed_m = std::sqrt(2 * aim_acc * s1 + init_speed * init_speed);
  double speed_final =
      std::sqrt(std::max(speed_m * speed_m - 2 * aim_acc * s3, 0.0));
  double time_1 = fabs(speed_m - init_speed) / aim_acc, time_2 = s2 / speed_m,
         time_3 = (speed_m - speed_final) / aim_acc;
  for (; acculate_s < aim_distance;) {
    speed_point.s = acculate_s;
    speed_point.t = acculate_t;
    speed_point.speed = acculate_v;
    acculate_t += delta_t;
    results.push_back(speed_point);
    if (acculate_t < time_1) {
      acculate_s =
          init_speed * acculate_t + 0.5 * aim_acc * acculate_t * acculate_t;
      acculate_v = init_speed + aim_acc * acculate_t * s1_sign;
    } else if (acculate_t < time_1 + time_2) {
      double noacc_t = acculate_t - time_1;
      acculate_s = s1 + speed_m * noacc_t;
      acculate_v = speed_m;
    } else {
      // 减速段
      double deacc_t = acculate_t - time_1 - time_2;
      acculate_s =
          s1 + s2 + speed_m * deacc_t - 0.5 * aim_acc * deacc_t * deacc_t;
      acculate_v = speed_m - aim_acc * deacc_t;
      if (acculate_v <= 0 || deacc_t >= time_3) break;
    }
  }
  // 增加最后1个点
  {
    speed_point = trapezoidalSpeedPlanningPointByS(s1, s2, s3, aim_distance,
                                                   init_speed, aim_acc);
    results.push_back(speed_point);
  }

  return results;
}  // namespace planning

inline double trapezoidalSpeedPlanningTime(const double& max_speed,
                                           const double& init_speed,
                                           const double& aim_distance,
                                           const double& aim_speed,
                                           const double& aim_acc) {
  if (max_speed <= 0) {
    // to zero.
    return INFINITY;
  }
  double s1, s2, s3;
  std::tuple<double, double, double> result_ss = trapezoidalSpeedPlanningGetS(
      max_speed, init_speed, aim_distance, aim_speed, aim_acc);
  double valid_aim_speed = aim_speed;
  if (aim_speed > max_speed) {
    valid_aim_speed = max_speed;
  }
  s1 = std::get<0>(result_ss);
  s2 = std::get<1>(result_ss);
  s3 = std::get<2>(result_ss);

  //  std::cout << "s1: " << s1 << ", s2: " << s2 << ", s3: " << s3 <<
  //  std::endl;
  double speed_m = std::sqrt(2 * aim_acc * s1 + init_speed * init_speed);
  double speed_final =
      std::sqrt(std::max(speed_m * speed_m - 2 * aim_acc * s3, 0.0));
  if (fabs(speed_final - valid_aim_speed) > 1) return INFINITY;
  double time_1 = fabs(speed_m - init_speed) / aim_acc, time_2 = s2 / speed_m,
         time_3 = (speed_m - speed_final) / aim_acc;
  return time_1 + time_2 + time_3;
}

inline double GetSpeedPlanningTimeByReultS(
    const std::tuple<double, double, double>& result_ss,
    const double& max_speed, const double& init_speed,
    const double& aim_distance, const double& aim_speed,
    const double& aim_acc) {
  if (max_speed <= 0) {
    // to zero.
    return INFINITY;
  }
  double s1, s2, s3;
  double valid_aim_speed = aim_speed;
  if (aim_speed > max_speed) {
    valid_aim_speed = max_speed;
  }
  s1 = std::get<0>(result_ss);
  s2 = std::get<1>(result_ss);
  s3 = std::get<2>(result_ss);

  //  std::cout << "s1: " << s1 << ", s2: " << s2 << ", s3: " << s3 <<
  //  std::endl;
  double speed_m = std::sqrt(2 * aim_acc * s1 + init_speed * init_speed);
  double speed_final =
      std::sqrt(std::max(speed_m * speed_m - 2 * aim_acc * s3, 0.0));
  if (fabs(speed_final - valid_aim_speed) > 1) return INFINITY;
  double time_1 = fabs(speed_m - init_speed) / aim_acc, time_2 = s2 / speed_m,
         time_3 = (speed_m - speed_final) / aim_acc;
  return time_1 + time_2 + time_3;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/782850?site
推荐阅读
相关标签
  

闽ICP备14008679号