37 #include "ompl/geometric/PathSimplifier.h" 
   38 #include "ompl/tools/config/MagicConstants.h" 
   39 #include "ompl/base/objectives/PathLengthOptimizationObjective.h" 
   40 #include "ompl/base/StateSampler.h" 
   49                                                 const base::OptimizationObjectivePtr &obj)
 
   50   : si_(std::move(si)), freeStates_(true)
 
   54         gsr_ = std::dynamic_pointer_cast<base::GoalSampleableRegion>(goal);
 
   56             OMPL_WARN(
"%s: Goal could not be cast to GoalSampleableRegion.  Goal simplification will not be performed.",
 
   65         obj_ = std::make_shared<base::PathLengthOptimizationObjective>(
si_);
 
   82     if (path.getStateCount() < 3)
 
   85     const base::SpaceInformationPtr &si = path.getSpaceInformation();
 
   86     std::vector<base::State *> &states = path.getStates();
 
   91     for (
unsigned int s = 0; s < maxSteps; ++s)
 
   95         unsigned int i = 2, u = 0, n1 = states.size() - 1;
 
   98             if (si->isValid(states[i - 1]))
 
  100                 si->getStateSpace()->interpolate(states[i - 1], states[i], 0.5, temp1);
 
  101                 si->getStateSpace()->interpolate(states[i], states[i + 1], 0.5, temp2);
 
  102                 si->getStateSpace()->interpolate(temp1, temp2, 0.5, temp1);
 
  103                 if (si->checkMotion(states[i - 1], temp1) && si->checkMotion(temp1, states[i + 1]))
 
  105                     if (si->distance(states[i], temp1) > minChange)
 
  107                         si->copyState(states[i], temp1);
 
  120     si->freeState(temp1);
 
  121     si->freeState(temp2);
 
  125                                                      unsigned int maxEmptySteps, 
double rangeRatio)
 
  127     if (path.getStateCount() < 3)
 
  131         maxSteps = path.getStateCount();
 
  133     if (maxEmptySteps == 0)
 
  134         maxEmptySteps = path.getStateCount();
 
  137     unsigned int nochange = 0;
 
  138     const base::SpaceInformationPtr &si = path.getSpaceInformation();
 
  139     std::vector<base::State *> &states = path.getStates();
 
  141     if (si->checkMotion(states.front(), states.back()))
 
  144             for (std::size_t i = 2; i < states.size(); ++i)
 
  145                 si->freeState(states[i - 1]);
 
  146         std::vector<base::State *> newStates(2);
 
  147         newStates[0] = states.front();
 
  148         newStates[1] = states.back();
 
  149         states.swap(newStates);
 
  153         for (
unsigned int i = 0; i < maxSteps && nochange < maxEmptySteps; ++i, ++nochange)
 
  155             int count = states.size();
 
  156             int maxN = count - 1;
 
  157             int range = 1 + (int)(floor(0.5 + (
double)count * rangeRatio));
 
  159             int p1 = rng_.uniformInt(0, maxN);
 
  160             int p2 = rng_.uniformInt(std::max(p1 - range, 0), std::min(maxN, p1 + range));
 
  161             if (abs(p1 - p2) < 2)
 
  174             if (si->checkMotion(states[p1], states[p2]))
 
  177                     for (
int j = p1 + 1; j < p2; ++j)
 
  178                         si->freeState(states[j]);
 
  179                 states.erase(states.begin() + p1 + 1, states.begin() + p2);
 
  189     if (path.getStateCount() < 3)
 
  192     const base::SpaceInformationPtr &si = path.getSpaceInformation();
 
  193     std::vector<base::State *> &states = path.getStates();
 
  197     for (std::size_t i = 0; i < states.size() - 1; ++i)
 
  199         double dist = si->distance(states[i], states[i + 1]);
 
  202             std::size_t numIntermediateStates = 
