public bool CreateNewDoubleLoadCycleTask(ElevatorTask newTask, string loadB_ID) { lock (locker) { var task = newTask.Elevator.ElevatorTasks.Where(t => t.LoadB_ID == loadB_ID); //Find the task for the load located at B if (task.Any()) { ElevatorTask existingTask = task.First() as ElevatorTask; if (existingTask != null) { existingTask.LoadA_ID = newTask.LoadA_ID; existingTask.SourceLoadA = newTask.SourceLoadA; existingTask.DestinationLoadA = newTask.DestinationLoadA; existingTask.SourceLoadAConv = newTask.SourceLoadAConv; existingTask.DestinationLoadAConv = newTask.DestinationLoadAConv; existingTask.numberOfLoadsInTask = 2; existingTask.LoadCycle = Cycle.Double; existingTask.UnloadCycle = Cycle.Double; if (existingTask.Elevator.ParentMultiShuttle.GetConveyorFromLocName(existingTask.DestinationLoadA) != existingTask.Elevator.ParentMultiShuttle.GetConveyorFromLocName(existingTask.DestinationLoadB)) { existingTask.UnloadCycle = Cycle.Single; } return(true); } } return(false); } }
/// <summary> /// Refactored from CurrentTask so that a control object can have control of when a new task assigned (if there is one to be assigned). /// </summary> public void GetNewElevatorTask() { currentTask = null; //The CurrentTask wraps this field if (ElevatorTasks.Any()) //Get a new task { ElevatorTask eT = ElevatorTasks[0]; CurrentTask = eT; } }
public bool OptimiseTask(Elevator elevator) //Not used { lock (locker) { try { //Try to take another task from another level and add to this task? var eTasks = elevator.ElevatorTasks.Where(t => t.Flow == TaskType.Outfeed && t.NumberOfLoadsInTask == 1); //get all eligable tasks //TODO check tht the DS is the same or that the DS of the new task will DS is on the way to the current task DS ElevatorTask newTask = null; if (eTasks != null) { if (elevator.CurrentTask.DropIndexLoadB != 0) { //Find the next sequence and if it is accessable (Load has arrived at front position on Rack Conv) add it to the current task //ElevatorTask nextInSeq = eTasks.OrderBy(x => x.DropIndexLoadB).FirstOrDefault(x => x.DropIndexLoadB != 0); ElevatorTask nextInSeq = Elevator.OrderTasks(eTasks).FirstOrDefault(x => x.DropIndexLoadB != 0); if (((RackConveyor)nextInSeq.SourceLoadBConv).LocationB.Active && ((RackConveyor)nextInSeq.SourceLoadBConv).LocationB.ActiveLoad.Identification == nextInSeq.LoadB_ID) { //newTask = eTasks.OrderBy(x => x.DropIndexLoadB).FirstOrDefault(x => x.DropIndexLoadB != 0); //Exclude unsequenced loads newTask = Elevator.OrderTasks(eTasks).FirstOrDefault(x => x.DropIndexLoadB != 0); //Exclude unsequenced loads } } else { //Try to pair an unsequenced load, load must be at the front position newTask = eTasks.FirstOrDefault(x => x.DropIndexLoadB == 0 && ((RackConveyor)x.SourceLoadBConv).LocationB.Active && ((RackConveyor)x.SourceLoadBConv).LocationB.ActiveLoad.Identification == x.LoadB_ID); } if (newTask != null) { elevator.CurrentTask.CombineTasks(elevator, newTask); } if (elevator.CurrentTask != null) { ElevatorTask t = elevator.CurrentTask; //Log.Write(string.Format("Optimise Task: LoadB: {0}_{1}_{2}, LoadA {3}_{4}_{5}", t.LoadB_ID, t.DropIndexLoadB, t.SourceLoadB, t.LoadA_ID, t.DropIndexLoadA, t.SourceLoadA)); } } return(false); } catch { return(false); } } }
public override void Reset() { lift.Route.Motor.Stop(); ElevatorTasks.Clear(); currentTask = null; foreach (Load l in ElevatorConveyor.Route.Loads) { l.Dispose(); } lift.Destination.Distance = 0; lift.ShuttleCar.Switch(lift.Destination); base.Reset(); }
void ElevatorTasks_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add) { if (e.NewItems != null) { ElevatorTask etNew = null; foreach (ElevatorTask newTask in e.NewItems) { newTask.SourceLoadAConv = ParentMultiShuttle.GetConveyorFromLocName(newTask.SourceLoadA); newTask.SourceLoadBConv = ParentMultiShuttle.GetConveyorFromLocName(newTask.SourceLoadB); newTask.DestinationLoadAConv = ParentMultiShuttle.GetConveyorFromLocName(newTask.DestinationLoadA); newTask.DestinationLoadBConv = ParentMultiShuttle.GetConveyorFromLocName(newTask.DestinationLoadB); newTask.Elevator = this; etNew = newTask; } ///// Check for repeated tasks This shouldn't happen however the controller/WMS may issue repeated tasks ////// List <ElevatorTask> listET = ElevatorTasks.ToList(); if (CurrentTask != null) { listET.Add(CurrentTask); } listET.Remove(etNew); foreach (ElevatorTask st in listET) { if (st.Equals(etNew)) // Already have this task { ElevatorTasks.Remove(etNew); //etNew = null; } } /////// Log.Write(etNew.ToString()); if (CurrentTask == null && etNew != null) //elevator not doing a task add this to the current task { CurrentTask = etNew; } } } }
void ElevatorTasks_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add) { if (e.NewItems != null) { ElevatorTask etNew = null; foreach (ElevatorTask newTask in e.NewItems) { newTask.SourceLoadAConv = ParentMultiShuttle.GetConveyorFromLocName(newTask.SourceLoadA); newTask.SourceLoadBConv = ParentMultiShuttle.GetConveyorFromLocName(newTask.SourceLoadB); newTask.DestinationLoadAConv = ParentMultiShuttle.GetConveyorFromLocName(newTask.DestinationLoadA); newTask.DestinationLoadBConv = ParentMultiShuttle.GetConveyorFromLocName(newTask.DestinationLoadB); newTask.Elevator = this; etNew = newTask; } ///// Check for repeated tasks This shouldn't happen however the controller/WMS may issue repeated tasks ////// List <ElevatorTask> listET = ElevatorTasks.ToList(); if (CurrentTask != null) { listET.Add(CurrentTask); } listET.Remove(etNew); foreach (ElevatorTask st in listET) { if (st.Equals(etNew)) // Already have this task { ElevatorTasks.Remove(etNew); //etNew = null; } } //BG Changing this so that the controller and control have full control over what the elevator chooses to do next //ParentMultiShuttle.ElevatorTasksStatusChanged(new ElevatorTasksStatusChangedEventArgs(this)); SetNewElevatorTask(); } } }
/// <summary> /// Use to combine 2 tasks that are on the same level into 1 task and remove the second task /// </summary> /// <param name="elevator"></param> /// <param name="newTask"></param> public void CombineTasks(Elevator elevator, ElevatorTask newTask) { lock (locker) { LoadA_ID = newTask.LoadB_ID; SourceLoadA = newTask.SourceLoadB; DestinationLoadA = newTask.DestinationLoadB; SourceLoadAConv = newTask.SourceLoadBConv; DestinationLoadAConv = newTask.DestinationLoadBConv; DropIndexLoadA = newTask.DropIndexLoadB; numberOfLoadsInTask = 2; UnloadCycle = Cycle.Double; if (DestinationLoadAConv != DestinationLoadBConv) { elevator.CurrentTask.UnloadCycle = Cycle.Single; } elevator.ElevatorTasks.Remove(newTask); } }
/// <summary> /// Trys to clear the elevator task if it is now complete /// </summary> private void TryClearElevatorTask(ElevatorTask task) { if (task == null) { return; } if (task.UnloadCycle == Cycle.Double && LocationA.Active && LocationB.Active) { //if (Elevator.ElevatorConveyor.Route.Loads.Count == 0 && RelevantElevatorTask(task)) //No loads on the elevator and the loads at location A and Location B are part of the current task if (Elevator.ElevatorConveyor.Route.Loads.Count == 0 && RelevantElevatorTask(LocationA, LocationB)) //No loads on the elevator and the loads at location A and Location B are part of the current task { Elevator.CurrentTask = null; // Elevator task is now complete } } //else if (task.UnloadCycle == Cycle.Single && Elevator.ElevatorConveyor.Route.Loads.Count == 0 && RelevantElevatorTask(task)) else if (task.UnloadCycle == Cycle.Single && Elevator.ElevatorConveyor.Route.Loads.Count == 0 && RelevantElevatorTask(LocationA, LocationB)) { //if the elevator task is double pick and single drop and the elevator has no load then kill the elevator task or single pick and single drop in both cases the elevator conveyor will be empty Elevator.CurrentTask = null; } }
//public override bool Equals(object obj) public override bool Equals(object obj) { if (obj == null) { return(false); } ElevatorTask et = obj as ElevatorTask; if (et == null) { return(false); } //Not checking CaseData bool retVal = false; if (et.DestinationLoadAConv == null && DestinationLoadAConv == null) { retVal = true; } else if (et.DestinationLoadAConv != null && et.DestinationLoadAConv.Equals(DestinationLoadAConv)) { retVal = true; } //if (!(retVal && et.DestinationLoadBConv == null && DestinationLoadBConv == null)) if ((retVal && et.DestinationLoadBConv == null && DestinationLoadBConv == null)) { retVal = false; } else if (et.DestinationLoadBConv != null && et.DestinationLoadBConv.Equals(DestinationLoadBConv)) { retVal = true; } return(retVal && et.ToString() == this.ToString()); }
public void SetNewElevatorTask() { if (CurrentTask == null) { if (ElevatorTasks.Any()) { //Look for any type but make sure that the drop station is available before sending any missions var oTasks = (ElevatorTasks.Where(task => task.Flow == TaskType.Outfeed && ((DropStationConveyor)task.DestinationLoadBConv).DropStationConvEmpty)).ToList(); if (oTasks.Any()) { //ElevatorTask lowestTask = oTasks.OrderBy(x => x.DropIndexLoadB).FirstOrDefault(x => x.DropIndexLoadB != 0); //Exclude unsequenced loads var sTasks = OrderTasks(oTasks).ToList(); //Does a special sort to allow for wrap around of the Drop Index var lowestTask = sTasks.FirstOrDefault(x => x.DropIndexLoadB != 0); //Exclude unsequenced loads ElevatorTask blockingTask = null; if (lowestTask != null) { blockingTask = sTasks.FirstOrDefault(x => x.SourceLoadBConv == lowestTask.SourceLoadBConv && ((RackConveyor)x.SourceLoadBConv).LocationB.ActiveLoad != null && ((RackConveyor)x.SourceLoadBConv).LocationB.ActiveLoad.Identification == x.LoadB_ID); } //Check that the lowest task is not blocked by a Housekeep move (IntraLevel) if (blockingTask == null) { ElevatorTask frontTask = null; if (lowestTask != null && lowestTask.TaskLoadLocationBack()) { //Check if there is a load in the front location with the same drop index frontTask = sTasks.FirstOrDefault(x => x != lowestTask && x.SourceLoadBConv == lowestTask.SourceLoadBConv && x.DropIndexLoadB == lowestTask.DropIndexLoadB); } //Is the next task on the same level the next sequence number //ElevatorTask nextLowestTask = oTasks.OrderBy(x => x.DropIndexLoadB).FirstOrDefault(x => x != lowestTask && x.DropIndexLoadB != 0); //Exclude unsequenced loads, are they on the same level? ElevatorTask nextLowestTask = sTasks.FirstOrDefault(x => x != lowestTask && x.DropIndexLoadB != 0); if (frontTask != null) { frontTask.CombineTasks(this, lowestTask); lowestTask = frontTask; } else if (lowestTask != null && nextLowestTask != null && lowestTask.SourceLoadBConv == nextLowestTask.SourceLoadBConv) { //Combine the two tasks... lowestTask.CombineTasks(this, nextLowestTask); } else if (lowestTask != null) { //Need to workout which load is in which position on the conveyor //Does the lowest seq have an unsequenced load in front of it? if (((RackConveyor)lowestTask.SourceLoadBConv).LocationA.Active && ((RackConveyor)lowestTask.SourceLoadBConv).LocationA.ActiveLoad.Identification == lowestTask.LoadB_ID) { //Is there a 0 sequnced load on the same level as a sequenced load? var zTasks = ElevatorTasks.Where(task => task.DropIndexLoadB == 0 && task.SourceLoadBConv == lowestTask.SourceLoadBConv && task.Flow == TaskType.Outfeed); if (zTasks.Any()) { ElevatorTask zTask = zTasks.First(); zTask.CombineTasks(this, lowestTask); lowestTask = zTask; } } } else { //Deal with unsequenced loads... //Look for paired loads first... var dTasks = oTasks.Where(x => ((RackConveyor)x.SourceLoadBConv).LocationB.Active && ((RackConveyor)x.SourceLoadBConv).LocationA.Active && ((RackConveyor)x.SourceLoadBConv).LocationB.ActiveLoad.Identification == x.LoadB_ID); //Have found tasks that could be paired because there is a load behind (Load behind may not have an onward destination) foreach (ElevatorTask task in dTasks) { ElevatorTask dTask = oTasks.FirstOrDefault(x => x.SourceLoadBConv == task.SourceLoadBConv && x.LoadB_ID != task.LoadB_ID); if (dTask != null) { task.CombineTasks(this, dTask); lowestTask = task; break; } } if (lowestTask == null) //A paired load has not been found so choose a single (will be paired with another load from another level using optimise task) { //Only choose loads that are on the front position (B) lowestTask = oTasks.FirstOrDefault(x => ((RackConveyor)x.SourceLoadBConv).LocationB.Active && ((RackConveyor)x.SourceLoadBConv).LocationB.ActiveLoad.Identification == x.LoadB_ID); if (lowestTask != null) { //Is there also a load behind on the same level that can be paired to it? nextLowestTask = oTasks.FirstOrDefault(x => x.SourceLoadBConv == lowestTask.SourceLoadBConv && x != lowestTask); if (nextLowestTask != null) { lowestTask.CombineTasks(this, nextLowestTask); } } } } } else { if (blockingTask.DropIndexLoadB <= lowestTask.DropIndexLoadB) { lowestTask = blockingTask; } } //Set the current task and start the elevator moving if (lowestTask != null && ((RackConveyor)lowestTask.SourceLoadBConv).LocationB.Active && ((RackConveyor)lowestTask.SourceLoadBConv).LocationB.ActiveLoad.Identification == lowestTask.LoadB_ID) { CurrentTask = lowestTask; } } else //When the drop station is not available then try to find one on the infeed station { //look for inbound tasks and check destination is available var iTasks = ElevatorTasks.Where(task => (task.Flow == TaskType.Infeed || task.Flow == TaskType.HouseKeep)).Where(task => (task.DestinationLoadAConv != null && task.DestinationLoadAConv == task.DestinationLoadBConv && task.DestinationLoadAConv.TransportSection.Route.Loads.Count == 0) || //Unload 2 at same level (task.DestinationLoadAConv != task.DestinationLoadBConv && //Unload at different levels (task.DestinationLoadAConv == null || task.DestinationLoadAConv.TransportSection.Route.Loads.Count <= 1) && (task.DestinationLoadBConv == null || task.DestinationLoadBConv.TransportSection.Route.Loads.Count <= 1))).ToList(); if (iTasks.Any()) { while (CurrentTask == null) { if (iTasks.Any()) { ElevatorTask topTask = iTasks.First(); if (topTask.Flow == TaskType.HouseKeep && ((RackConveyor)topTask.SourceLoadBConv).LocationB.ActiveLoad != null && ((RackConveyor)topTask.SourceLoadBConv).LocationB.ActiveLoad.Identification != topTask.LoadB_ID) { //If the top task is a house keep move, check that there is no load in front, blocking the path ElevatorTask frontTask = iTasks.FirstOrDefault(x => x.SourceLoadBConv == topTask.SourceLoadBConv); if (frontTask != null) { //Remove from the list iTasks = iTasks.Where(x => x != frontTask).ToList(); continue; } } CurrentTask = topTask; } else { break; //Jump out if there are no more tasks } } } } } if (CurrentTask != null) { ElevatorTask t = CurrentTask; //Log.Write(string.Format("New Task: LoadB: {0}_{1}_{2}, LoadA {3}_{4}_{5}", t.LoadB_ID, t.DropIndexLoadB, t.SourceLoadB, t.LoadA_ID, t.DropIndexLoadA, t.SourceLoadA)); } } }