Skip to content

Commit 3418f33

Browse files
author
twill777
committed
Updated order to perform straight line check before search and fixed PDT
visualize support - Switch order of Extend and Connect step in search to start with straight line check - Unified initial and aox planners into one aox planner - Cleaned up planner restart functionality for pdt visualize - Should fix nearest neighbour crash
1 parent 27db84d commit 3418f33

File tree

4 files changed

+231
-127
lines changed

4 files changed

+231
-127
lines changed

src/ompl/geometric/planners/rrt/AORRTC.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242
#include "ompl/base/OptimizationObjective.h"
4343
#include "ompl/geometric/PathSimplifier.h"
4444

45-
#include "ompl/geometric/planners/rrt/RRTConnect.h"
4645
#include "ompl/geometric/planners/rrt/AOXRRTConnect.h"
4746

4847
namespace ompl
@@ -88,6 +87,8 @@ namespace ompl
8887

8988
void setup() override;
9089

90+
void reset(bool solvedProblem);
91+
9192
void setProblemDefinition(const base::ProblemDefinitionPtr &pdef) override;
9293

9394
void setRange(double distance)
@@ -138,7 +139,6 @@ namespace ompl
138139
/** \brief The random number generator */
139140
RNG rng_;
140141

141-
std::shared_ptr<ompl::geometric::RRTConnect> init_planner;
142142
std::shared_ptr<ompl::geometric::AOXRRTConnect> aox_planner;
143143

144144
/** \brief Free the memory allocated by this planner */
@@ -164,7 +164,6 @@ namespace ompl
164164

165165
double initCost_;
166166
ompl::base::PlannerStatus solve_status;
167-
ompl::base::PlannerStatus aox_solve_status;
168167
};
169168
} // namespace geometric
170169
} // namespace ompl

src/ompl/geometric/planners/rrt/AOXRRTConnect.h

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,26 @@ namespace ompl
108108
setup();
109109
}
110110

111+
/** \brief Check if the inner loop planner met its condition to terminate */
112+
bool internalResetCondition()
113+
{
114+
bool shouldReset = false;
115+
if (tStart_ && tGoal_) {
116+
// Reset if we have met our maximum internal vertices
117+
shouldReset = shouldReset || (tStart_->size() + tGoal_->size() >= maxInternalVertices);
118+
} else {
119+
// If our trees don't exist, we're not in the middle of a search anyways
120+
shouldReset = true;
121+
}
122+
// Reset if we have attempted our maximum internal samples
123+
shouldReset = shouldReset || (sampleAttempts >= maxInternalSamples);
124+
return shouldReset;
125+
}
126+
111127
void setup() override;
112128

129+
void reset(bool solvedProblem);
130+
113131
void setPathCost(double pc);
114132

115133
protected:
@@ -143,8 +161,14 @@ namespace ompl
143161
bool start;
144162
};
145163

