|
11 | 11 | #include "drake/common/drake_assert.h"
|
12 | 12 | #include "drake/common/drake_throw.h"
|
13 | 13 | #include "drake/common/unused.h"
|
| 14 | +#include "drake/math/binomial_coefficient.h" |
14 | 15 | #include "drake/math/matrix_util.h"
|
15 | 16 |
|
16 | 17 | using Eigen::VectorXd;
|
@@ -532,6 +533,83 @@ void PiecewisePolynomial<T>::shiftRight(const T& offset) {
|
532 | 533 | }
|
533 | 534 | }
|
534 | 535 |
|
| 536 | +namespace { |
| 537 | +template <typename T> |
| 538 | +Polynomial<T> ShiftPoly(Polynomial<T> poly, const T& x) { |
| 539 | + if (poly.GetVariables().size() == 0) { |
| 540 | + // Make constant polynomial. |
| 541 | + return poly; |
| 542 | + } |
| 543 | + using std::pow; |
| 544 | + // Given p(t) = a0 + a1*t + a2*t^2 + ... + an*t^n, |
| 545 | + // we want to shift the parameter to p(t + x) |
| 546 | + // = b0 + b1*t + b2*t^2 + ... + bn*t^n. |
| 547 | + // We can expand the rhs to get the values in b. |
| 548 | + DRAKE_THROW_UNLESS(poly.GetVariables().size() == 1); |
| 549 | + int n = poly.GetDegree(); |
| 550 | + const auto& a = poly.GetCoefficients(); |
| 551 | + Eigen::Matrix<T, Eigen::Dynamic, 1> b = |
| 552 | + Eigen::Matrix<T, Eigen::Dynamic, 1>::Zero(n + 1); |
| 553 | + for (int i = 0; i <= n; i++) { |
| 554 | + for (int j = 0; j <= i; j++) { |
| 555 | + b(j) += a(i) * drake::math::BinomialCoefficient(i, j) * pow(x, i - j); |
| 556 | + } |
| 557 | + } |
| 558 | + return Polynomial<T>(b); |
| 559 | +} |
| 560 | +} // namespace |
| 561 | + |
| 562 | +template <typename T> |
| 563 | +int PiecewisePolynomial<T>::AddBreak(const T& new_break) { |
| 564 | + auto& breaks = this->get_mutable_breaks(); |
| 565 | + // Check if the new break is already within the kEpsilonTime of an |
| 566 | + // existing break. |
| 567 | + for (int k = 0; k < this->get_number_of_segments(); k++) { |
| 568 | + const T& break_time = breaks[k]; |
| 569 | + if (abs(break_time - new_break) < PiecewiseTrajectory<T>::kEpsilonTime) { |
| 570 | + // No need to add a new break. |
| 571 | + return k; |
| 572 | + } |
| 573 | + } |
| 574 | + DRAKE_THROW_UNLESS(this->is_time_in_range(new_break)); |
| 575 | + const auto value = this->value(new_break); |
| 576 | + int i = this->get_segment_index(new_break); |
| 577 | + const T last_break_before_new = this->start_time(i); |
| 578 | + const T shift = new_break - last_break_before_new; |
| 579 | + breaks.insert(breaks.begin() + i + 1, new_break); |
| 580 | + // New polynomial matrix to be added at index i. |
| 581 | + const auto& broken_polynomial = polynomials_[i]; |
| 582 | + PolynomialMatrix new_polynomial = broken_polynomial; |
| 583 | + for (int row = 0; row < rows(); row++) { |
| 584 | + for (int col = 0; col < cols(); col++) { |
| 585 | + new_polynomial(row, col) = ShiftPoly(new_polynomial(row, col), shift); |
| 586 | + } |
| 587 | + } |
| 588 | + // The i+1'th polynomial should become the new_polynomial. |
| 589 | + polynomials_.insert(polynomials_.begin() + i + 1, new_polynomial); |
| 590 | + return i + 1; |
| 591 | +} |
| 592 | + |
| 593 | +template <typename T> |
| 594 | +PiecewisePolynomial<T> PiecewisePolynomial<T>::SliceByTime( |
| 595 | + const T& start_time, const T& end_time) const { |
| 596 | + DRAKE_THROW_UNLESS(start_time < end_time); |
| 597 | + DRAKE_THROW_UNLESS(this->is_time_in_range(start_time)); |
| 598 | + DRAKE_THROW_UNLESS(this->is_time_in_range(end_time)); |
| 599 | + PiecewisePolynomial<T> result{*this}; |
| 600 | + int i = result.AddBreak(start_time); |
| 601 | + int j = result.AddBreak(end_time); |
| 602 | + std::vector<PolynomialMatrix> polynomials; |
| 603 | + std::vector<T> breaks; |
| 604 | + for (int k = i; k < j; k++) { |
| 605 | + polynomials.push_back(result.getPolynomialMatrix(k)); |
| 606 | + breaks.push_back(result.get_segment_times()[k]); |
| 607 | + } |
| 608 | + // Add the last break |
| 609 | + breaks.push_back(result.get_segment_times()[j]); |
| 610 | + return PiecewisePolynomial<T>(polynomials, breaks); |
| 611 | +} |
| 612 | + |
535 | 613 | template <typename T>
|
536 | 614 | void PiecewisePolynomial<T>::setPolynomialMatrixBlock(
|
537 | 615 | const typename PiecewisePolynomial<T>::PolynomialMatrix& replacement,
|
|
0 commit comments