99 "fmt"
1010 "io"
1111 "log"
12+ "math"
1213 "os"
1314 "runtime/pprof"
1415 "slices"
@@ -23,10 +24,14 @@ import (
2324 "go.viam.com/utils/perf"
2425 "go.viam.com/utils/trace"
2526
27+ "go.viam.com/rdk/cli"
2628 "go.viam.com/rdk/logging"
2729 "go.viam.com/rdk/motionplan"
2830 "go.viam.com/rdk/motionplan/armplanning"
2931 "go.viam.com/rdk/referenceframe"
32+ "go.viam.com/rdk/robot"
33+ "go.viam.com/rdk/robot/client"
34+ "go.viam.com/rdk/robot/framesystem"
3035 "go.viam.com/rdk/spatialmath"
3136)
3237
@@ -48,6 +53,8 @@ func realMain() error {
4853 loop := flag .Int ("loop" , 1 , "loop" )
4954 cpu := flag .String ("cpu" , "" , "cpu profiling" )
5055 interactive := flag .Bool ("i" , false , "interactive" )
56+ host := flag .String ("host" , "" , "host to execute on" )
57+ forceMotion := flag .Bool ("force-move" , false , "" )
5158
5259 flag .Parse ()
5360
@@ -96,6 +103,10 @@ func realMain() error {
96103 Pattern : "*.mp.*" ,
97104 Level : "INFO" ,
98105 },
106+ {
107+ Pattern : "*.networking.*" ,
108+ Level : "INFO" ,
109+ },
99110 }, logger )
100111 }
101112
@@ -207,6 +218,13 @@ func realMain() error {
207218 myl2n ,
208219 referenceframe .InputsLinfDistance (p , t [c ]),
209220 cart )
221+
222+ deltas := []float64 {}
223+ for i , a := range t [c ] {
224+ deltas = append (deltas , a - p [i ])
225+ }
226+
227+ mylog .Printf ("\t \t \t \t deltas: %v" , logging.FloatArrayFormat {"%0.5f" , deltas })
210228 }
211229 }
212230 }
@@ -224,6 +242,13 @@ func realMain() error {
224242 }
225243 }
226244
245+ if * host != "" {
246+ err := executeOnArm (ctx , * host , plan , * forceMotion , logger )
247+ if err != nil {
248+ return err
249+ }
250+ }
251+
227252 return nil
228253}
229254
@@ -455,3 +480,84 @@ func doInteractive(req *armplanning.PlanRequest, plan motionplan.Plan, planErr e
455480 }
456481 }
457482}
483+
484+ func executeOnArm (ctx context.Context , host string , plan motionplan.Plan , force bool , logger logging.Logger ) error {
485+ byComponent := map [string ][][]referenceframe.Input {}
486+
487+ for _ , s := range plan .Trajectory () {
488+ for cName , inputs := range s {
489+ if len (inputs ) > 0 {
490+ byComponent [cName ] = append (byComponent [cName ], inputs )
491+ }
492+ }
493+ }
494+
495+ if len (byComponent ) > 1 {
496+ return fmt .Errorf ("executeOnArm only supports one component moving right now, not: %d" , len (byComponent ))
497+ }
498+
499+ c , err := cli .ConfigFromCache (nil )
500+ if err != nil {
501+ return err
502+ }
503+
504+ dopts , err := c .DialOptions ()
505+ if err != nil {
506+ return err
507+ }
508+
509+ theRobot , err := client .New (
510+ ctx ,
511+ host ,
512+ logger ,
513+ client .WithDialOptions (dopts ... ),
514+ )
515+ if err != nil {
516+ return err
517+ }
518+ defer func () {
519+ err := theRobot .Close (ctx )
520+ if err != nil {
521+ logger .Errorf ("cannot close robot: %v" , err )
522+ }
523+ }()
524+
525+ for cName , allInputs := range byComponent {
526+ r , err := robot .ResourceByName (theRobot , cName )
527+ if err != nil {
528+ return err
529+ }
530+
531+ ie , ok := r .(framesystem.InputEnabled )
532+ if ! ok {
533+ return fmt .Errorf ("%s is not InputEnabled, is %T" , cName , r )
534+ }
535+
536+ cur , err := ie .CurrentInputs (ctx )
537+ if err != nil {
538+ return err
539+ }
540+
541+ for j , v := range cur {
542+ delta := math .Abs (v - allInputs [0 ][j ])
543+ if delta > .01 {
544+ err = fmt .Errorf ("joint %d for resource %s too far start: %0.5f go: %0.5f delta: %0.5f" ,
545+ j , cName , v , allInputs [0 ][j ], delta )
546+ if force {
547+ logger .Warnf ("ignoring %v" , err )
548+ } else {
549+ return err
550+ }
551+ }
552+ }
553+
554+ logger .Infof ("sending %d positions to %s" , len (allInputs ), cName )
555+
556+ err = ie .GoToInputs (ctx , allInputs ... )
557+ if err != nil {
558+ return err
559+ }
560+ }
561+
562+ return nil
563+ }
0 commit comments