github.com/gkstretton/dark/services/goo@v0.0.0-20231114224855-2d1a2074d446/actor/executor/executor_dispense.go (about) 1 package executor 2 3 import ( 4 "fmt" 5 6 "github.com/gkstretton/asol-protos/go/machinepb" 7 ) 8 9 type dispenseExecutor struct { 10 X float32 11 Y float32 12 } 13 14 func NewDispenseExecutor(x, y float32) *dispenseExecutor { 15 return &dispenseExecutor{ 16 X: x, 17 Y: y, 18 } 19 } 20 21 func (e *dispenseExecutor) Preempt() { 22 if !goToLock.TryLock() { 23 fmt.Println("preemptive goTo blocked") 24 return 25 } 26 defer goToLock.Unlock() 27 goTo(e.X, e.Y) 28 } 29 30 func (e *dispenseExecutor) PredictOutcome(state *machinepb.StateReport) *machinepb.StateReport { 31 state.PipetteState.DispenseRequestNumber++ 32 state.MovementDetails.TargetXUnit = e.X 33 state.MovementDetails.TargetYUnit = e.Y 34 35 state.PipetteState.VolumeTargetUl -= getDispenseVolume() 36 if state.PipetteState.VolumeTargetUl < 1 { 37 state.PipetteState.Spent = true 38 } 39 40 // status will change too, but not used in decision making 41 return state 42 } 43 44 func (e *dispenseExecutor) Execute(c chan *machinepb.StateReport) { 45 goToLock.Lock() 46 defer goToLock.Unlock() 47 48 fmt.Printf("Going to %f, %f\n", e.X, e.Y) 49 goTo(e.X, e.Y) 50 fmt.Println("dispensing...") 51 dispenseBlocking(c) 52 fmt.Println("done...") 53 } 54 55 func (e *dispenseExecutor) String() string { 56 return fmt.Sprintf("dispenseExecutor (x: %.3f, y: %.3f)", e.X, e.Y) 57 } 58 59 // call dispense, and observe transition (-> dispensing -> not dispensing) 60 func dispenseBlocking(c chan *machinepb.StateReport) { 61 a1 := conditionWaiter(c, func(sr *machinepb.StateReport) bool { 62 return sr.Status == machinepb.Status_DISPENSING 63 }) 64 dispense() 65 fmt.Println("waiting for 'DISPENSING'") 66 <-a1 67 fmt.Println("waiting for '!DISPENSING'") 68 <-conditionWaiter(c, func(sr *machinepb.StateReport) bool { 69 return sr.Status != machinepb.Status_DISPENSING 70 }) 71 }