private void AssembleMachineForCompleteTrayPickup(TransportOperationMachine machine, object sourceLockOwner) { // In this case, Station is the source of the tray. var station = machine.Station as IStation; var dockStation = machine.Station as ITransportDock; if (station != null && dockStation != null) { // This machine doesn't know if Transport is safe yet or not. machine.AddActivity(new DynamicActivity("Set machine HaltOnError", () => machine.HaltOnError = true)); // Wait for transportation to stop moving. machine.AddContinueCondition(new DynamicConstraint <ITransport>("Transport Detects Tray?", machine.Transport, (td) => IsTransportParkedWithTray(machine.Transport))); if (station.Type != StationType.Stainer) { // This machine knows it is above the station and in elevator now, so no need for transport error. machine.AddActivity(new DynamicActivity("Set machine HaltOnError", () => machine.HaltOnError = false)); } // Wait for the source station IsTrayDetected trigger. // Slide id does not have a tray present sensor, so it should always be faking it. machine.AddContinueCondition( new DynamicConstraint <ITrayDetector>("Tray Not Detected At Source?", machine.Station, (td) => !td.IsTrayDetected)); // Complete the handoff. Quit this machine if the CompleteHandoff fails. machine.SetActivityTrayHandlerCompleteHandoff(); // If we just picked up from a stainer and the destination is below it, wait for CompleteHandoff to finish. if (station.Type == StationType.Stainer) { var destinationZ = machine.Configuration.Data.DestinationZLocation; // If the destination is below the source stainer, // wait until the stainer's handoff is completed. Otherwise, transport can move on safely. if (dockStation.DockZ > destinationZ) { // Pause until source station has completed its handoff. machine.SetPauseUntilConditionOfStation("IsStationNotHandoffPrepared", IsStationNotHandoffPrepared); } } // Assuming the station is no longer HandoffPrepared, TrayMover does not need to halt movements anymore. machine.AddActivity(new DynamicActivity("Set machine HaltOnError", () => machine.HaltOnError = true)); // Reassign the tray from source to transport. machine.SetActivityReassignTray(machine.Station, machine.Transport); // Special activity needed only for this machine to release the lock on the source station early. machine.SetActivityReleaseDockLock(sourceLockOwner); } else { throw new Exception("Complete tray pick-up failed to build: no source station."); } }
public void AssembleMachineForCompleteTrayDropoff(TransportOperationMachine machine) { var station = machine.Station as IStation; if (station != null) { // This machine doesn't know if Transport is safe or not. machine.AddActivity(new DynamicActivity("Set machine HaltOnError", () => machine.HaltOnError = true)); // If the prior machine was stopped, skip tray reassignment. if (!machine.IsStopped) { //TODO: change this to go by interfaces once SlideId is refactored. if (station.Type != StationType.SlideId) { // Wait for transportation to stop moving machine.AddContinueCondition(new DynamicConstraint <ITransport>("Transport Missing Tray?", machine.Transport, (td) => IsTransportParkedWithoutTray(machine.Transport))); } // Wait for the destination station IsTrayDetected trigger. // Slide id does not have a tray present sensor, so it should always be faking it. machine.AddContinueCondition(new DynamicConstraint <ITrayDetector>("Tray Detected At Destination?", machine.Station, (td) => td.IsTrayDetected)); // Reassign the tray from transport to destination. // Needed to reassign the Tray before performing complete handoff to ensure the tray cooling is performed. machine.SetActivityReassignTray(machine.Transport, machine.Station); } if (station.Type != StationType.Stainer) { // This machine knows it is below the station and in elevator now, so no need for transport error. machine.AddActivity(new DynamicActivity("Set machine HaltOnError", () => machine.HaltOnError = false)); } // Complete the handoff. Quit this machine if the CompleteHandoff fails. machine.SetActivityTrayHandlerCompleteHandoff(); // Pause until destination station has completed its handoff, which indicates the overall tray move is done. machine.SetPauseUntilConditionOfStation("IsStationNotHandoffPrepared?", IsStationNotHandoffPrepared); // If neither the destination nor the transport detect a tray when the machine exits, set tray to Lost state. machine.UseFinalExitBehavior(new ActOnResultActivity <bool>("Set Tray Lost", () => IsTrayLost(machine.Transport, machine.Station) && machine.Tray != null, true, () => machine.Tray.OnDetectionLost())); } else { throw new Exception("Complete tray drop-off failed to build: no destination station."); } }
internal static IActivityMachine CreateMachineForTransportOperation(DynamicConfiguration config) { var dispatcher = config.Data.Dispatcher as SimpleDispatcher; var operation = config.Data.TransportOperation; var activityMachine = new TransportOperationMachine(Enum.GetName(typeof(TransportOperation), operation), dispatcher); // Try to reuse a builder if one was supplied. try { activityMachine.Builder = config.Data.Builder as IActivityMachineBuilder; } catch (Exception) { //nothing to do } if (activityMachine.Builder == null) { activityMachine.Builder = ActivityMachineBuilderLoader.GetActivityMachineBuilder(config); } return(activityMachine); }
public void AssembleMachineForBeginTrayDropoff(TransportOperationMachine machine) { var station = machine.Station as IStation; var dockStation = machine.Station as ITransportDock; if (station != null && dockStation != null && IsStationDropoffReady(station)) { // We can get an early start on handoff preparation if not dropping off to a stainer, // or if the transport is already above the stainer. var prepareForHandoffEarly = station.Type != StationType.Stainer || IsTransportAboveDropoffHeight(dockStation)(machine.Transport); if (prepareForHandoffEarly) { // Pause until the source station is ready to start hand-off prep. machine.SetPauseUntilConditionOfStation("IsStationDropoffReady", IsStationDropoffReady); // Prepare the source station for handoff. Quit this machine if the PrepareForHandoff fails. machine.SetActivityTrayHandlerPrepareForHandoff(); } // Move the transport to the tray destination station for a tray drop-off. Quit if the move fails. machine.SetConditionalActivityTransportMoveToDropoffHeight(IsTransportParkedInElevator, machine.Configuration.Data.MoveCancellationToken); // Pause until the transport is above the destination station's drop-off location. // If it is already above, this will continue immediately. machine.SetPauseUntilConditionOfTransport("IsTransportAboveDropoffHeight", IsTransportAboveDropoffHeight(dockStation)); // If we didn't already prepare for handoff before the Z move, do it now. if (!prepareForHandoffEarly) { // Pause until the source station is ready to start hand-off prep. machine.SetPauseUntilConditionOfStation("IsStationDropoffReady?", IsStationDropoffReady); // Prepare the source station for handoff. Quit this machine if the PrepareForHandoff fails. machine.SetActivityTrayHandlerPrepareForHandoff(); } // Pause until the destination station is handoff-prepared for drop-off. machine.SetPauseUntilConditionOfStation("IsStationHandoffPrepared?", IsStationHandoffPrepared); // Wait for transport to be stopped at location. machine.SetPauseUntilConditionOfTransport("IsTransportStoppedAtLocation?", IsTransportParkedAtDropoffHeight(dockStation)); // Ensure destination station is safe to enter to drop-off tray machine.SetActivityTrayHandlerSafeToEnter(); // Don't allow the machine to be stopped once the drop-off has started. machine.AddActivity(new DynamicActivity("Set CanStop=false", () => machine.CanStop = false)); // Possibly finish before doing the drop-off if the operation was cancelled, regardless of tray aborted or not. // CompleteTrayDropoff operation will do recovery if we finish here. machine.SetFinishOrContinueForMoveStopped(); // From this point on, TrayMover should stop movements if this machine encounters an error. machine.AddActivity(new DynamicActivity("Set machine HaltOnError", () => machine.HaltOnError = true)); // Tell transport to put the tray. Quit if the move fails. // This will not act until transport is at the drop-off height. machine.SetActivityTransportPerformDropoff(); // If dropping off to a stainer, make sure transport is clear of the stainer mount before allowing complete handoff. if (station.Type == StationType.Stainer) { //TODO: ASK TEST/DEV TEAMS IF STAINER UPPER&LOWER LOADOFFSETS ARE EVER DIFFERENT THAN UPPER&LOWER OFFSETS. //TODO: IF NOT, CAN ELIMINATE THIS AND REMOVE THE LOADOFFSETS FROM THE CONFIGURATION. //TODO: IF STILL NEEDED, ELIMINATE SPECIAL CASE HERE BY MAKING STAINERS OVERRIDE UPPEROFFSET & LOWEROFFSET WHICH INCORPORATES ANY EXTRA OFFSET INTO THE ONE MOVE. // Ensure the transport made it to below the stainer mount. If it already is below the stainer, just move on. machine.SetPauseUntilConditionOfTransport("IsTransportBelowPickupHeight?", IsTransportBelowPickupHeight(dockStation)); } } else { throw new Exception("Begin tray drop-off failed to build: no destination station, or station is not ready."); } }
private void AssembleMachineForBeginTrayPickup(TransportOperationMachine machine) { // In this case, Station is the source of the tray. var station = machine.Station as IStation; var dockStation = machine.Station as ITransportDock; if (station != null && dockStation != null) { // Wait for the source station to detect a tray, responding only to the IsTrayDetected trigger. // The source station should have the tray. Slide id does not have a tray present sensor, so it should fake it. machine.AddQuitOrContinueCondition( new DynamicConstraint <ITrayDetector>("Tray Not Detected At Source?", machine.Station, (td) => !td.IsTrayDetected), new DynamicConstraint <ITrayDetector>("Tray Detected At Source?", machine.Station, (td) => td.IsTrayDetected)); // We can get an early start on handoff preparation if not picking up from a stainer, // or if the transport is already below the stainer. var prepareForHandoffEarly = station.Type != StationType.Stainer || IsTransportBelowPickupHeight(dockStation)(machine.Transport); if (prepareForHandoffEarly) { // Pause until the source station is ready for hand-off preparation. machine.SetPauseUntilConditionOfStation("IsStationPickupReady?", IsStationPickupReady); // Prepare the source station for handoff. Quit this machine if the PrepareForHandoff fails. machine.SetActivityTrayHandlerPrepareForHandoff(); } // Move the transport to the tray source station for a tray pick-up. Quit if the move fails. machine.SetConditionalActivityTransportMoveToPickupHeight(IsTransportParkedInElevator, machine.Configuration.Data.MoveCancellationToken); // Pause until the transport is below the source station's pick-up location. machine.SetPauseUntilConditionOfTransport("IsTransportBelowPickupHeight?", IsTransportBelowPickupHeight(dockStation)); // If we didn't already prepare for handoff before the elevator move, do it now. if (!prepareForHandoffEarly) { // Pause until the source station is ready. machine.SetPauseUntilConditionOfStation("IsStationPickupReady?", IsStationPickupReady); // Prepare the source station for handoff. Quit this machine if the PrepareForHandoff fails. machine.SetActivityTrayHandlerPrepareForHandoff(); } // Pause until source station is handoff-prepared for pickup. machine.SetPauseUntilConditionOfStation("IsStationHandoffPrepared?", IsStationHandoffPrepared); // Wait for transport to be stopped at the pick-up height. machine.SetPauseUntilConditionOfTransport("IsTransportStoppedAtLocation?", IsTransportParkedAtPickupHeight(dockStation)); // Ensure source station is safe to enter to pick-up tray machine.SetActivityTrayHandlerSafeToEnter(); // From this point on, TrayMover should stop movements if this machine encounters an error. machine.AddActivity(new DynamicActivity("Set machine HaltOnError", () => machine.HaltOnError = true)); // Tell transport to get the tray. Quit if the move fails. machine.SetActivityTransportPerformPickup(); // If picking up from a stainer, make sure transport is clear of stainer mount before allowing complete handoff. if (station.Type == StationType.Stainer) { //TODO: ASK TEST/DEV TEAMS IF STAINER UPPER&LOWER LOADOFFSETS ARE EVER DIFFERENT THAN UPPER&LOWER OFFSETS. //TODO: IF NOT, CAN ELIMINATE THIS AND REMOVE THE LOADOFFSETS FROM THE CONFIGURATION. //TODO: IF STILL NEEDED, ELIMINATE SPECIAL CASE HERE BY MAKING STAINERS OVERRIDE UPPEROFFSET & LOWEROFFSET WHICH INCORPORATES ANY EXTRA OFFSET INTO THE ONE MOVE. // Ensure the transport made it to the desired Z position. machine.SetPauseUntilConditionOfTransport("IsTransportAboveDropoffHeight?", IsTransportAboveDropoffHeight(dockStation)); } } else { throw new Exception("Begin tray pick-up failed to build: no source station."); } }