static_cast<std::size_t
>(floor(dist / delta));
 
  203             double t = 1.0 / (numIntermediateStates + 1);
 
  204             for (std::size_t j = 0; j < numIntermediateStates; ++j)
 
  207                 si->getStateSpace()->interpolate(states[i], states[i + 1 + j], t * (j + 1), newState);
 
  208                 states.insert(states.begin() + i + 1 + j, newState);
 
  210             i = i + numIntermediateStates;
 
  216     std::vector<base::Cost> costs(states.size(), obj_->identityCost());
 
  217     for (std::size_t i = 1; i < costs.size(); ++i)
 
  219         costs[i] = obj_->combineCosts(costs[i - 1], obj_->motionCost(states[i - 1], states[i]));
 
  226     for (std::size_t i = 0; i < states.size() - 2; ++i)
 
  229         for (std::size_t j = states.size() - 1; j > i + 1; --j)
 
  232             if (si->checkMotion(states[i], states[j]))
 
  234                 base::Cost shortcutCost = obj_->motionCost(states[i], states[j]);
 
  235                 base::Cost alongPath = obj_->subtractCosts(costs[j], costs[i]);
 
  238                 if (obj_->isCostBetterThan(obj_->subtractCosts(alongPath, shortcutCost), equivalenceCost))
 
  240                     if (j == states.size() - 1)  
 
  247                 if (obj_->isCostBetterThan(shortcutCost, alongPath))
 
  251                         for (std::size_t k = i + 1; k < j; ++k)
 
  252                             si->freeState(states[k]);
 
  253                     states.erase(states.begin() + i + 1, states.begin() + j);
 
  256                     double dist = si->distance(states[i], states[j]);
 
  259                         std::size_t numIntermediateStates = (int)(floor(dist / delta));
 
  260                         double t = 1.0 / (numIntermediateStates + 1);
 
  261                         for (std::size_t k = 0; k < numIntermediateStates; ++k)
 
  264                             si->getStateSpace()->interpolate(states[i], states[i + 1 + k], t * (k + 1), newState);
 
  265                             states.insert(states.begin() + i + 1 + k, newState);
 
  270                     costs.resize(states.size(), obj_->identityCost());
 
  271                     for (std::size_t k = i + 1; k < costs.size(); ++k)
 
  273                         costs[k] = obj_->combineCosts(costs[k - 1], obj_->motionCost(states[k - 1], states[k]));
 
  277                     if (j == states.size() - 1)  
 
  294                                                           unsigned int maxEmptySteps, 
