private IEnumerable <Event> MoveCraneVertical(HoistAction action, int level, IStackingLocation stack = null) { moveStart = Now; fromPos = World.Crane.HoistPosition; toPos = CalculateHoistPosition(level); moveDirection = MoveDirection.Vertical; var low = settings.HoistMoveTimeMean.TotalSeconds - settings.HoistMoveTimeStd.TotalSeconds; var high = settings.HoistMoveTimeMean.TotalSeconds + settings.HoistMoveTimeStd.TotalSeconds; moveDuration = TimeSpan.FromSeconds(sim.RandTriangular(craneRNG, low, high) * Math.Abs(toPos - fromPos)); yield return(sim.Timeout(moveDuration)); if (action == HoistAction.Pickup) { World.Crane.Load = stack.Pickup(); //sim.Log($"{Now} Crane picked up block ({World.Crane.Load.Id}) at location {World.Crane.LocationId}"); World.KPIs.CraneManipulations++; } else if (action == HoistAction.Dropoff) { var block = World.Crane.Load; stack.Drop(block); World.Crane.Load = null; //sim.Log($"{Now} Crane dropped off block ({block.Id}) at location {World.Crane.LocationId}"); } BufferUtilization.UpdateTo(World.Buffers.Sum(x => x.Height) / (double)World.Buffers.Sum(x => x.MaxHeight)); World.KPIs.BufferUtilizationMean = BufferUtilization.Mean; World.Crane.HoistPosition = toPos; fromPos = toPos; OnWorldChanged(); }
private void InitializeWorldState() { var rand = new Random(settings.Seed); var initRand = new PcgRandom(rand.Next()); craneRNG = new PcgRandom(rand.Next()); productionRNG = new PcgRandom(rand.Next()); handoverRNG = new PcgRandom(rand.Next()); readyRNG = new PcgRandom(rand.Next()); var capacity = World.Buffers.Sum(x => x.MaxHeight); var past = sim.Now; for (var i = 0; i < settings.InitialNumberOfBlocks; i++) { past -= sim.RandLogNormal2(initRand, settings.ArrivalTimeMean, settings.ArrivalTimeStd); var b = new Block() { Id = ++blockIds, Release = ToTimeStamp(past), Ready = false, Due = ToTimeStamp(past + sim.RandLogNormal2(initRand, settings.DueTimeMean, settings.DueTimeStd)) }; while (b.Due < ToTimeStamp(sim.Now + settings.DueTimeMin)) { b.Due += sim.RandLogNormal2(initRand, settings.DueTimeMean, settings.DueTimeStd); } var readyFactor = settings.ReadyFactorMin + initRand.NextDouble() * (settings.ReadyFactorMax - settings.ReadyFactorMin); b.Ready = (b.Release + TimeSpan.FromSeconds(readyFactor * (b.Due - b.Release).TotalSeconds)) < Now; var possibleBuffers = World.Buffers.Where(x => x.BottomToTop.Count < x.MaxHeight).ToList(); var buf = possibleBuffers[initRand.Next(possibleBuffers.Count)]; if (buf.BottomToTop.Count == 0) { buf.BottomToTop.Add(b); } else { buf.BottomToTop.Insert(0, b); } sim.Process(BlockProcess(b, suppressEvent: true)); } BufferUtilization.UpdateTo(World.Buffers.Sum(x => x.Height) / (double)World.Buffers.Sum(x => x.MaxHeight)); World.KPIs.BufferUtilizationMean = BufferUtilization.Mean; World.Production.BottomToTop.Add(new Block() { Id = ++blockIds, Release = ToTimeStamp(sim.Now), Ready = false, Due = ToTimeStamp(sim.Now + sim.RandLogNormal2(initRand, settings.DueTimeMean, settings.DueTimeStd)) }); World.Handover.Ready = true; sim.Process(BlockProcess(World.Production.BottomToTop.Single(), suppressEvent: true)); sim.Process(WorldUpdates()); }