@@ -19,13 +19,10 @@ import (
19
19
20
20
const (
21
21
defaultOptimalityMultiple = 2.0
22
- defaultFallbackTimeout = 1.5
23
22
defaultTPspaceOrientationScale = 500.
24
23
)
25
24
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.
29
26
type planManager struct {
30
27
* planner // TODO: This should probably be removed
31
28
// 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(
280
277
return seed , & resultPromise {steps : planReturn .steps }, nil
281
278
}
282
279
} 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.
285
281
plannerctx , cancel := context .WithTimeout (ctx , time .Duration (wp .mp .opt ().Timeout * float64 (time .Second )))
286
282
defer cancel ()
287
283
plan , err := wp .mp .plan (plannerctx , wp .startState , wp .goalState )
@@ -297,8 +293,7 @@ func (pm *planManager) planSingleAtomicWaypoint(
297
293
}
298
294
}
299
295
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.
302
297
func (pm * planManager ) planParallelRRTMotion (
303
298
ctx context.Context ,
304
299
wp atomicWaypoint ,
@@ -308,7 +303,6 @@ func (pm *planManager) planParallelRRTMotion(
308
303
) {
309
304
pathPlanner := wp .mp .(rrtParallelPlanner )
310
305
var rrtBackground sync.WaitGroup
311
- var err error
312
306
if maps == nil {
313
307
solutionChan <- & rrtSolution {err : errors .New ("nil maps" )}
314
308
return
@@ -326,8 +320,7 @@ func (pm *planManager) planParallelRRTMotion(
326
320
}
327
321
}
328
322
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.
331
324
plannerctx , cancel := context .WithTimeout (ctx , time .Duration (wp .mp .opt ().Timeout * float64 (time .Second )))
332
325
defer cancel ()
333
326
@@ -340,7 +333,7 @@ func (pm *planManager) planParallelRRTMotion(
340
333
pathPlanner .rrtBackgroundRunner (plannerctx , & rrtParallelPlannerShared {maps , endpointPreview , plannerChan })
341
334
})
342
335
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.
344
337
select {
345
338
case <- ctx .Done ():
346
339
// Error will be caught by monitoring loop
@@ -353,85 +346,15 @@ func (pm *planManager) planParallelRRTMotion(
353
346
select {
354
347
case finalSteps := <- plannerChan :
355
348
// 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.
394
349
smoothChan := make (chan []node , 1 )
395
350
rrtBackground .Add (1 )
396
351
utils .PanicCapturingGo (func () {
397
352
defer rrtBackground .Done ()
398
353
smoothChan <- pathPlanner .smoothPath (ctx , finalSteps .steps )
399
354
})
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
- }
411
355
412
356
// Receive the newly smoothed path from our original solve, and score it
413
357
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
- }
435
358
436
359
solutionChan <- finalSteps
437
360
return
@@ -624,22 +547,6 @@ func (pm *planManager) generateWaypoints(seedPlan motionplan.Plan, wpi int) ([]a
624
547
return waypoints , nil
625
548
}
626
549
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
-
643
550
func (pm * planManager ) planToRRTGoalMap (plan motionplan.Plan , goal atomicWaypoint ) (* rrtMaps , error ) {
644
551
traj := plan .Trajectory ()
645
552
path := plan .Path ()
0 commit comments