double rangeRatio,
 
  297     if (path.getStateCount() < 3)
 
  301         maxSteps = path.getStateCount();
 
  303     if (maxEmptySteps == 0)
 
  304         maxEmptySteps = path.getStateCount();
 
  306     const base::SpaceInformationPtr &si = path.getSpaceInformation();
 
  307     std::vector<base::State *> &states = path.getStates();
 
  310     std::vector<base::Cost> costs(states.size(), obj_->identityCost());
 
  311     std::vector<double> dists(states.size(), 0.0);
 
  312     for (
unsigned int i = 1; i < costs.size(); ++i)
 
  314         costs[i] = obj_->combineCosts(costs[i - 1], obj_->motionCost(states[i - 1], states[i]));
 
  315         dists[i] = dists[i - 1] + si->distance(states[i - 1], states[i]);
 
  319     double threshold = dists.back() * snapToVertex;
 
  321     double rd = rangeRatio * dists.back();
 
  326     unsigned int nochange = 0;
 
  329     for (
unsigned int i = 0; i < maxSteps && nochange < maxEmptySteps; ++i, ++nochange)
 
  335         double distTo0 = rng_.uniformReal(0.0, dists.back());  
 
  337             std::lower_bound(dists.begin(), dists.end(), distTo0);  
 
  338         int pos0 = pit == dists.end() ? dists.size() - 1 :
 
  341         if (pos0 == 0 || dists[pos0] - distTo0 < threshold)  
 
  345             while (pos0 > 0 && distTo0 < dists[pos0])
 
  347             if (distTo0 - dists[pos0] < threshold)  
 
  356             rng_.uniformReal(std::max(0.0, distTo0 - rd),
 
  357                              std::min(distTo0 + rd, dists.back()));   
 
  358         pit = std::lower_bound(dists.begin(), dists.end(), distTo1);  
 
  359         int pos1 = pit == dists.end() ? dists.size() - 1 :
 
  362         if (pos1 == 0 || dists[pos1] - distTo1 < threshold)  
 
  366             while (pos1 > 0 && distTo1 < dists[pos1])
 
  368             if (distTo1 - dists[pos1] < threshold)  
 
  373         if (pos0 == pos1 || index0 == pos1 || index1 == pos0 || pos0 + 1 == index1 || pos1 + 1 == index0 ||
 
  374             (index0 >= 0 && index1 >= 0 && abs(index0 - index1) < 2))
 
  384             t0 = (distTo0 - dists[pos0]) / (dists[pos0 + 1] - dists[pos0]);
 
  385             si->getStateSpace()->interpolate(states[pos0], states[pos0 + 1], t0, temp0);
 
  396             t1 = (distTo1 - dists[pos1]) / (dists[pos1 + 1] - dists[pos1]);
 
  397             si->getStateSpace()->interpolate(states[pos1], states[pos1 + 1], t1, temp1);
 
  402         if (si->checkMotion(s0, s1))
 
  406                 std::swap(pos0, pos1);
 
  407                 std::swap(index0, index1);
 
  413             base::Cost s0PartialCost = (index0 >= 0) ? obj_->identityCost() : obj_->motionCost(s0, states[pos0 + 1]);
 
  414             base::Cost s1PartialCost = (index1 >= 0) ? obj_->identityCost() : obj_->motionCost(states[pos1], s1);
 
  416             int posTemp = pos0 + 1;
 
  417             while (posTemp < pos1)
 
  419                 alongPath = obj_->combineCosts(alongPath, obj_->motionCost(states[posTemp], states[posTemp + 1]));
 
  422             alongPath = obj_->combineCosts(alongPath, s1PartialCost);
 
  423             if (obj_->isCostBetterThan(alongPath, obj_->motionCost(s0, s1)))
 
  432             if (index0 < 0 && index1 < 0)
 
  434                 if (pos0 + 1 == pos1)
 
  436                     si->copyState(states[pos1], s0);
 
  437                     states.insert(states.begin() + pos1 + 1, si->cloneState(s1));
 
  442                         for (
int j = pos0 + 2; j < pos1; ++j)
 
  443                             si->freeState(states[j]);
 
  444                     si->copyState(states[pos0 + 1], s0);
 
  445                     si->copyState(states[pos1], s1);
 
  446                     states.erase(states.begin() + pos0 + 2, states.begin() + pos1);
 
  449             else if (index0 >= 0 && index1 >= 0)
 
  452                     for (
int j = index0 + 1; j < index1; ++j)
 
  453                         si->freeState(states[j]);
 
  454                 states.erase(states.begin() + index0 + 1, states.begin() + index1);
 
  456             else if (index0 < 0 && index1 >= 0)
 
  459                     for (
int j = pos0 + 2; j < index1; ++j)
 
  460                         si->freeState(states[j]);
 
  461                 si->copyState(states[pos0 + 1], s0);
 
  462                 states.erase(states.begin() + pos0 + 2, states.begin() + index1);
 
  464             else if (index0 >= 0 && index1 < 0)
 
  467                     for (
int j = index0 + 1; j < pos1; ++j)
 
  468                         si->freeState(states[j]);
 
  469                 si->copyState(states[pos1], s1);
 
  470                 states.erase(states.begin() + index0 + 1, states.begin() + pos1);
 
  474             dists.resize(states.size(), 0.0);
 
  475             costs.resize(states.size(), obj_->identityCost());
 
  476             for (
unsigned int j = pos0 + 1; j < costs.size(); ++j)
 
  478                 costs[j] = obj_->combineCosts(costs[j - 1], obj_->motionCost(states[j - 1], states[j]));
 
  479                 dists[j] = dists[j - 1] + si->distance(states[j - 1], states[j]);
 
  481             threshold = dists.back() * snapToVertex;
 
  482             rd = rangeRatio * dists.back();
 
  488     si->freeState(temp1);
 
  489     si->freeState(temp0);
 
  494                                                   unsigned int maxEmptySteps, 
