/// <summary> /// As the accumilation conveyor length is not set conventually it is set via positions, outfeedsection /// infeedsection and AccPitch. We have to wait until all these are set. So we need this method to place /// transition points. /// </summary> public void ConvLocationConfiguration(string level) { // TransportSection.Route.InsertActionPoint(ExitPoint, Length); // TransportSection.Route.InsertActionPoint(EnterPoint, 0); foreach (AccumulationSensor sensor in sensors) { int convPosName; if (int.TryParse(sensor.sensor.Name, out convPosName) && convPosName == 0) { sensor.sensor.OnEnter += sensor_OnEnter1; sensor.sensor.OnLeave += sensor_OnLeave; Location1 = sensor.sensor; //Location1.LocName = string.Format("{0}{1}{2}{3}{4}", AisleNumber.ToString().PadLeft(2, '0'), (char)Side, Level.ToString().PadLeft(2, '0'), (char)ConveyorTypes.Drop, "B"); Location1.LocName = string.Format("{0}{1}{2}{3}{4}", AisleNumber.ToString().PadLeft(2, '0'), (char)Side, level, (char)ConveyorTypes.Drop, "B"); ParentMultishuttle.ConveyorLocations.Add(Location1); } else if (int.TryParse(sensor.sensor.Name, out convPosName) && convPosName == 1) { sensor.sensor.OnEnter += sensor_OnEnter2; sensor.sensor.OnLeave += sensor_OnLeave; Location2 = sensor.sensor; //Location2.LocName = string.Format("{0}{1}{2}{3}{4}", AisleNumber.ToString().PadLeft(2, '0'), (char)Side, Level.ToString().PadLeft(2, '0'), (char)ConveyorTypes.Drop, "A"); Location2.LocName = string.Format("{0}{1}{2}{3}{4}", AisleNumber.ToString().PadLeft(2, '0'), (char)Side, level, (char)ConveyorTypes.Drop, "A"); ParentMultishuttle.ConveyorLocations.Add(Location2); } } // Location1.Visible = true; }
/// <summary> /// As the accumilation conveyor length is not set conventually it is set via positions, outfeedsection /// infeedsection and AccPitch. We have to wait until all these are set. So we need this method to place /// transition points. /// </summary> public void ConvLocationConfiguration(string level) { Leaving.OnEnter += Leaving_OnEnter; RouteStatus nextRouteStatus = new RouteStatus() { Available = RouteStatuses.Available }; NextRouteStatus = nextRouteStatus; Leaving.Distance = Length; foreach (AccumulationSensor sensor in sensors) { //The accumilation conveyor PEC last (wrt the load travel direction) position is called "0", this is position 2 for the multishuttle. //The accumilation conveyor PEC second from last position (wrt the load travel direction) is called "1", this is position 1 for the multishuttle. int convPosName; if (int.TryParse(sensor.sensor.Name, out convPosName) && convPosName == 0) { LocationB = sensor.sensor; LocationB.LocName = string.Format("{0}{1}{2}{3}{4}", AisleNumber.ToString().PadLeft(2, '0'), (char)Side, level, (char)ConveyorTypes.Pick, "B"); ParentMultiShuttle.ConveyorLocations.Add(LocationB); sensor.sensor.OnEnter += sensor_OnEnterB; //sensor.sensor.OnLeave += sensor_OnLeave2; //sensor.sensor.leaving.Edge = ActionPoint.Edges.Leading; //sensor.sensor.leaving.Distance = sensor.sensor.leaving.Distance + 0.02f;//ParentMultiShuttle.workarround; //Workaround for a load switiching to another conveyor whilst blocking a sensor, hopfully Xcelgo will fix this } else if (int.TryParse(sensor.sensor.Name, out convPosName) && convPosName == 1) { LocationA = sensor.sensor; LocationA.LocName = string.Format("{0}{1}{2}{3}{4}", AisleNumber.ToString().PadLeft(2, '0'), (char)Side, level, (char)ConveyorTypes.Pick, "A"); ParentMultiShuttle.ConveyorLocations.Add(sensor.sensor); sensor.sensor.OnEnter += sensor_OnEnterA; } } LocationB.Visible = false; }
/// <summary> /// As the accumilation conveyor length is not set conventually it is set via positions, outfeedsection /// infeedsection and AccPitch. We have to wait until all these are set. So we need this method to place /// transition points. /// </summary> public void ConvLocationConfiguration(string level) { foreach (AccumulationSensor sensor in sensors) { int convPosName; if (int.TryParse(sensor.sensor.Name, out convPosName) && convPosName == 0) { sensor.sensor.OnEnter += sensor_OnEnter1; sensor.sensor.OnLeave += sensor_OnLeave; Location1 = sensor.sensor; Location1.LocName = string.Format("{0}{1}{2}{3}{4}", AisleNumber.ToString().PadLeft(2, '0'), (char)Side, level, (char)ConveyorTypes.Drop, "B"); ParentMultishuttle.ConveyorLocations.Add(Location1); } else if (int.TryParse(sensor.sensor.Name, out convPosName) && convPosName == 1) { sensor.sensor.OnEnter += sensor_OnEnter2; sensor.sensor.OnLeave += sensor_OnLeave; Location2 = sensor.sensor; Location2.LocName = string.Format("{0}{1}{2}{3}{4}", AisleNumber.ToString().PadLeft(2, '0'), (char)Side, level, (char)ConveyorTypes.Drop, "A"); ParentMultishuttle.ConveyorLocations.Add(Location2); } } }
/// <summary> /// Tasks are split into elevator task and shuttle task this method gives you the corrent rack location (i.e. the destination for an infeed elevator task) /// </summary> /// <param name="messageA">Can be either a full message or just the destination</param> /// <param name="multipal">We need to know if it is multipal as we need to know if we need to extract destinations or destination</param> /// <returns>A rack destination that the assembly will understand</returns> private string GetRackDestinationFromDCIBinLocation(string telegram, int blockPosition) { string dest = null, current = null; current = telegram.GetFieldValue(this, TelegramFields.Current, blockPosition); dest = telegram.GetFieldValue(this, TelegramFields.Destination, blockPosition); //Need to make the intermediate position to the rack conveyor //takes the form aasyyxz: aa=aisle, s = side, yy = level, x = conv type see enum ConveyorTypes , Z = loc A or B e.g. 01R05OA //The actual final destination from the message is stored on a load parameter and this will be used when creating the shuttle task MultiShuttle ms = GetMultishuttleFromAisleNum(GetPSDSLocFields(current, PSDSRackLocFields.Aisle)); string destinationLoc = string.Format("{0}{1}{2}IA", GetPSDSLocFields(current, PSDSRackLocFields.Aisle), GetPSDSLocFields(current, PSDSRackLocFields.Side), GetBinLocField(dest, BinLocFields.YLoc)); DematicActionPoint ap = ms.ConveyorLocations.Find(x => x.LocName == destinationLoc); if (ap == null) { Log.Write("Can't find location in MHEController_Multishuttle.GetRackDestinationFromDCIBinLocation.", Color.Red); return(null); } return(destinationLoc); }
private void SendULData() { foreach (MultiShuttle ms in multishuttles) { var dematicActionPoints = ms.ConveyorLocations.FindAll(x => x.Active); var caseLoads = dematicActionPoints.Select(x => x.ActiveLoad); foreach (Case_Load caseload in caseLoads) { CaseData cData = (CaseData)caseload.Case_Data; if (cData.CurrentPosition.Length == 0) { continue; } //MSC sends type 31 for every place (other than the PS) which has unit load data if (cData.CurrentPosition.Datcom_Location() == "P") { continue; } string body = CreateMissionDataSetBody(cData); SendTelegram("31", body, 1); if (cData.CurrentPosition.Length >= 10 && cData.CurrentPosition.Datcom_Location() == "I" && cData.CurrentPosition.Datcom_X_horizontal() == "002" && cData.DestinationPosition.Datcom_Location() != "I") { //Caseload is on infeed rack conveyor position 002. Destination is not Infeed so shuttle car has got a mission. Send 31 with current position = shuttle car and status 02 pending. //Remap will be sent from two locations: //1. From Rack Conveyor, present location is rack conveyor (pos2), status ‘00’ //2. From shuttle car, present location is shuttle car with mission status ‘02’ (Pending) //If mission is not also remapped from shuttle, MFH should re-send mission. //If mission reported from shuttle but status is not ’02’, remap should be failed. //If mission is remapped from shuttle only with status ‘02’. This should also cause remap failure. //Create telegram body with mission status 02 pending and current is shuttlecar string current = cData.CurrentPosition; string level = current.Substring(8, 2); cData.CurrentPosition = "S" + ms.AisleNumber + " " + level; cData.MissionStatus = "02"; body = CreateMissionDataSetBody(cData); //Restore current and mission status cData.CurrentPosition = current; cData.MissionStatus = "00"; SendTelegram("31", body, 1); } } foreach (PickStationConveyor conv in ms.PickStationConveyors) { //MSC sends type 35 for Pick Station unit loads DematicActionPoint ap1 = conv.LocationA; DematicActionPoint ap2 = conv.LocationB; if (ap2.Active) { Case_Load caseload2 = ap2.ActiveLoad as Case_Load; conv.psTimeoutTimer.Stop(); caseload2.Stop(); //update current position ((CaseData)caseload2.Case_Data).CurrentPosition = string.Format("P{0}{1}{2}001{3}", ap2.LocName.AisleNumber().ToString().PadLeft(2, '0'), ms.ElevatorGroup(ap2.LocName), (char)(ap2.LocName.Side()), //ap2.LocName.ConvPosition(), ap2.LocName.Level()); //TODO elevator group Case_Load caseload1 = ap1.ActiveLoad as Case_Load; if (caseload1 != null) { //update current position //update current position ((CaseData)caseload1.Case_Data).CurrentPosition = string.Format("P{0}{1}{2}002{3}", ap1.LocName.AisleNumber().ToString().PadLeft(2, '0'), ms.ElevatorGroup(ap1.LocName), (char)(ap1.LocName.Side()), //ap1.LocName.Datcom_X_horizontal(), ap1.LocName.Level()); //TODO elevator group } string body = CreatePickStationDataSetBody(caseload2, caseload1); SendTelegram("35", body, 1); } } } }
private void TUMissionMultiBlock(string telegram) { string currentLoc = string.Empty; DematicActionPoint locA = null, locB = null; MultiShuttle ms = null; TelegramTypes type = telegram.GetTelegramType(this); //List<string> indexTags; //List<string> messageBodies = Telegrams.DeMultaplise(telegram, telegram.GetTelegramType(), out indexTags); //string[] messageBodySplit = messageBodies.First().Split(',');//don't care which message is used as both on the same conveyor string current = telegram.GetFieldValue(this, TelegramFields.Current); string destLoc0 = telegram.GetFieldValue(this, TelegramFields.Destination, 0); string destLoc1 = telegram.GetFieldValue(this, TelegramFields.Destination, 1); string tuIdent0 = telegram.GetFieldValue(this, TelegramFields.TUIdent, 0); string tuIdent1 = telegram.GetFieldValue(this, TelegramFields.TUIdent, 1); string aisle = GetPSDSLocFields(current, PSDSRackLocFields.Aisle); string side = GetPSDSLocFields(current, PSDSRackLocFields.Side); string destA = null, destB = null; // takes the form aasyyxz: aa=aisle, s = side, yy = level, x = conv type see enum ConveyorTypes , Z = loc A or B e.g. 01R05OA string loc = string.Format("{0}{1}{2}P", aisle, side, GetPSDSLocFields(current, PSDSRackLocFields.Level)); ms = GetMultishuttleFromAisleNum(loc + "A"); locA = ms.ConveyorLocations.Find(x => x.LocName == loc + "A"); locB = ms.ConveyorLocations.Find(x => x.LocName == loc + "B"); if ((locA != null && locA.Active) && (locB != null && locB.Active)) { string messageA = telegram.Split(',').ToList().Find(x => x.Contains(locA.ActiveLoad.Identification)); string messageB = telegram.Split(',').ToList().Find(x => x.Contains(locB.ActiveLoad.Identification)); if (destLoc0 == null || destLoc1 == null) { Log.Write(string.Format("{0}: Invalid destinations sent in TUMission - Logically Grouped", Name), Color.Red); return; } if (telegram.GetFieldValue(this, TelegramFields.Destination, 0).LocationType() == LocationTypes.DropStation) //Assume that both going to DS { destA = string.Format("{0}{1}{2}{3}A", aisle, side, GetPSDSLocFields(destLoc0, PSDSRackLocFields.Level), GetPSDSLocFields(destLoc0, PSDSRackLocFields.ConvType)); destB = destA; } else if (telegram.GetFieldValue(this, TelegramFields.Destination).LocationType() == LocationTypes.RackConvIn) { //need to calculate which way around the loads are on the PS and ensure that the elevator task is correct if (locA.ActiveLoad.Identification == tuIdent0) { destA = string.Format("{0}{1}{2}{3}B", aisle, side, GetLocFields(destLoc0, PSDSRackLocFields.Level), GetLocFields(destLoc0, PSDSRackLocFields.ConvType)); } else if (locA.ActiveLoad.Identification == tuIdent1) { destA = string.Format("{0}{1}{2}{3}B", aisle, side, GetLocFields(destLoc1, PSDSRackLocFields.Level), GetLocFields(destLoc1, PSDSRackLocFields.ConvType)); } else { Log.Write(string.Format("Error {0}: The tuIdent at the PS does not match the tuIdent in the TU Mission - Logically Grouped (Position A"), Color.Orange); return; } if (locB.ActiveLoad.Identification == tuIdent0) { destB = string.Format("{0}{1}{2}{3}B", aisle, side, GetLocFields(destLoc0, PSDSRackLocFields.Level), GetLocFields(destLoc0, PSDSRackLocFields.ConvType)); } else if (locB.ActiveLoad.Identification == tuIdent1) { destB = string.Format("{0}{1}{2}{3}B", aisle, side, GetLocFields(destLoc1, PSDSRackLocFields.Level), GetLocFields(destLoc1, PSDSRackLocFields.ConvType)); } else { Log.Write(string.Format("Error {0}: The tuIdent at the PS does not match the tuIdent in the TU Mission - Logically Grouped (Position A"), Color.Orange); return; } } else { destA = GetRackDestinationFromDCIBinLocation(telegram, 0); destB = GetRackDestinationFromDCIBinLocation(telegram, 1); } if (messageA != null && messageB != null) { ElevatorTask et = new ElevatorTask(locA.ActiveLoad.Identification, locB.ActiveLoad.Identification) { LoadCycle = Cycle.Double, Flow = TaskType.Infeed, SourceLoadA = locA.LocName, SourceLoadB = locB.LocName, DestinationLoadA = destA, DestinationLoadB = destB, UnloadCycle = Cycle.Single }; if (et.DestinationLoadA == et.DestinationLoadB) { et.UnloadCycle = Cycle.Double; } UpDateLoadParameters(telegram, (Case_Load)locA.ActiveLoad, 1); UpDateLoadParameters(telegram, (Case_Load)locB.ActiveLoad, 0); ms.elevators.First(x => x.ElevatorName == side + aisle).ElevatorTasks.Add(et); //ms.elevators[side+aisle].ElevatorTasks.Add(et); } else { Log.Write("ERROR: Load ids from telegram do not match active load ids in TU Mission - Logically Grouped", Color.Red); return; } } else { Log.Write("ERROR: Can't find locations or can't find loads on the locations named in TU Mission - Logically Grouped", Color.Red); } }