@@ -19,13 +19,10 @@ import (
1919
2020const (
2121 defaultOptimalityMultiple = 2.0
22- defaultFallbackTimeout = 1.5
2322 defaultTPspaceOrientationScale = 500.
2423)
2524
26- // planManager is intended to be the single entry point to motion planners, wrapping all others, dealing with fallbacks, etc.
27- // Intended information flow should be:
28- // motionplan.PlanMotion() -> SolvableFrameSystem.SolveWaypointsWithOptions() -> planManager.planSingleWaypoint().
25+ // planManager is intended to be the single entry point to motion planners.
2926type planManager struct {
3027 * planner // TODO: This should probably be removed
3128 // We store the request because we want to be able to inspect the original state of the plan
@@ -280,8 +277,7 @@ func (pm *planManager) planSingleAtomicWaypoint(
280277 return seed , & resultPromise {steps : planReturn .steps }, nil
281278 }
282279 } else {
283- // This ctx is used exclusively for the running of the new planner and timing it out. It may be different from the main `ctx`
284- // timeout due to planner fallbacks.
280+ // This ctx is used exclusively for the running of the new planner and timing it out.
285281 plannerctx , cancel := context .WithTimeout (ctx , time .Duration (wp .mp .opt ().Timeout * float64 (time .Second )))
286282 defer cancel ()
287283 plan , err := wp .mp .plan (plannerctx , wp .startState , wp .goalState )
@@ -297,8 +293,7 @@ func (pm *planManager) planSingleAtomicWaypoint(
297293 }
298294}
299295
300- // planParallelRRTMotion will handle planning a single atomic waypoint using a parallel-enabled RRT solver. It will handle fallbacks
301- // as necessary.
296+ // planParallelRRTMotion will handle planning a single atomic waypoint using a parallel-enabled RRT solver.
302297func (pm * planManager ) planParallelRRTMotion (
303298 ctx context.Context ,
304299 wp atomicWaypoint ,
@@ -308,7 +303,6 @@ func (pm *planManager) planParallelRRTMotion(
308303) {
309304 pathPlanner := wp .mp .(rrtParallelPlanner )
310305 var rrtBackground sync.WaitGroup
311- var err error
312306 if maps == nil {
313307 solutionChan <- & rrtSolution {err : errors .New ("nil maps" )}
314308 return
@@ -326,8 +320,7 @@ func (pm *planManager) planParallelRRTMotion(
326320 }
327321 }
328322
329- // This ctx is used exclusively for the running of the new planner and timing it out. It may be different from the main `ctx` timeout
330- // due to planner fallbacks.
323+ // This ctx is used exclusively for the running of the new planner and timing it out.
331324 plannerctx , cancel := context .WithTimeout (ctx , time .Duration (wp .mp .opt ().Timeout * float64 (time .Second )))
332325 defer cancel ()
333326
@@ -340,7 +333,7 @@ func (pm *planManager) planParallelRRTMotion(
340333 pathPlanner .rrtBackgroundRunner (plannerctx , & rrtParallelPlannerShared {maps , endpointPreview , plannerChan })
341334 })
342335
343- // Wait for results from the planner. This will also handle calling the fallback if needed, and will ultimately return the best path
336+ // Wait for results from the planner.
344337 select {
345338 case <- ctx .Done ():
346339 // Error will be caught by monitoring loop
@@ -353,85 +346,15 @@ func (pm *planManager) planParallelRRTMotion(
353346 select {
354347 case finalSteps := <- plannerChan :
355348 // We didn't get a solution preview (possible error), so we get and process the full step set and error.
356-
357- mapSeed := finalSteps .maps
358-
359- // Create fallback planner
360- var fallbackPlanner motionPlanner
361- if pathPlanner .opt ().Fallback != nil {
362- //nolint: gosec
363- fallbackPlanner , err = newMotionPlanner (
364- pm .fs ,
365- rand .New (rand .NewSource (int64 (pm .randseed .Int ()))),
366- pm .logger ,
367- pathPlanner .opt ().Fallback ,
368- pm .ConstraintHandler ,
369- pm .motionChains ,
370- )
371- if err != nil {
372- fallbackPlanner = nil
373- }
374- }
375-
376- // If there was no error, check path quality. If sufficiently good, move on.
377- // If there *was* an error, then either the fallback will not error and will replace it, or the error will be returned
378- if finalSteps .err == nil {
379- if fallbackPlanner != nil {
380- if ok , score := pm .goodPlan (finalSteps ); ok {
381- pm .logger .CDebugf (ctx , "got path with score %f, close enough to optimal %f" , score , maps .optNode .Cost ())
382- fallbackPlanner = nil
383- } else {
384- pm .logger .CDebugf (ctx , "path with score %f not close enough to optimal %f, falling back" , score , maps .optNode .Cost ())
385-
386- // If we have a connected but bad path, we recreate new IK solutions and start from scratch
387- // rather than seeding with a completed, known-bad tree
388- mapSeed = nil
389- }
390- }
391- }
392-
393- // Start smoothing before initializing the fallback plan. This allows both to run simultaneously.
394349 smoothChan := make (chan []node , 1 )
395350 rrtBackground .Add (1 )
396351 utils .PanicCapturingGo (func () {
397352 defer rrtBackground .Done ()
398353 smoothChan <- pathPlanner .smoothPath (ctx , finalSteps .steps )
399354 })
400- var alternateFuture * resultPromise
401-
402- // Run fallback only if we don't have a very good path
403- if fallbackPlanner != nil {
404- fallbackWP := wp
405- fallbackWP .mp = fallbackPlanner
406- _ , alternateFuture , err = pm .planSingleAtomicWaypoint (ctx , fallbackWP , mapSeed )
407- if err != nil {
408- alternateFuture = nil
409- }
410- }
411355
412356 // Receive the newly smoothed path from our original solve, and score it
413357 finalSteps .steps = <- smoothChan
414- score := math .Inf (1 )
415-
416- if finalSteps .steps != nil {
417- score = nodesToTrajectory (finalSteps .steps ).EvaluateCost (wp .mp .getScoringFunction ())
418- }
419-
420- // If we ran a fallback, retrieve the result and compare to the smoothed path
421- if alternateFuture != nil {
422- alternate , err := alternateFuture .result ()
423- if err == nil {
424- // If the fallback successfully found a path, check if it is better than our smoothed previous path.
425- // The fallback should emerge pre-smoothed, so that should be a non-issue
426- altCost := nodesToTrajectory (alternate ).EvaluateCost (wp .mp .getScoringFunction ())
427- if altCost < score {
428- pm .logger .CDebugf (ctx , "replacing path with score %f with better score %f" , score , altCost )
429- finalSteps = & rrtSolution {steps : alternate }
430- } else {
431- pm .logger .CDebugf (ctx , "fallback path with score %f worse than original score %f; using original" , altCost , score )
432- }
433- }
434- }
435358
436359 solutionChan <- finalSteps
437360 return
@@ -624,22 +547,6 @@ func (pm *planManager) generateWaypoints(seedPlan motionplan.Plan, wpi int) ([]a
624547 return waypoints , nil
625548}
626549
627- // check whether the solution is within some amount of the optimal.
628- func (pm * planManager ) goodPlan (pr * rrtSolution ) (bool , float64 ) {
629- solutionCost := math .Inf (1 )
630- if pr .steps != nil {
631- if pr .maps .optNode .Cost () <= 0 {
632- return true , solutionCost
633- }
634- solutionCost = nodesToTrajectory (pr .steps ).EvaluateCost (pm .scoringFunction )
635- if solutionCost < pr .maps .optNode .Cost ()* defaultOptimalityMultiple {
636- return true , solutionCost
637- }
638- }
639-
640- return false , solutionCost
641- }
642-
643550func (pm * planManager ) planToRRTGoalMap (plan motionplan.Plan , goal atomicWaypoint ) (* rrtMaps , error ) {
644551 traj := plan .Trajectory ()
645552 path := plan .Path ()
0 commit comments