-
Notifications
You must be signed in to change notification settings - Fork 111
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RSDK-8835 motionplan should support planning both from and to either a pose or a list of possible configurations #4623
base: main
Are you sure you want to change the base?
Conversation
… goals, which can be configurations or sets of poses.
…-planning-both-from-and-to-either-a-pose-or-a-list-of-possible-configurations
} | ||
|
||
// TODO: This should replace Frame and Goal | ||
req.allGoals = map[string]*referenceframe.PoseInFrame{req.Frame.Name(): req.Goal} | ||
for i, goalState := range req.Goals { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO: comment this better
"go.viam.com/rdk/referenceframe" | ||
) | ||
|
||
// fixedStepInterpolation returns inputs at qstep distance along the path from start to target |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These functions are not new, they are merely moved over from rrt.go.
motionplan/planManager.go
Outdated
maps *rrtMaps, | ||
) (map[string][]referenceframe.Input, *resultPromise, error) { | ||
if parPlan, ok := pathPlanner.(rrtParallelPlanner); ok { | ||
// ~ pm.logger.Debug("start planning for ", goal.ToProto()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Re-enable
motionplan/planManager.go
Outdated
if err != nil { | ||
return nil, err | ||
} | ||
// ~ wpOpt.setGoal(to) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Delete
@@ -124,7 +123,6 @@ type plannerOptions struct { | |||
ConstraintHandler | |||
motionChains []*motionChain | |||
goalMetricConstructor func(spatialmath.Pose) ik.StateMetric |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment use of this
@@ -984,7 +984,7 @@ func TestClientStreamDisconnectHandler(t *testing.T) { | |||
t.Helper() | |||
|
|||
client.connected.Store(false) | |||
//nolint:staticcheck // the status API is deprecated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These shouldn't have changed I think...darn linter
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall I like the shape of it. I think we should think a little more about how we want to call these structs which will become the building blocks of this package. If we come up with something coherent I think it will make the mental load of understanding this package lighter to new developers
|
||
// PlanState is a struct which holds both a PathStep and a configuration. This is intended to be used as start or goal states for plans. | ||
// Either field may be nil. | ||
type PlanState struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find the way the names for these objects slightly confusing. Maybe rename to PlanStep
? Or if not rename PathStep
to PathState
? I think I like the latter better. That way we have a Plan & PlanState, Path & PathState, in the future Trajectory & TrajectoryState. I'm open to other ideas on what to actually call them but I think we should try to draw parallels here in our nomenclature, otherwise some of these names are a bit confusing.
utils.PanicCapturingGo(func() { | ||
mp.rrtBackgroundRunner(ctx, seed, &rrtParallelPlannerShared{nil, nil, solutionChan}) | ||
mp.rrtBackgroundRunner(ctx, &rrtParallelPlannerShared{ | ||
initMaps.maps, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[style] this doesnt have to be broken up to multiple lines. Or if you want to do this can you add the field names to the struct instantiation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point; I think I was originally prototyping this with a much longer line, and had to split to read it, then shrunk it later
// Pick a random (first in map) seed node to create the first interp node | ||
for sNode, parent := range rrt.maps.startMap { | ||
if parent == nil { | ||
seed = sNode.Q() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pretty sure you want to be breaking out of this loop here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep
executionState.CurrentPoses(), | ||
poses[len(poses)-1], | ||
&PlanState{poses: executionState.CurrentPoses(), configuration: startingInputs}, | ||
&PlanState{poses: poses[len(poses)-1]}, | ||
startingInputs, | ||
worldState, | ||
nil, | ||
nil, // no pb.Constraints |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as long as youre fixing these comments this should read Constraints
now
} | ||
|
||
// DeserializePlanState turns a serialized PlanState back into a PlanState. | ||
func DeserializePlanState(iface map[string]interface{}) (*PlanState, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have round trip tests for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WIP
referenceframe.PoseInFrameToProtobuf(startPose.(*referenceframe.PoseInFrame)), | ||
request.WorldState.String(), | ||
) | ||
} | ||
opt, err := pm.plannerSetupFromMoveRequest( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The arguments of this function can be cleaned up a little I think. We're passing redundant arguments
return nil, err | ||
|
||
// Log each requested motion | ||
for frame, goal := range goalPoses { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be worth it to make a String
function on PlanRequest
@@ -758,6 +670,122 @@ func (pm *planManager) plannerSetupFromMoveRequest( | |||
return opt, nil | |||
} | |||
|
|||
// generateWaypoints will return the list of atomic waypoints that correspond to a specific goal in a plan request. | |||
func (pm *planManager) generateWaypoints(request *PlanRequest, seedPlan Plan, wpi int) ([]atomicWaypoint, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like a lot of this was moved from above should I do a deeper read of this?
…, more to do on creating motion chains when goal is in frame of itself.
This PR is not quite complete; there are not yet tests for the new behavior. Tests will be added before merge, and bugs turned up by the tests may merit minor changes to the body of code presented here.
This PR is a breaking change to
motionplan
. It introduces a new struct,PlanState
, which may be a PathStep, a configuration, or both.PlanRequest
undergoes the breaking change, removing several public fields and replacing them with new fields which must be PlanStates.The changes here enable an arbitrary number of waypoints to be specified, and the planner will plan to each one in turn. It will do so faster than it would if each one were an individual Plan call.
Additionally, it permits two new interesting pieces of behavior: