Skip to content

Commit 02fce30

Browse files
erhdanielbotros
authored andcommitted
remove dead code and duplicative options, add psuedolinear constraint to proto (viamrobotics#5241)
1 parent d81a836 commit 02fce30

17 files changed

+72
-234
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ require (
8181
go.uber.org/atomic v1.11.0
8282
go.uber.org/multierr v1.11.0
8383
go.uber.org/zap v1.27.0
84-
go.viam.com/api v0.1.473
84+
go.viam.com/api v0.1.474
8585
go.viam.com/test v1.2.4
8686
go.viam.com/utils v0.1.164
8787
goji.io v2.0.2+incompatible

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1530,8 +1530,8 @@ go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
15301530
go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY=
15311531
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
15321532
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
1533-
go.viam.com/api v0.1.473 h1:Hy1JybY6b9lqO2WIfniQN6Mj5+1bmibTzsXkuqos41c=
1534-
go.viam.com/api v0.1.473/go.mod h1:p/am76zx8SZ74V/F4rEAYQIpHaaLUwJgY2q3Uw3FIWk=
1533+
go.viam.com/api v0.1.474 h1:PQz7d3PrSzWGl70rTQDW9rCE3TriuQIhn4/KDSaUs0c=
1534+
go.viam.com/api v0.1.474/go.mod h1:p/am76zx8SZ74V/F4rEAYQIpHaaLUwJgY2q3Uw3FIWk=
15351535
go.viam.com/test v1.2.4 h1:JYgZhsuGAQ8sL9jWkziAXN9VJJiKbjoi9BsO33TW3ug=
15361536
go.viam.com/test v1.2.4/go.mod h1:zI2xzosHdqXAJ/kFqcN+OIF78kQuTV2nIhGZ8EzvaJI=
15371537
go.viam.com/utils v0.1.164 h1:EVKu5AuulD2m7V0OQyXb1YBEgvbHd4p/OwHkw8uT25Y=

motionplan/armplanning/constraint.go

Lines changed: 0 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -394,47 +394,6 @@ func NewSlerpOrientationConstraint(start, goal spatial.Pose, tolerance float64)
394394
return validFunc, gradFunc
395395
}
396396

397-
// NewPlaneConstraint is used to define a constraint space for a plane, and will return 1) a constraint
398-
// function which will determine whether a point is on the plane and in a valid orientation, and 2) a distance function
399-
// which will bring a pose into the valid constraint space. The plane normal is assumed to point towards the valid area.
400-
// angle refers to the maximum unit sphere segment length deviation from the ov
401-
// epsilon refers to the closeness to the plane necessary to be a valid pose.
402-
func NewPlaneConstraint(pNorm, pt r3.Vector, writingAngle, epsilon float64) (StateConstraint, motionplan.StateMetric) {
403-
// get the constant value for the plane
404-
pConst := -pt.Dot(pNorm)
405-
406-
// invert the normal to get the valid AOA OV
407-
ov := &spatial.OrientationVector{OX: -pNorm.X, OY: -pNorm.Y, OZ: -pNorm.Z}
408-
ov.Normalize()
409-
410-
dFunc := motionplan.OrientDistToRegion(ov, writingAngle)
411-
412-
// distance from plane to point
413-
planeDist := func(pt r3.Vector) float64 {
414-
return math.Abs(pNorm.Dot(pt) + pConst)
415-
}
416-
417-
// TODO: do we need to care about trajectory here? Probably, but not yet implemented
418-
gradFunc := func(state *motionplan.State) float64 {
419-
pDist := planeDist(state.Position.Point())
420-
oDist := dFunc(state.Position.Orientation())
421-
return pDist*pDist + oDist*oDist
422-
}
423-
424-
validFunc := func(state *motionplan.State) error {
425-
err := resolveStatesToPositions(state)
426-
if err != nil {
427-
return err
428-
}
429-
if gradFunc(state) < epsilon*epsilon {
430-
return nil
431-
}
432-
return errors.New(planarConstraintDescription + " violated")
433-
}
434-
435-
return validFunc, gradFunc
436-
}
437-
438397
// NewLineConstraint is used to define a constraint space for a line, and will return 1) a constraint
439398
// function which will determine whether a point is on the line, and 2) a distance function
440399
// which will bring a pose into the valid constraint space.
@@ -621,26 +580,6 @@ func CreateSlerpOrientationConstraintFS(
621580
return constraintInternal.constraint, constraintInternal.metric, nil
622581
}
623582

624-
// CreateLineConstraintFS will measure the linear distance between the positions of two poses across a frame system,
625-
// and return a constraint that checks whether given positions are within a specified tolerance distance of the shortest
626-
// line segment between their respective positions, as well as a metric which returns the distance to that valid region.
627-
func CreateLineConstraintFS(
628-
fs *referenceframe.FrameSystem,
629-
startCfg referenceframe.FrameSystemInputs,
630-
from, to referenceframe.FrameSystemPoses,
631-
tolerance float64,
632-
) (StateFSConstraint, motionplan.StateFSMetric, error) {
633-
// Need to define a constructor here since NewLineConstraint takes r3.Vectors, not poses
634-
constructor := func(fromPose, toPose spatial.Pose, tolerance float64) (StateConstraint, motionplan.StateMetric) {
635-
return NewLineConstraint(fromPose.Point(), toPose.Point(), tolerance)
636-
}
637-
constraintInternal, err := newFsPathConstraintTol(fs, startCfg, from, to, constructor, tolerance)
638-
if err != nil {
639-
return nil, nil, err
640-
}
641-
return constraintInternal.constraint, constraintInternal.metric, nil
642-
}
643-
644583
// CreateAbsoluteLinearInterpolatingConstraintFS provides a Constraint whose valid manifold allows a specified amount of deviation from the
645584
// shortest straight-line path between the start and the goal. linTol is the allowed linear deviation in mm, orientTol is the allowed
646585
// orientation deviation measured by norm of the R3AA orientation difference to the slerp path between start/goal orientations.

motionplan/armplanning/constraint_handler.go

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -134,17 +134,6 @@ func newConstraintHandler(
134134
handler.AddStateFSConstraint(name, constraint)
135135
}
136136

137-
switch opt.MotionProfile {
138-
case LinearMotionProfile:
139-
constraints.AddLinearConstraint(motionplan.LinearConstraint{opt.LineTolerance, opt.OrientationTolerance})
140-
case PseudolinearMotionProfile:
141-
constraints.AddPseudolinearConstraint(motionplan.PseudolinearConstraint{opt.ToleranceFactor, opt.ToleranceFactor})
142-
case OrientationMotionProfile:
143-
constraints.AddOrientationConstraint(motionplan.OrientationConstraint{opt.OrientationTolerance})
144-
// FreeMotionProfile or PositionOnlyMotionProfile produce no additional constraints.
145-
case FreeMotionProfile, PositionOnlyMotionProfile:
146-
}
147-
148137
hasTopoConstraint, err := handler.addTopoConstraints(fs, seedMap, startPoses, goalPoses, constraints)
149138
if err != nil {
150139
return nil, err

motionplan/armplanning/constraint_test.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,15 @@ func TestLineFollow(t *testing.T) {
151151
from := frame.FrameSystemPoses{markerFrame.Name(): frame.NewPoseInFrame(markerFrame.Name(), p1)}
152152
to := frame.FrameSystemPoses{markerFrame.Name(): frame.NewPoseInFrame(goalFrame.Name(), p2)}
153153

154-
validFunc, gradFunc, err := CreateLineConstraintFS(fs, startCfg, from, to, 0.001)
154+
constructor := func(fromPose, toPose spatial.Pose, tolerance float64) (StateConstraint, motionplan.StateMetric) {
155+
return NewLineConstraint(fromPose.Point(), toPose.Point(), .001)
156+
}
157+
constraintInternal, err := newFsPathConstraintTol(fs, startCfg, from, to, constructor, .001)
155158
test.That(t, err, test.ShouldBeNil)
156159

160+
validFunc := constraintInternal.constraint
161+
gradFunc := constraintInternal.metric
162+
157163
_, innerGradFunc := NewLineConstraint(p1.Point(), p2.Point(), 0.001)
158164
pointGrad := innerGradFunc(&motionplan.State{Position: query})
159165
test.That(t, pointGrad, test.ShouldBeLessThan, 0.001*0.001)

motionplan/armplanning/motion_planner_test.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -947,10 +947,7 @@ func TestMovementWithGripper(t *testing.T) {
947947
goal := spatialmath.NewPose(r3.Vector{500, 0, -300}, &spatialmath.OrientationVector{OZ: -1})
948948
startConfig := frame.NewZeroInputs(fs)
949949

950-
// linearly plan with the gripper
951-
motionConfig := map[string]interface{}{
952-
"motion_profile": LinearMotionProfile,
953-
}
950+
motionConfig := map[string]interface{}{}
954951
planOpts, err := NewPlannerOptionsFromExtra(motionConfig)
955952
test.That(t, err, test.ShouldBeNil)
956953
request := &PlanRequest{
@@ -1150,7 +1147,7 @@ func TestPtgPosOnlyBidirectional(t *testing.T) {
11501147

11511148
goal := spatialmath.NewPoseFromPoint(r3.Vector{1000, -8000, 0})
11521149

1153-
extra := map[string]interface{}{"motion_profile": PositionOnlyMotionProfile, "position_seeds": 2, "smooth_iter": 5}
1150+
extra := map[string]interface{}{} //
11541151

11551152
baseFS := frame.NewEmptyFrameSystem("baseFS")
11561153
err = baseFS.AddFrame(kinematicFrame, baseFS.World())

motionplan/armplanning/plan_manager.go

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -764,19 +764,13 @@ func (pm *planManager) planRelativeWaypoint(ctx context.Context, seedPlan motion
764764
return nil, err
765765
}
766766
}
767-
if pm.planOpts.PositionSeeds > 0 && pm.planOpts.MotionProfile == PositionOnlyMotionProfile {
768-
err = maps.fillPosOnlyGoal(wp.goalState.poses, pm.planOpts.PositionSeeds)
769-
if err != nil {
770-
return nil, err
771-
}
772-
} else {
773-
goalPose := wp.goalState.poses[pm.motionChains.ptgFrameName].Pose()
774-
goalMapFlip := map[string]*referenceframe.PoseInFrame{
775-
pm.motionChains.ptgFrameName: referenceframe.NewPoseInFrame(referenceframe.World, spatialmath.Compose(goalPose, flipPose)),
776-
}
777-
goalNode := &basicNode{q: zeroInputs, poses: goalMapFlip}
778-
maps.goalMap = map[node]node{goalNode: nil}
767+
goalPose := wp.goalState.poses[pm.motionChains.ptgFrameName].Pose()
768+
goalMapFlip := map[string]*referenceframe.PoseInFrame{
769+
pm.motionChains.ptgFrameName: referenceframe.NewPoseInFrame(referenceframe.World, spatialmath.Compose(goalPose, flipPose)),
779770
}
771+
goalNode := &basicNode{q: zeroInputs, poses: goalMapFlip}
772+
maps.goalMap = map[node]node{goalNode: nil}
773+
780774
startNode := &basicNode{q: zeroInputs, poses: pm.request.StartState.poses}
781775
maps.startMap = map[node]node{startNode: nil}
782776

@@ -821,11 +815,6 @@ func (pm *planManager) useSubWaypoints(seedPlan motionplan.Plan, wpi int) bool {
821815
}
822816
}
823817

824-
// linear motion profile has known intermediate points, so solving can be broken up and sped up
825-
if pm.planOpts.MotionProfile == LinearMotionProfile {
826-
return true
827-
}
828-
829818
if len(pm.request.Constraints.GetLinearConstraint()) > 0 {
830819
return true
831820
}

motionplan/armplanning/planner_options.go

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -76,18 +76,6 @@ func init() {
7676
defaultNumThreads = utils.GetenvInt("MP_NUM_THREADS", defaultNumThreads)
7777
}
7878

79-
// MotionProfile is an enum which indicates the motion profile to use when planning.
80-
type MotionProfile string
81-
82-
// These are the currently supported motion profiles.
83-
const (
84-
FreeMotionProfile MotionProfile = "free"
85-
LinearMotionProfile MotionProfile = "linear"
86-
PseudolinearMotionProfile MotionProfile = "pseudolinear"
87-
OrientationMotionProfile MotionProfile = "orientation"
88-
PositionOnlyMotionProfile MotionProfile = "position_only"
89-
)
90-
9179
// NewBasicPlannerOptions specifies a set of basic options for the planner.
9280
func NewBasicPlannerOptions() *PlannerOptions {
9381
opt := &PlannerOptions{}
@@ -118,10 +106,6 @@ func NewBasicPlannerOptions() *PlannerOptions {
118106
opt.TimeMultipleAfterFindingFirstSolution = defaultTimeMultipleAfterFindingFirstSolution
119107
opt.NumThreads = defaultNumThreads
120108

121-
opt.LineTolerance = defaultLinearDeviation
122-
opt.OrientationTolerance = defaultOrientationDeviation
123-
opt.ToleranceFactor = defaultPseudolinearTolerance
124-
125109
opt.PathStepSize = defaultStepSizeMM
126110
opt.CollisionBufferMM = defaultCollisionBufferMM
127111
opt.RandomSeed = defaultRandomSeed
@@ -194,21 +178,6 @@ type PlannerOptions struct {
194178
// See metrics.go for options
195179
ConfigurationDistanceMetric motionplan.SegmentFSMetricType `json:"configuration_distance_metric"`
196180

197-
// A profile indicating which of the tolerance parameters listed below should be considered
198-
// for further constraining the motion.
199-
MotionProfile MotionProfile `json:"motion_profile"`
200-
201-
// Linear tolerance for translational deviation for a path. Only used when the
202-
// `MotionProfile` is `LinearMotionProfile`.
203-
LineTolerance float64 `json:"line_tolerance"`
204-
205-
// Orientation tolerance for angular deviation for a path. Used for either the `LinearMotionProfile`
206-
// or the `OrientationMotionProfile`.
207-
OrientationTolerance float64 `json:"orient_tolerance"`
208-
209-
// A factor by which the entire pose is allowed to deviate for a path. Used only for a PseudolinearMotionProfile.
210-
ToleranceFactor float64 `json:"tolerance"`
211-
212181
// No two geometries that did not start the motion in collision may come within this distance of
213182
// one another at any time during a motion.
214183
CollisionBufferMM float64 `json:"collision_buffer_mm"`
@@ -259,11 +228,6 @@ func NewPlannerOptionsFromExtra(extra map[string]interface{}) (*PlannerOptions,
259228
return nil, errors.New("collision_buffer_mm can't be negative")
260229
}
261230

262-
// we want to deprecate, rather than break, usage of the "tolerance" key for
263-
// OrientationMotionProfile
264-
if opt.MotionProfile == OrientationMotionProfile {
265-
opt.OrientationTolerance = opt.ToleranceFactor
266-
}
267231
return opt, nil
268232
}
269233

@@ -293,18 +257,6 @@ func updateOptionsForPlanning(opt *PlannerOptions, useTPSpace bool) (*PlannerOpt
293257
optCopy.ScoringMetric = motionplan.PTGDistance
294258
}
295259

296-
if optCopy.MotionProfile == FreeMotionProfile || optCopy.MotionProfile == PositionOnlyMotionProfile {
297-
if optCopy.PlanningAlgorithm() == UnspecifiedAlgorithm {
298-
fallbackOpts := &optCopy
299-
300-
optCopy.Timeout = defaultFallbackTimeout
301-
optCopy.PlanningAlgorithmSettings = AlgorithmSettings{
302-
Algorithm: RRTStar,
303-
}
304-
optCopy.Fallback = fallbackOpts
305-
}
306-
}
307-
308260
return &optCopy, nil
309261
}
310262

motionplan/armplanning/rrt.go

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -48,32 +48,6 @@ type rrtMaps struct {
4848
optNode node // The highest quality IK solution
4949
}
5050

51-
func (maps *rrtMaps) fillPosOnlyGoal(goal referenceframe.FrameSystemPoses, posSeeds int) error {
52-
thetaStep := 360. / float64(posSeeds)
53-
if maps == nil {
54-
return errors.New("cannot call method fillPosOnlyGoal on nil maps")
55-
}
56-
if maps.goalMap == nil {
57-
maps.goalMap = map[node]node{}
58-
}
59-
for i := 0; i < posSeeds; i++ {
60-
newMap := referenceframe.FrameSystemPoses{}
61-
for frame, goal := range goal {
62-
newMap[frame] = referenceframe.NewPoseInFrame(
63-
frame,
64-
spatialmath.NewPose(goal.Pose().Point(), &spatialmath.OrientationVectorDegrees{OZ: 1, Theta: float64(i) * thetaStep}),
65-
)
66-
}
67-
68-
goalNode := &basicNode{
69-
q: make(referenceframe.FrameSystemInputs),
70-
poses: newMap,
71-
}
72-
maps.goalMap[goalNode] = nil
73-
}
74-
return nil
75-
}
76-
7751
// initRRTsolutions will create the maps to be used by a RRT-based algorithm. It will generate IK solutions to pre-populate the goal
7852
// map, and will check if any of those goals are able to be directly interpolated to.
7953
// If the waypoint specifies poses for start or goal, IK will be run to create configurations.

motionplan/constraint.go

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,25 @@ func ConstraintsFromProtobuf(pbConstraint *motionpb.Constraints) *Constraints {
6464
return toRet
6565
}
6666

67+
plinConstraintFromProto := func(plinConstraints []*motionpb.PseudolinearConstraint) []PseudolinearConstraint {
68+
toRet := make([]PseudolinearConstraint, 0, len(plinConstraints))
69+
for _, plc := range plinConstraints {
70+
linTol := 0.
71+
if plc.LineToleranceFactor != nil {
72+
linTol = float64(*plc.LineToleranceFactor)
73+
}
74+
orientTol := 0.
75+
if plc.OrientationToleranceFactor != nil {
76+
orientTol = float64(*plc.OrientationToleranceFactor)
77+
}
78+
toRet = append(toRet, PseudolinearConstraint{
79+
LineToleranceFactor: linTol,
80+
OrientationToleranceFactor: orientTol,
81+
})
82+
}
83+
return toRet
84+
}
85+
6786
// iterate through all motionpb.OrientationConstraint and convert to RDK form
6887
orientConstraintFromProto := func(orientConstraints []*motionpb.OrientationConstraint) []OrientationConstraint {
6988
toRet := make([]OrientationConstraint, 0, len(orientConstraints))
@@ -99,7 +118,7 @@ func ConstraintsFromProtobuf(pbConstraint *motionpb.Constraints) *Constraints {
99118

100119
return NewConstraints(
101120
linConstraintFromProto(pbConstraint.LinearConstraint),
102-
[]PseudolinearConstraint{},
121+
plinConstraintFromProto(pbConstraint.PseudolinearConstraint),
103122
orientConstraintFromProto(pbConstraint.OrientationConstraint),
104123
collSpecFromProto(pbConstraint.CollisionSpecification),
105124
)
@@ -155,6 +174,19 @@ func (c *Constraints) ToProtobuf() *motionpb.Constraints {
155174
return toRet
156175
}
157176

177+
convertPseudoLinConstraintToProto := func(plinConstraints []PseudolinearConstraint) []*motionpb.PseudolinearConstraint {
178+
toRet := make([]*motionpb.PseudolinearConstraint, 0)
179+
for _, plc := range plinConstraints {
180+
lineTolerance := float32(plc.LineToleranceFactor)
181+
orientationTolerance := float32(plc.OrientationToleranceFactor)
182+
toRet = append(toRet, &motionpb.PseudolinearConstraint{
183+
LineToleranceFactor: &lineTolerance,
184+
OrientationToleranceFactor: &orientationTolerance,
185+
})
186+
}
187+
return toRet
188+
}
189+
158190
// convert OrientationConstraint to motionpb.OrientationConstraint
159191
convertOrientConstraintToProto := func(orientConstraints []OrientationConstraint) []*motionpb.OrientationConstraint {
160192
toRet := make([]*motionpb.OrientationConstraint, 0)
@@ -187,6 +219,7 @@ func (c *Constraints) ToProtobuf() *motionpb.Constraints {
187219

188220
return &motionpb.Constraints{
189221
LinearConstraint: convertLinConstraintToProto(c.LinearConstraint),
222+
PseudolinearConstraint: convertPseudoLinConstraintToProto(c.PseudolinearConstraint),
190223
OrientationConstraint: convertOrientConstraintToProto(c.OrientationConstraint),
191224
CollisionSpecification: convertCollSpecToProto(c.CollisionSpecification),
192225
}

0 commit comments

Comments
 (0)