double snapToVertex)
 
  497         maxSteps = path.getStateCount();
 
  499     if (maxEmptySteps == 0)
 
  500         maxEmptySteps = path.getStateCount();
 
  502     const base::SpaceInformationPtr &si = path.getSpaceInformation();
 
  503     std::vector<base::State *> &states = path.getStates();
 
  505     std::vector<double> dists(states.size(), 0.0);
 
  506     for (
unsigned int i = 1; i < dists.size(); i++)
 
  507         dists[i] = dists[i - 1] + si->distance(states[i - 1], states[i]);
 
  509     std::vector<std::tuple<double, base::Cost, unsigned int>> distCostIndices;
 
  510     for (
unsigned int i = 0; i < states.size() - 1; i++)
 
  511         distCostIndices.emplace_back(si->distance(states[i], states[i + 1]), obj_->motionCost(states[i], states[i + 1]),
 
  515     std::sort(distCostIndices.begin(), distCostIndices.end(),
 
  516               [
this](std::tuple<double, base::Cost, unsigned int> a, std::tuple<double, base::Cost, unsigned int> b) {
 
  517                   return obj_->isCostBetterThan(std::get<1>(b), std::get<1>(a));
 
  520     double threshold = dists.back() * snapToVertex;
 
  523     unsigned int nochange = 0;
 
  525     base::StateSamplerPtr sampler = si->allocStateSampler();
 
  534     for (
unsigned int i = 0; i < maxSteps && nochange < maxEmptySteps; i++, nochange++)
 
  538         double costBias = -1 * rng_.halfNormalReal(-dists.back(), 0.0, 20.0);
 
  540         if (costBias >= dists.back())
 
  542             z = distCostIndices.size() - 1;
 
  543             costBias = std::get<0>(distCostIndices[z]);
 
  548             while (costBias - std::get<0>(distCostIndices[z]) > std::numeric_limits<double>::epsilon())
 
  550                 costBias -= std::get<0>(distCostIndices[z]);
 
  555         int pos, pos_before, pos_after;
 
  556         double distTo = dists[std::get<2>(distCostIndices[z])] + costBias;
 
  557         selectAlongPath(dists, states, distTo, threshold, perturb_state, pos);
 
  560         int index_before = selectAlongPath(dists, states, distTo - stepSize / 2.0, threshold, before_state, pos_before);
 
  561         int index_after = selectAlongPath(dists, states, distTo + stepSize / 2.0, threshold, after_state, pos_after);
 
  563         if (index_before >= 0 && index_after >= 0 && index_before == index_after)
 
  569         sampler->sampleUniform(new_state);
 
  570         double dist = si->distance(perturb_state, new_state);
 
  571         si->getStateSpace()->interpolate(perturb_state, new_state, stepSize / dist, new_state);
 
  574         if (si->checkMotion(before_state, new_state) && si->checkMotion(new_state, after_state))
 
  578             if (pos_before == pos_after)
 
  580                 alongPath = obj_->motionCost(before_state, after_state);
 
  586                     (index_before >= 0) ? obj_->identityCost() : obj_->motionCost(before_state, states[pos_before + 1]);
 
  587                 int posTemp = (index_before >= 0) ? index_before : pos_before + 1;
 
  588                 while (posTemp < pos_after)
 
  590                     alongPath = obj_->combineCosts(alongPath, obj_->motionCost(states[posTemp], states[posTemp + 1]));
 
  594                     (index_after >= 0) ? obj_->identityCost() : obj_->motionCost(states[pos_after], after_state);
 
  595                 alongPath = obj_->combineCosts(alongPath, afterPartialCost);
 
  599                 obj_->combineCosts(obj_->motionCost(before_state, new_state), obj_->motionCost(new_state, after_state));
 
  600             if (obj_->isCostBetterThan(alongPath, newCost) || obj_->isCostEquivalentTo(alongPath, newCost))
 
  607             if (index_before < 0 && index_after < 0)
 
  609                 if (pos_before == pos_after)
 
  613                     states.insert(states.begin() + pos_before + 1, si->cloneState(after_state));
 
  614                     states.insert(states.begin() + pos_before + 1, si->cloneState(new_state));
 
  615                     states.insert(states.begin() + pos_before + 1, si->cloneState(before_state));
 
  617                 else if (pos_before + 1 == pos_after)
 
  619                     si->copyState(states[pos_after], before_state);
 
  620                     states.insert(states.begin() + pos_after + 1, si->cloneState(after_state));
 
  621                     states.insert(states.begin() + pos_after + 1, si->cloneState(new_state));
 
  623                 else if (pos_before + 2 == pos_after)
 
  625                     si->copyState(states[pos_before + 1], before_state);
 
  626                     si->copyState(states[pos_after], new_state);
 
  627                     states.insert(states.begin() + pos_after + 1, si->cloneState(after_state));
 
  631                     si->copyState(states[pos_before + 1], before_state);
 
  632                     si->copyState(states[pos_before + 2], new_state);
 
  633                     si->copyState(states[pos_before + 3], after_state);
 
  635                         for (
int j = pos_before + 4; j < pos_after + 1; ++j)
 
  636                             si->freeState(states[j]);
 
  637                     states.erase(states.begin() + pos_before + 4, states.begin() + pos_after + 1);
 
  640             else if (index_before >= 0 && index_after >= 0)
 
  642                 states.insert(states.begin() + index_before + 1, si->cloneState(new_state));
 
  644                     for (
int j = index_before + 2; j < index_after + 1; ++j)
 
  645                         si->freeState(states[j]);
 
  646                 states.erase(states.begin() + index_before + 2, states.begin() + index_after + 1);
 
  648             else if (index_before < 0 && index_after >= 0)
 
  650                 if (index_after > pos_before + 1)
 
  652                     si->copyState(states[pos_before + 1], before_state);
 
  653                     states.insert(states.begin() + pos_before + 2, si->cloneState(new_state));
 
  655                         for (
int j = pos_before + 3; j < index_after + 1; ++j)
 
  656                             si->freeState(states[j]);
 
  657                     states.erase(states.begin() + pos_before + 3, states.begin() + index_after + 1);
 
  661                     states.insert(states.begin() + pos_before + 1, si->cloneState(new_state));
 
  662                     states.insert(states.begin() + pos_before + 1, si->cloneState(before_state));
 
  665             else if (index_before >= 0 && index_after < 0)
 
  667                 if (pos_after > index_before)
 
  669                     si->copyState(states[pos_after], new_state);
 
  670                     states.insert(states.begin() + pos_after + 1, si->cloneState(after_state));
 
  672                         for (
int j = index_before + 1; j < pos_after; ++j)
 
  673                             si->freeState(states[j]);
 
  674                     states.erase(states.begin() + index_before + 1, states.begin() + pos_after);
 
  678                     states.insert(states.begin() + index_before + 1, si->cloneState(after_state));
 
  679                     states.insert(states.begin() + index_before + 1, si->cloneState(new_state));
 
  684             dists.resize(states.size(), 0.0);
 
  685             for (
unsigned int j = pos_before + 1; j < dists.size(); ++j)
 
  687                 dists[j] = dists[j - 1] + si->distance(states[j - 1], states[j]);
 
  689             distCostIndices.clear();
 
  690             for (
unsigned int i = 0; i < states.size() - 1; i++)
 
  691                 distCostIndices.emplace_back(si->distance(states[i], states[i + 1]),
 
  692                                              obj_->motionCost(states[i], states[i + 1]), i);
 
  696                 distCostIndices.begin(), distCostIndices.end(),
 
  697                 [
this](std::tuple<double, base::Cost, unsigned int> a, std::tuple<double, base::Cost, unsigned int> b) {
 
  698                     return obj_->isCostBetterThan(std::get<1>(b), std::get<1>(a));
 
  700             threshold = dists.back() * snapToVertex;
 
  705     si->freeState(perturb_state);
 
  706     si->freeState(before_state);
 
  707     si->freeState(after_state);
 
  708     si->freeState(new_state);
 
  714                                                             unsigned int maxEmptySteps)
 
  716     if (path.getStateCount() < 3)
 
  720         maxSteps = path.getStateCount();
 
  722     if (maxEmptySteps == 0)
 
  723         maxEmptySteps = path.getStateCount();
 
  725     const base::SpaceInformationPtr &si = path.getSpaceInformation();
 
  726     std::vector<base::State *> &states = path.getStates();
 
  729     std::map<std::pair<const base::State *, const base::State *>, 
double> distances;
 
  730     for (
unsigned int i = 0; i < states.size(); ++i)
 
  731         for (
unsigned int j = i + 2; j < states.size(); ++j)
 
  732             distances[std::make_pair(states[i], states[j])] = si->distance(states[i], states[j]);
 
  735     unsigned int nochange = 0;
 
  736     for (
unsigned int s = 0; s < maxSteps && nochange < maxEmptySteps; ++s, ++nochange)
 
  739         double minDist = std::numeric_limits<double>::infinity();
 
  742         for (
unsigned int i = 0; i < states.size(); ++i)
 
  743             for (
unsigned int j = i + 2; j < states.size(); ++j)
 
  745                 double d = distances[std::make_pair(states[i], states[j])];
 
  754         if (p1 >= 0 && p2 >= 0)
 
  756             if (si->checkMotion(states[p1], states[p2]))
 
  759                     for (
int i = p1 + 1; i < p2; ++i)
 
  760                         si->freeState(states[i]);
 
  761                 states.erase(states.begin() + p1 + 1, states.begin() + p2);
 
  766                 distances[std::make_pair(states[p1], states[p2])] = std::numeric_limits<double>::infinity();
 
  777     return simplify(path, neverTerminate);
 
  788     if (path.getStateCount() < 3)
 
  791     bool tryMore = 
true, valid = 
true;
 
  792     while ((ptc == 
false || atLeastOnce) && tryMore)
 
  795         if ((ptc == 
false || atLeastOnce) && si_->getStateSpace()->isMetricSpace())
 
  797             bool metricTryMore = 
true;
 
  798             unsigned int times = 0;
 
  801                 bool shortcut = partialShortcutPath(path);  
 
  803                     gsr_ ? findBetterGoal(path, ptc) : 
false;  
 
  805                 metricTryMore = shortcut || better_goal;
 
  806             } 
while ((ptc == 
false || atLeastOnce) && ++times <= 5 && metricTryMore);
 
  809             if (ptc == 
false || atLeastOnce)
 
  810                 smoothBSpline(path, 3, path.length() / 100.0);
 
  812             if (ptc == 
false || atLeastOnce)
 
  819                     OMPL_WARN(
"Solution path may slightly touch on an invalid region of the state space");
 
  822                     OMPL_DEBUG(
"The solution path was slightly touching on an invalid region of the state space, but " 
  824                                "successfully fixed.");
 
  829         if (ptc == 
false || atLeastOnce)
 
  830             tryMore = reduceVertices(path);
 
  833         if (ptc == 
false || atLeastOnce)
 
  834             collapseCloseVertices(path);
 
  837         unsigned int times = 0;
 
  838         while ((ptc == 
false || atLeastOnce) && tryMore && ++times <= 5)
 
  839             tryMore = reduceVertices(path);
 
  841         if ((ptc == 
false || atLeastOnce) && si_->getStateSpace()->isMetricSpace())
 
  848                 OMPL_WARN(
"Solution path may slightly touch on an invalid region of the state space");
 
  851                 OMPL_DEBUG(
"The solution path was slightly touching on an invalid region of the state space, but it " 
  853                            "successfully fixed.");
 
  858     return valid || path.check();
 
  862                                                      double rangeRatio, 
double snapToVertex)
 
  869                                                      unsigned int samplingAttempts, 
double rangeRatio,
 
  872     if (path.getStateCount() < 2)
 
  877         OMPL_WARN(
"%s: No goal sampleable object to sample a better goal from.", 
"PathSimplifier::findBetterGoal");
 
  881     unsigned int maxGoals = std::min((
unsigned)10, gsr_->maxSampleCount());  
 
  882     unsigned int failedTries = 0;
 
  883     bool betterGoal = 
false;
 
  885     const base::StateSpacePtr &ss = si_->getStateSpace();
 
  886     std::vector<base::State *> &states = path.getStates();
 
  889     std::vector<base::Cost> costs(states.size(), obj_->identityCost());
 
  890     std::vector<double> dists(states.size(), 0.0);
 
  891     for (
unsigned int i = 1; i < dists.size(); ++i)
 
  893         costs[i] = obj_->combineCosts(costs[i - 1], obj_->motionCost(states[i - 1], states[i]));
 
  894         dists[i] = dists[i - 1] + si_->distance(states[i - 1], states[i]);
 
  897             OMPL_WARN(
"%s: Somehow computed negative distance!.", 
"PathSimplifier::findBetterGoal");
 
  904     double threshold = dists.back() * snapToVertex;
 
  906     double rd = rangeRatio * dists.back();
 
  911     while (!ptc && failedTries++ < maxGoals && !betterGoal)
 
  913         gsr_->sampleGoal(tempGoal);
 
  916         if (!gsr_->isStartGoalPairValid(path.getState(0), tempGoal))
 
  919         unsigned int numSamples = 0;
 
  920         while (!ptc && numSamples++ < samplingAttempts && !betterGoal)
 
  923             double t = rng_.uniformReal(std::max(dists.back() - rd, 0.0),
 
  926             auto end = std::lower_bound(dists.begin(), dists.end(), t);
 
  928             while (start != dists.begin() && *start >= t)
 
  931             unsigned int startIndex = start - dists.begin();
 
  932             unsigned int endIndex = end - dists.begin();
 
  935             if (t - (*start) < threshold)  
 
  936                 endIndex = startIndex;
 
  937             if ((*end) - t < threshold)  
 
  938                 startIndex = endIndex;
 
  943             if (startIndex == endIndex)
 
  945                 state = states[startIndex];
 
  949                 double tSeg = (t - (*start)) / (*end - *start);
 
  950                 ss->interpolate(states[startIndex], states[endIndex], tSeg, temp);
 
  953                 costToCome = obj_->combineCosts(costToCome, obj_->motionCost(states[startIndex], state));
 
  956             base::Cost costToGo = obj_->motionCost(state, tempGoal);
 
  957             base::Cost candidateCost = obj_->combineCosts(costToCome, costToGo);
 
  960             if (obj_->isCostBetterThan(candidateCost, costs.back()) && si_->checkMotion(state, tempGoal))
 
  963                 if (startIndex == endIndex)
 
  966                     si_->copyState(states[startIndex], state);
 
  968                     si_->copyState(states[startIndex + 1], tempGoal);
 
  972                         for (
size_t i = startIndex + 2; i < states.size(); ++i)
 
  973                             si_->freeState(states[i]);
 
  975                     states.erase(states.begin() + startIndex + 2, states.end());
 
  980                     si_->copyState(states[endIndex], state);
 
  981                     if (endIndex == states.size() - 1)
 
  983                         path.append(tempGoal);
 
  988                         si_->copyState(states[endIndex + 1], tempGoal);
 
  991                             for (
size_t i = endIndex + 2; i < states.size(); ++i)
 
  992                                 si_->freeState(states[i]);
 
  994                         states.erase(states.begin() + endIndex + 2, states.end());
 
  999                 costs.resize(states.size(), obj_->identityCost());
 
 1000                 dists.resize(states.size(), 0.0);
 
 1001                 for (
unsigned int j = std::max(1u, startIndex); j < dists.size(); ++j)
 
 1003                     costs[j] = obj_->combineCosts(costs[j - 1], obj_->motionCost(states[j - 1], states[j]));
 
 1004                     dists[j] = dists[j - 1] + si_->distance(states[j - 1], states[j]);
 
 1012     si_->freeState(temp);
 
 1013     si_->freeState(tempGoal);
 
 1018 int ompl::geometric::PathSimplifier::selectAlongPath(std::vector<double> dists, std::vector<base::State *> states,
 
 1019                                                      double distTo, 
double threshold, 
base::State *select_state,
 
 1024     else if (distTo > dists.back())
 
 1025         distTo = dists.back();
 
 1028     auto pit = std::lower_bound(dists.begin(), dists.end(), distTo);
 
 1029     pos = pit == dists.end() ? dists.size() - 1 : pit - dists.begin();
 
 1031     if (pos == 0 || dists[pos] - distTo < threshold)
 
 1035         while (pos > 0 && distTo < dists[pos])
 
 1037         if (distTo - dists[pos] < threshold)
 
 1043         si_->copyState(select_state, states[index]);
 
 1048         double t = (distTo - dists[pos]) / (dists[pos + 1] - dists[pos]);
 
 1049         si_->getStateSpace()->interpolate(states[pos], states[pos + 1], t, select_state);