15 template<
class T,
class U = T>
26 func_ = std::make_shared<PiecewiseFunc<double>>();
30 throw std::invalid_argument(
31 "[BangBangInterpolator] The size of the accelDurationList must be one less than the size of the points: "
32 + std::to_string(
accelDurationList_.size()) +
" != " + std::to_string(this->points_.size()) +
" + 1");
45 func_ = std::make_shared<PiecewiseFunc<double>>(*inst.
func_);
49 virtual std::shared_ptr<Interpolator<T, U>>
clone()
const override
66 virtual void appendPoint(
const std::pair<double, T> & point)
override
77 void appendPoint(
const std::pair<double, T> & point,
double accelDuration)
79 if(!this->
points_.empty() && point.first <= this->points_.rbegin()->first)
81 throw std::invalid_argument(
"[BangBangInterpolator] Only adding a trailing point is allowed: "
82 + std::to_string(point.first)
83 +
" <= " + std::to_string(this->points_.rbegin()->first));
91 double interpDuration = this->
points_.rbegin()->first - std::next(this->
points_.rbegin())->first;
93 if(accelDuration <= 0.0)
95 constexpr
double accelDurationRatio = 0.2;
96 accelDuration = accelDurationRatio * interpDuration;
99 if(accelDuration >= 0.5 * interpDuration)
101 std::cerr <<
"[BangBangInterpolator] Overwrite accelDuration because accelDuration must be less than half of "
103 << std::to_string(accelDuration) <<
" >= " << std::to_string(0.5 * interpDuration) << std::endl;
104 constexpr
double eps = 1e-10;
105 accelDuration = 0.5 * interpDuration - eps;
117 throw std::out_of_range(
"[BangBangInterpolator] Number of points should be 2 or more: "
118 + std::to_string(this->
points_.size()));
123 auto pointIt = this->
points_.begin();
124 for(
int i = 0; i < static_cast<int>(this->
points_.size()) - 1; i++, pointIt++)
126 double segStartTime = pointIt->first;
127 double segEndTime = std::next(pointIt)->first;
129 double segVel = 1.0 / (segEndTime - segStartTime - segAccelDuration);
130 double segAccel = segVel / segAccelDuration;
133 std::shared_ptr<PiecewiseFunc<double>> segFunc = std::make_shared<PiecewiseFunc<double>>();
134 segFunc->setDomainLowerLimit(segStartTime);
135 segFunc->appendFunc(segStartTime + segAccelDuration,
137 std::array<double, 3>{
static_cast<double>(i), 0.0, 0.5 * segAccel}, segStartTime));
139 segEndTime - segAccelDuration,
141 0.5 * (segStartTime + segEndTime)));
142 segFunc->appendFunc(segEndTime,
144 std::array<double, 3>{
static_cast<double>(i + 1), 0.0, -0.5 * segAccel}, segEndTime));
146 func_->appendFunc(segEndTime, segFunc);
149 func_->setDomainLowerLimit(this->
points_.begin()->first);
157 size_t idx =
func_->index(t);
158 double ratio = (*func_)(t) -
static_cast<double>(idx);
159 return interpolate<T>(std::next(this->
points_.begin(), idx)->second,
160 std::next(this->points_.begin(), idx + 1)->second, std::clamp(ratio, 0.0, 1.0));
171 size_t idx =
func_->index(t);
172 double ratio = (*func_)(t) -
static_cast<double>(idx);
173 return func_->derivative(t, order)
174 * interpolateDerivative<T, U>(std::next(this->
points_.begin(), idx)->second,
175 std::next(this->points_.begin(), idx + 1)->second, std::clamp(ratio, 0.0, 1.0),
184 std::shared_ptr<PiecewiseFunc<double>>
func_;