146-
/** \brief Compute distance between motions (actually distance between contained states) */
147-
double distanceFunction(const Motion *a, const Motion *b) const
164+
/** \brief Compute euclidian distance between motions */
165+
double euclideanDistanceFunction(const Motion *a, const Motion *b) const
166+
{
167+
return si_->distance(a->state, b->state);
168+
}
169+
170+
/** \brief Compute AOX distance between motions */
171+
double aoxDistanceFunction(const Motion *a, const Motion *b) const
148172
{
149173
auto space_diff = si_->distance(a->state, b->state);
150174
auto cost_diff = a->cost - b->cost;
@@ -163,23 +187,39 @@ namespace ompl
163187
/** \brief State sampler */
164188
base::InformedSamplerPtr sampler_;
165189

190+
std::size_t sampleAttempts{0};
191+
166192
/** \brief The start tree */
167193
TreeData tStart_;
168194

169195
/** \brief The goal tree */
170196
TreeData tGoal_;
171197

172-
/** \brief Maximum allowed cost resampling iterations */
173-
int maxResampleAttempts_{100};
198+
/** \brief Maximum allowed cost resampling iterations before moving on */
199+
long int maxResampleAttempts_{100};
200+
201+
/** \brief Maximum allowed total vertices in trees before the search is restarted */
202+
std::size_t maxInternalVertices{10000};
203+
204+
/** \brief Increment by which maxVertices is increased */
205+
std::size_t maxInternalVerticesIncrement{10000};
206+
207+
/** \brief Maximum samples tried before the search is restarted */
208+
std::size_t maxInternalSamples{10000000};
209+
210+
/** \brief Increment by which maxSamples is increased */
211+
std::size_t maxInternalSamplesIncrement{10000000};
174212

175213
base::State *startState{nullptr};
176214
base::State *goalState{nullptr};
177215

178216
/** \brief Best cost found so far by algorithm */
179-
base::Cost bestCost_{std::numeric_limits<double>::quiet_NaN()};
217+
base::Cost bestCost_{std::numeric_limits<double>::infinity()};
180218

219+
/** \brief Path found by the algorithm */
181220
base::PathPtr foundPath{nullptr};
182221

222+
/** \brief Outer loop termination condition for AORRTC */
183223
base::PlannerTerminationCondition _ptc{nullptr};
184224

185225
/** \brief Objective we're optimizing */

src/ompl/geometric/planners/rrt/src/AORRTC.cpp

Lines changed: 64 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -68,43 +68,41 @@ ompl::base::Cost ompl::geometric::AORRTC::bestCost() const
6868
void ompl::geometric::AORRTC::setup()
6969
{
7070
Planner::setup();
71-
init_planner = std::make_shared<ompl::geometric::RRTConnect>(si_);
72-
init_planner->setProblemDefinition(pdef_);
73-
init_planner->setName("Initial RRTConnect");
74-
init_planner->setRange(getRange());
75-
init_planner->setIntermediateStates(getIntermediateStates());
7671

7772
aox_planner = std::make_shared<ompl::geometric::AOXRRTConnect>(si_);
7873
aox_planner->setProblemDefinition(pdef_);
7974
aox_planner->setName("AOXRRTConnect");
8075
aox_planner->setRange(getRange());
8176
aox_planner->setIntermediateStates(getIntermediateStates());
8277

83-
init_planner->setup();
8478
aox_planner->setup();
8579

8680
psk_ = std::make_shared<PathSimplifier>(si_);
87-
8881
initCost_ = std::numeric_limits<double>::infinity();
82+
solve_status = base::PlannerStatus::TIMEOUT;
83+
}
8984

85+
// Reset our planner to begin a new search
86+
void ompl::geometric::AORRTC::reset(bool solvedProblem)
87+
{
88+
aox_planner->clearQuery();
89+
aox_planner->setFoundPath(nullptr);
90+
aox_planner->reset(solvedProblem);
9091
solve_status = base::PlannerStatus::TIMEOUT;
91-
aox_solve_status = base::PlannerStatus::TIMEOUT;
9292
}
9393

9494
void ompl::geometric::AORRTC::setProblemDefinition(const base::ProblemDefinitionPtr &pdef)
9595
{
9696
pdef_ = pdef;
9797

98-
if (init_planner != nullptr)
98+
if (aox_planner != nullptr)
9999
{
100-
init_planner->setProblemDefinition(pdef);
101100
aox_planner->setProblemDefinition(pdef);
102101
}
103102
}
104103

105104
void ompl::geometric::AORRTC::freeMemory()
106105
{
107-
init_planner->clear();
108106
aox_planner->clear();
109107
}
110108

@@ -126,21 +124,21 @@ ompl::base::PlannerStatus ompl::geometric::AORRTC::solve(const base::PlannerTerm
126124
{
127125
do
128126
{
127+
// If we already have a solution (and therefore a reasonable cost range)
129128
if (pdef_->hasExactSolution())
130129
{
130+
// Inform the planner about our cost bound
131131
aox_planner->setPathCost(bestCost_.value());
132+
133+
// Try to solve the planning problem
134+
solve_status = aox_planner->solve(ptc);
132135

133-
OMPL_INFORM("%s: Best cost is %.5f", getName().c_str(), bestCost_);
134-
aox_solve_status = aox_planner->solve(ptc);
135-
136-
if (aox_solve_status != base::PlannerStatus::EXACT_SOLUTION)
137-
{
138-
OMPL_INFORM("%s: Restarted before finding a solution", getName().c_str());
139-
}
140-
else
136+
if (solve_status == base::PlannerStatus::EXACT_SOLUTION)
141137
{
138+
// If we found a solution, extract it and update our path
142139
const base::PathPtr path = aox_planner->getFoundPath();
143140

141+
// Update our best path if our new path is better
144142
if (path->length() < bestCost_.value())
145143
{
146144
bestPath_ = path;
@@ -149,34 +147,29 @@ ompl::base::PlannerStatus ompl::geometric::AORRTC::solve(const base::PlannerTerm
149147
pdef_->addSolutionPath(bestPath_, false, 0.0, getName());
150148
}
151149

150+
// Simplify our solution
152151
simplifySolution(path, ptc);
153-
OMPL_INFORM("%s: AOX search simplified to cost %.5f", getName().c_str(), path->length());
154152

153+
// Again, update our best path if our new (simplified) path is better
155154
if (path->length() < bestCost_.value())
156155
{
156+
OMPL_INFORM("%s: AOX search simplified to cost %.5f", getName().c_str(), path->length());
157+
157158
bestPath_ = path;
158159
bestCost_ = ompl::base::Cost(path->length());
159160

160161
pdef_->addSolutionPath(bestPath_, false, 0.0, getName());
161162
}
162-
163-
aox_planner->clearQuery();
164-
aox_planner->setProblemDefinition(pdef_);
165-
}
166-
167-
aox_planner->setFoundPath(nullptr);
168-
aox_solve_status = base::PlannerStatus::TIMEOUT;
163+
}
169164
}
170165

166+
// Find an initial solution
171167
else
172168
{
173-
solve_status = init_planner->solve(ptc);
169+
solve_status = aox_planner->solve(ptc);
174170

175-
if (solve_status != base::PlannerStatus::EXACT_SOLUTION)
176-
{
177-
OMPL_INFORM("%s: Initial search restarted before finding a solution", getName().c_str());
178-
}
179-
else
171+
// If we found a solution, extract it and update our path
172+
if (solve_status == base::PlannerStatus::EXACT_SOLUTION)
180173
{
181174
initCost_ = pdef_->getSolutionPath()->length();
182175
bestPath_ = pdef_->getSolutionPath();
@@ -192,19 +185,48 @@ ompl::base::PlannerStatus ompl::geometric::AORRTC::solve(const base::PlannerTerm
192185
pdef_->addSolutionPath(bestPath_, false, 0.0, getName());
193186
}
194187
}
188+
189+
// If we ran into errors, exit early
190+
if (solve_status == base::PlannerStatus::UNRECOGNIZED_GOAL_TYPE ||
191+
solve_status == base::PlannerStatus::INVALID_START ||
192+
solve_status == base::PlannerStatus::INVALID_GOAL)
193+
{
194+
return solve_status;
195+
}
196+
197+
// If we found a solution, we can reset our planner
198+
if (solve_status == base::PlannerStatus::EXACT_SOLUTION)
199+
{
200+
reset(true);
201+
}
202+
203+
// If we didn't find a solution on this iteration of solve, reset our planner.
204+
// (PDT visualize calls solve for each iteration of the search,
205+
// so we need to check if our planner actually needs to reset)
206+
else if (aox_planner->internalResetCondition())
207+
{
208+
OMPL_INFORM("%s: Restarted before finding a solution", getName().c_str());
209+
reset(false);
210+
}
211+
212+
// Something has surely gone wrong if you have found a zero-length path
213+
if (bestCost_.value() == 0)
214+
{
215+
OMPL_ERROR("%s: Zero-length path found. May have a common start/goal.", getName().c_str());
216+
return base::PlannerStatus::INVALID_GOAL;
217+
}
195218
} while (!ptc);
196219

197-
return solve_status;
220+
// Now that we're done, return whether or not we timed out
221+
if (pdef_->hasExactSolution())
222+
{
223+
return base::PlannerStatus::EXACT_SOLUTION;
224+
} else {
225+
return base::PlannerStatus::TIMEOUT;
226+
}
198227
}
199228

200229
void ompl::geometric::AORRTC::getPlannerData(base::PlannerData &data) const
201230
{
202-
if (pdef_->hasExactSolution())
203-
{
204-
aox_planner->getPlannerData(data);
205-
}
206-
else
207-
{
208-
init_planner->getPlannerData(data);
209-
}
231+
aox_planner->getPlannerData(data);
210232
}

0 commit comments

Comments
 (0)