Monitor and Control Plan Execution

You need to monitor whether a motion plan is still executing, check if it succeeded or failed, or cancel it mid-execution.

Important limitation

The builtin motion service does not support GetPlan, ListPlanStatuses, or StopPlan. These methods return “not supported” errors. They are only available from motion service implementations that support MoveOnMap or MoveOnGlobe (typically provided by modules or the navigation service).

If you are using the builtin motion service with Move() for arms and gantries, the Move() call blocks until the motion completes or fails. You do not need to poll for status.

Methods (when supported)

GetPlan

Retrieves the plan being executed or most recently executed for a component.

from viam.services.motion import MotionClient

motion_service = MotionClient.from_robot(machine, "my-motion-service")

response = await motion_service.get_plan(
    component_name="my-base",
)
plan_status = response.current_plan_with_status.status
print(f"Plan state: {plan_status.state}")
response, err := motionService.PlanHistory(ctx, motion.PlanHistoryReq{
    ComponentName: "my-base",
})
if err != nil {
    logger.Fatal(err)
}
fmt.Printf("Plan state: %v\n", response[0].StatusHistory[0].State)

ListPlanStatuses

Lists all active and recently completed plans.

statuses = await motion_service.list_plan_statuses()
for s in statuses:
    print(f"Component: {s.component_name}, "
          f"State: {s.status.state}")
statuses, err := motionService.ListPlanStatuses(ctx, motion.ListPlanStatusesReq{})
if err != nil {
    logger.Fatal(err)
}
for _, s := range statuses {
    fmt.Printf("Component: %s, State: %v\n", s.ComponentName, s.Status.State)
}

Plan states:

StateMeaning
IN_PROGRESSPlan is currently executing.
STOPPEDPlan was stopped by a StopPlan call.
SUCCEEDEDPlan completed successfully.
FAILEDPlan failed during execution.

StopPlan

Cancels an executing plan for a component.

await motion_service.stop_plan(
    component_name="my-base",
)
print("Plan stopped")
err = motionService.StopPlan(ctx, motion.StopPlanReq{
    ComponentName: "my-base",
})
if err != nil {
    logger.Fatal(err)
}
fmt.Println("Plan stopped")

For builtin Move() calls

Since Move() blocks, handle errors directly:

try:
    await motion_service.move(
        component_name="my-arm",
        destination=destination,
        world_state=world_state
    )
    print("Motion succeeded")
except Exception as e:
    print(f"Motion failed: {e}")
_, err = motionService.Move(ctx, motion.MoveReq{
    ComponentName: "my-arm",
    Destination:   destination,
    WorldState:    worldState,
})
if err != nil {
    fmt.Printf("Motion failed: %v\n", err)
} else {
    fmt.Println("Motion succeeded")
}

What’s Next