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 Named(name string) resource.Name
- func NewRPCServiceServer(coll resource.APIResourceGetter[Service], logger logging.Logger) 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
- func FromDependencies(deps resource.Dependencies, name string) (Service, error)deprecated
- func FromProvider(provider resource.Provider, name string) (Service, error)
- func FromRobot(r robot.Robot, name string) (Service, error)deprecated
- func NewClientFromConn(ctx context.Context, conn rpc.ClientConn, remoteName string, ...) (Service, error)
- 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 ErrEmptyComponentName = errors.New("component name cannot be empty")
ErrEmptyComponentName is returned when a component name is empty.
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 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.APIResourceGetter[Service], logger logging.Logger) 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 string
// 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 string
// 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 string
Destination spatialmath.Pose
SlamName string
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 string
// 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 string
// 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 string
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 string
// 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.
// deprecated, use framesystem.Servce.GetPose
GetPose(
ctx context.Context,
componentName string,
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.FromProvider(machine, "builtin")
// Assumes a gripper configured with name "my_gripper" on the machine
gripperName := "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
})
For more information, see the Move method docs.
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,
},
)
For more information, see the MoveOnMap method docs.
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,
},
)
For more information, see the MoveOnGlobe method docs.
StopPlan example:
motionService, err := motion.FromProvider(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,
})
For more information, see the StopPlan method docs.
ListPlanStatuses example:
motionService, err := motion.FromProvider(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{})
For more information, see the ListPlanStatuses method docs.
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,
})
For more information, see the PlanHistory method docs.
func FromDependencies
deprecated
added in
v0.2.47
func FromDependencies(deps resource.Dependencies, name string) (Service, error)
Deprecated: FromDependencies is a helper for getting the named motion service from a collection of dependencies. Use FromProvider instead.
func FromProvider ¶ added in v0.98.0
FromProvider is a helper for getting the named Motion service from a resource Provider (collection of Dependencies or a Robot).
type StopPlanReq ¶ added in v0.11.0
type StopPlanReq struct {
// ComponentName of the plan which should be stopped
ComponentName string
Extra map[string]interface{}
}
StopPlanReq describes the request to StopPlan().