Documentation ¶
Overview ¶
Package motion is the service that allows you to plan and execute movements. For more information, see the motion service docs.
Index ¶
- Constants
- Variables
- func MoveArm(ctx context.Context, logger logging.Logger, a arm.Arm, dst spatialmath.Pose) error
- func Named(name string) resource.Name
- func NewRPCServiceServer(coll resource.APIResourceCollection[Service]) interface{}
- func PollHistoryUntilSuccessOrError(ctx context.Context, m Service, interval time.Duration, req PlanHistoryReq) error
- type ExecutionID
- type ListPlanStatusesReq
- type Localizer
- type MotionConfiguration
- type MoveOnGlobeReq
- type MoveOnMapReq
- type MoveReq
- type ObstacleDetectorName
- type PlanHistoryReq
- type PlanID
- type PlanState
- type PlanStatus
- type PlanStatusWithID
- type PlanWithMetadata
- type PlanWithStatus
- type Service
- type StopPlanReq
Constants ¶
const ( // PlanStateUnspecified denotes an the Plan is in an unspecified state. This should never happen. PlanStateUnspecified = iota // PlanStateInProgress denotes an the Plan is in an in progress state. It is a temporary state. PlanStateInProgress // PlanStateStopped denotes an the Plan is in a stopped state. It is a terminal state. PlanStateStopped // PlanStateSucceeded denotes an the Plan is in a succeeded state. It is a terminal state. PlanStateSucceeded // PlanStateFailed denotes an the Plan is in a failed state. It is a terminal state. PlanStateFailed )
const SubtypeName = "motion"
SubtypeName is the name of the type of service.
Variables ¶
var API = resource.APINamespaceRDK.WithServiceType(SubtypeName)
API is a variable that identifies the motion service resource API.
var SLAMOrientationAdjustment = spatialmath.NewPoseFromOrientation(&spatialmath.OrientationVectorDegrees{OZ: 1, Theta: -90})
SLAMOrientationAdjustment is needed because a SLAM map pose has orientation of OZ=1, Theta=0 when the rover is intended to be pointing at the +X axis of the SLAM map. However, for a rover's relative planning frame, driving forwards increments +Y. Thus we must adjust where the rover thinks it is.
var TerminalStateSet = map[PlanState]struct{}{ PlanStateStopped: {}, PlanStateSucceeded: {}, PlanStateFailed: {}, }
TerminalStateSet is a set that defines the PlanState values which are terminal i.e. which represent the end of a plan.
Functions ¶
func MoveArm ¶ added in v0.34.0
MoveArm is a helper function to abstract away movement for general arms.
func Named ¶ added in v0.0.8
Named is a helper for getting the named motion service's typed resource name.
func NewRPCServiceServer ¶ added in v0.2.36
func NewRPCServiceServer(coll resource.APIResourceCollection[Service]) interface{}
NewRPCServiceServer constructs a motion gRPC service server. It is intentionally untyped to prevent use outside of tests.
func PollHistoryUntilSuccessOrError ¶ added in v0.17.0
func PollHistoryUntilSuccessOrError( ctx context.Context, m Service, interval time.Duration, req PlanHistoryReq, ) error
PollHistoryUntilSuccessOrError polls `PlanHistory()` with `req` every `interval` until a terminal state is reached. An error is returned if the terminal state is Failed, Stopped or an invalid state or if the context has an error. nil is returned if the terminal state is Succeeded.
Types ¶
type ExecutionID ¶ added in v0.15.0
ExecutionID uniquely identifies an execution.
type ListPlanStatusesReq ¶ added in v0.11.0
type ListPlanStatusesReq struct { // If true then only active plans will be returned. OnlyActivePlans bool Extra map[string]interface{} }
ListPlanStatusesReq describes the request to ListPlanStatuses().
type Localizer ¶ added in v0.3.0
type Localizer interface {
CurrentPosition(context.Context) (*referenceframe.PoseInFrame, error)
}
Localizer is an interface which both slam and movementsensor can satisfy when wrapped respectively.
func NewMovementSensorLocalizer ¶ added in v0.6.0
func NewMovementSensorLocalizer(ms movementsensor.MovementSensor, origin *geo.Point, calibration spatialmath.Pose) Localizer
NewMovementSensorLocalizer creates a Localizer from a MovementSensor. An origin point must be specified and the localizer will return Poses relative to this point. A calibration pose can also be specified, which will adjust the location after it is calculated relative to the origin.
func NewSLAMLocalizer ¶ added in v0.6.0
NewSLAMLocalizer creates a new Localizer that relies on a slam service to report Pose.
func TwoDLocalizer ¶ added in v0.21.0
TwoDLocalizer will check the orientation of the pose of a localizer, and ensure that it is normal to the XY plane. If it is not, it will be altered such that it is (accounting for e.g. an ourdoor base with one wheel on a rock). If the orientation is such that the base is pointed directly up or down (or is upside-down), an error is returned. The alteration to ensure normality to the plane is done by transforming the (0,1,0) vector by the provided orientation, and then using atan2 on the new x and y values to determine the vector of travel that would be followed.
type MotionConfiguration ¶ added in v0.7.3
type MotionConfiguration struct { ObstacleDetectors []ObstacleDetectorName PositionPollingFreqHz *float64 ObstaclePollingFreqHz *float64 PlanDeviationMM float64 LinearMPerSec float64 AngularDegsPerSec float64 }
MotionConfiguration specifies how to configure a call.
type MoveOnGlobeReq ¶ added in v0.11.0
type MoveOnGlobeReq struct { // ComponentName of the component to move ComponentName resource.Name // Goal destination the component should be moved to Destination *geo.Point // Heading the component should have a when it reaches the goal. // Range [0-360] Left Hand Rule (N: 0, E: 90, S: 180, W: 270) Heading float64 // Name of the momement sensor which can be used to derive Position & Heading MovementSensorName resource.Name // Static obstacles that should be navigated around Obstacles []*spatialmath.GeoGeometry // Set of bounds which the robot must remain within while navigating BoundingRegions []*spatialmath.GeoGeometry // Optional motion configuration MotionCfg *MotionConfiguration Extra map[string]interface{} }
MoveOnGlobeReq describes the request to the MoveOnGlobe interface method.
func (MoveOnGlobeReq) String ¶ added in v0.16.0
func (r MoveOnGlobeReq) String() string
type MoveOnMapReq ¶ added in v0.15.0
type MoveOnMapReq struct { ComponentName resource.Name Destination spatialmath.Pose SlamName resource.Name MotionCfg *MotionConfiguration Obstacles []spatialmath.Geometry Extra map[string]interface{} }
MoveOnMapReq describes a request to MoveOnMap.
func (MoveOnMapReq) String ¶ added in v0.20.0
func (r MoveOnMapReq) String() string
type MoveReq ¶ added in v0.43.0
type MoveReq struct { // ComponentName of the component to move ComponentName resource.Name // Goal destination the component should be moved to Destination *referenceframe.PoseInFrame // The external environment to be considered for the duration of the move WorldState *referenceframe.WorldState // Constraints which need to be satisfied during the movement Constraints *motionplan.Constraints Extra map[string]interface{} }
MoveReq describes the request to the Move interface method.
func MoveReqFromProto ¶ added in v0.43.0
func MoveReqFromProto(req *pb.MoveRequest) (MoveReq, error)
MoveReqFromProto converts a pb.MoveRequest to a MoveReq struct.
type ObstacleDetectorName ¶ added in v0.11.0
ObstacleDetectorName pairs a vision service name with a camera name.
type PlanHistoryReq ¶ added in v0.11.0
type PlanHistoryReq struct { // ComponentName the returned plans should be associated with. ComponentName resource.Name // When true, only the most recent plan will be returned which matches the ComponentName & ExecutionID if one was provided. LastPlanOnly bool // Optional, when not uuid.Nil it specifies the ExecutionID of the plans that should be returned. // Can be used to query plans from executions before the most recent one. ExecutionID ExecutionID Extra map[string]interface{} }
PlanHistoryReq describes the request to PlanHistory().
type PlanStatus ¶ added in v0.11.0
PlanStatus describes the state of a given plan at a point in time allong with an optional reason why the PlanStatus transitioned to that state.
func (PlanStatus) ToProto ¶ added in v0.11.0
func (ps PlanStatus) ToProto() *pb.PlanStatus
ToProto converts a PlanStatus to a *pb.PlanStatus.
type PlanStatusWithID ¶ added in v0.11.0
type PlanStatusWithID struct { PlanID PlanID ComponentName resource.Name ExecutionID ExecutionID Status PlanStatus }
PlanStatusWithID describes the state of a given plan at a point in time plus the PlanId, ComponentName and ExecutionID the status is associated with.
func (PlanStatusWithID) ToProto ¶ added in v0.11.0
func (ps PlanStatusWithID) ToProto() *pb.PlanStatusWithID
ToProto converts a PlanStatusWithID to a *pb.PlanStatusWithID.
type PlanWithMetadata ¶ added in v0.21.0
type PlanWithMetadata struct { // Unique ID of the plan ID PlanID // Name of the component the plan is planning for ComponentName resource.Name // Unique ID of the execution ExecutionID ExecutionID // The motionplan itself motionplan.Plan // The GPS point to anchor visualized plans at AnchorGeoPose *spatialmath.GeoPose }
PlanWithMetadata represents a motion plan with additional metadata used by the motion service.
func (PlanWithMetadata) Renderable ¶ added in v0.21.0
func (p PlanWithMetadata) Renderable() PlanWithMetadata
Renderable returns a copy of the struct substituting its Plan for a GeoPlan consisting of smuggled global coordinates This will only be done if the AnchorGeoPose field is non-nil, otherwise the original struct will be returned.
func (PlanWithMetadata) ToProto ¶ added in v0.21.0
func (p PlanWithMetadata) ToProto() *pb.Plan
ToProto converts a Plan to a *pb.Plan.
type PlanWithStatus ¶ added in v0.11.0
type PlanWithStatus struct { Plan PlanWithMetadata StatusHistory []PlanStatus }
PlanWithStatus contains a plan, its current status, and all state changes that came prior sorted by ascending timestamp.
func (PlanWithStatus) ToProto ¶ added in v0.11.0
func (pws PlanWithStatus) ToProto() *pb.PlanWithStatus
ToProto converts a PlanWithStatus to a *pb.PlanWithStatus.
type Service ¶
type Service interface { resource.Resource // Move is the primary method to move multiple components or any object to a specified location. // Given a destination pose and a component, Move constructs a kinematic chain from goal to destination, // solves it while adhering to constraints, and executes the movement to avoid collisions with the machine itself // and other known objects. The above arguments are all grouped together in the MoveReq struct. Move(ctx context.Context, req MoveReq) (bool, error) // MoveOnMap moves a base component to a destination Pose on a SLAM map and returns a unique ExecutionID. // If the machine is already within PlanDeviationM of the goal, an error is returned. // Monitor progress with `GetPlan()` and `ListPlanStatuses()`, and check the machine's position via the SLAM service. // Designed for autonomous indoor navigation of rover bases. MoveOnMap(ctx context.Context, req MoveOnMapReq) (ExecutionID, error) // MoveOnGlobe moves a base component to a destination GPS point(latitude, longitude and returns a unique ExecutionID. // If the machine is already within PlanDeviationM of the goal, an error is returned. // This non-blocking method uses a movement sensor to verify the location of the base. // You can monitor progress with `GetPlan()` and `ListPlanStatuses()`. Designed for autonomous GPS navigation of rover bases. MoveOnGlobe(ctx context.Context, req MoveOnGlobeReq) (ExecutionID, error) // GetPose returns the location and orientation of a component within a frame system. // It returns a `PoseInFrame` describing the pose of the specified component relative to the specified destination frame. // The `supplemental_transforms` argument can be used to augment the machine's existing frame system with additional frames. GetPose( ctx context.Context, componentName resource.Name, destinationFrame string, supplementalTransforms []*referenceframe.LinkInFrame, extra map[string]interface{}, ) (*referenceframe.PoseInFrame, error) // StopPlan stops a base component being moved by an in progress `MoveOnGlobe()` or `MoveOnMap()` call. StopPlan(ctx context.Context, req StopPlanReq) error // ListPlanStatuses returns the statuses of plans created by `MoveOnGlobe()` or `MoveOnMap()` since the motion service initialized. // It includes plans that are in progress or have changed state in the last 24 hours. // All repeated fields are in chronological order. ListPlanStatuses(ctx context.Context, req ListPlanStatusesReq) ([]PlanStatusWithID, error) // PlanHistory returns the plan history of the most recent `MoveOnGlobe()` or `MoveOnMap()` call by default. // The history for earlier executions can be requested by providing an ExecutionID. // It returns a result if the execution is active or has changed state in the last 24 hours and the machine has not reinitialized. // Plans never change; replans always create new plans and replans share the ExecutionID of the previously executing plan. PlanHistory(ctx context.Context, req PlanHistoryReq) ([]PlanWithStatus, error) }
A Service controls the flow of moving components. For more information, see the motion service docs.
Move example:
motionService, err := motion.FromRobot(machine, "builtin") // Assumes a gripper configured with name "my_gripper" on the machine gripperName := gripper.Named("my_gripper") // Define a destination Pose destination := referenceframe.NewPoseInFrame("world", spatialmath.NewPoseFromPoint(r3.Vector{X: 0.1, Y: 0.0, Z: 0.0})) // Create obstacles boxPose := spatialmath.NewPoseFromPoint(r3.Vector{X: 0.0, Y: 0.0, Z: 0.0}) boxDims := r3.Vector{X: 0.2, Y: 0.2, Z: 0.2} // 20cm x 20cm x 20cm box obstacle, _ := spatialmath.NewBox(boxPose, boxDims, "obstacle_1") geometryInFrame := referenceframe.NewGeometriesInFrame("base", []spatialmath.Geometry{obstacle}) obstacles := []*referenceframe.GeometriesInFrame{geometryInFrame} // Create transforms transform := referenceframe.NewLinkInFrame("gripper", spatialmath.NewPoseFromPoint(r3.Vector{X: 0.1, Y: 0.0, Z: 0.1}), "transform_1", nil ) transforms := []*referenceframe.LinkInFrame{transform} // Create WorldState worldState, err := referenceframe.NewWorldState(obstacles, transforms) // Move gripper component moved, err := motionService.Move(context.Background(), motion.MoveReq{ ComponentName: gripperName, Destination: destination, WorldState: WorldState })
MoveOnMap example:
// Assumes a base with the name "my_base" is configured on the machine myBaseResourceName := base.Named("my_base") mySLAMServiceResourceName := slam.Named("my_slam_service") // Define a destination Pose myPose := spatialmath.NewPoseFromPoint(r3.Vector{Y: 10}) // Move the base component to the destination pose executionID, err := motionService.MoveOnMap(context.Background(), motion.MoveOnMapReq{ ComponentName: myBaseResourceName, Destination: myPose, SlamName: mySLAMServiceResourceName, }) // MoveOnMap is a non-blocking method and this line can optionally be added to block until the movement is done err = motion.PollHistoryUntilSuccessOrError( context.Background(), motionService, time.Duration(time.Second), motion.PlanHistoryReq{ ComponentName: myBaseResourceName, ExecutionID: executionID, }, )
MoveOnGlobe example:
// Assumes a base with the name "myBase" is configured on the machine // Get the resource names of the base and movement sensor myBaseResourceName := base.Named("myBase") myMvmntSensorResourceName := movementsensor.Named("my_movement_sensor") // Define a destination Point at the GPS coordinates [0, 0] myDestination := geo.NewPoint(0, 0) // Move the base component to the designated geographic location, as reported by the movement sensor executionID, err := motionService.MoveOnGlobe(context.Background(), motion.MoveOnGlobeReq{ ComponentName: myBaseResourceName, Destination: myDestination, MovementSensorName: myMvmntSensorResourceName, }) // Assumes there is an active MoveOnMap() or MoveonGlobe() in progress for myBase // MoveOnGlobe is a non-blocking method and this line can optionally be added to block until the movement is done err = motion.PollHistoryUntilSuccessOrError( context.Background(), motionService, time.Duration(time.Second), motion.PlanHistoryReq{ ComponentName: myBaseResourceName, ExecutionID: executionID, }, )
GetPose example:
// Insert code to connect to your machine. // (see CONNECT tab of your machine's page in the Viam app) // Assumes a gripper configured with name "my_gripper" on the machine gripperName := gripper.Named("my_gripper") // Access the motion service motionService, err := motion.FromRobot(machine, "builtin") if err != nil { logger.Fatal(err) } myArmMotionPose, err := motionService.GetPose(context.Background(), my_gripper, referenceframe.World, nil, nil) if err != nil { logger.Fatal(err) } logger.Info("Position of myArm from the motion service:", myArmMotionPose.Pose().Point()) logger.Info("Orientation of myArm from the motion service:", myArmMotionPose.Pose().Orientation())
StopPlan example:
motionService, err := motion.FromRobot(machine, "builtin") myBaseResourceName := base.Named("myBase") myMvmntSensorResourceName := movement_sensor.Named("my_movement_sensor") myDestination := geo.NewPoint(0, 0) // Assuming a `MoveOnGlobe()`` started the execution // Stop the base component which was instructed to move by `MoveOnGlobe()` or `MoveOnMap()` err := motionService.StopPlan(context.Background(), motion.StopPlanReq{ ComponentName: s.req.ComponentName, })
ListPlanStatuses example:
motionService, err := motion.FromRobot(machine, "builtin") // Get the plan(s) of the base component's most recent execution i.e. `MoveOnGlobe()` or `MoveOnMap()` call. planStatuses, err := motionService.ListPlanStatuses(context.Background(), motion.ListPlanStatusesReq{})
PlanHistory example:
// Get the resource name of the base component myBaseResourceName := base.Named("myBase") // Get the plan history of the base component's most recent execution (e.g., MoveOnGlobe or MoveOnMap call) planHistory, err := motionService.PlanHistory(context.Background(), motion.PlanHistoryReq{ ComponentName: myBaseResourceName, })
func FromDependencies ¶ added in v0.2.47
func FromDependencies(deps resource.Dependencies, name string) (Service, error)
FromDependencies is a helper for getting the named motion service from a collection of dependencies.
type StopPlanReq ¶ added in v0.11.0
type StopPlanReq struct { // ComponentName of the plan which should be stopped ComponentName resource.Name Extra map[string]interface{} }
StopPlanReq describes the request to StopPlan().
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package builtin implements a motion service.
|
Package builtin implements a motion service. |
state
Package state provides apis for motion builtin plan executions and manages the state of those executions
|
Package state provides apis for motion builtin plan executions and manages the state of those executions |
Package register registers all relevant motion services and API specific functions.
|
Package register registers all relevant motion services and API specific functions. |