public CraneScheduleStoreGet(SimSharp.Simulation environment, ICraneAgent agent) : base(environment) { Time = environment.Now; Owner = environment.ActiveProcess; Agent = agent; }
private bool PotentialCausingCollision(ICraneAgent other) { if (GoalPosition1 < _crane.GirderPosition && other.GetGirderPosition() < GetGirderPosition()) { // crane may cause collision with other in two cases if (other.GoalPosition1 <= other.GetGirderPosition()) { // 0 .... <-other .... <-crane .... MAX return(other.GetGirderPosition() + other.Width / 2 > Math.Min(Math.Min(GoalPosition1, GoalPosition2), TargetPosition) - Width / 2); } else { // 0 .... other-> .... <-crane .... MAX return(Math.Max(Math.Max(other.GoalPosition1, other.GoalPosition2), other.TargetPosition) + other.Width / 2 > Math.Min(Math.Min(GoalPosition1, GoalPosition2), TargetPosition) - Width / 2); } } else if (GoalPosition1 > _crane.GirderPosition && other.GetGirderPosition() > GetGirderPosition()) { // crane may cause collision with other in two cases if (other.GoalPosition1 >= other.GetGirderPosition()) { // 0 .... crane-> .... other-> .... MAX return(other.GetGirderPosition() - other.Width / 2 < Math.Max(Math.Max(GoalPosition1, GoalPosition2), TargetPosition) + Width / 2); } else { // 0 .... crane-> .... <-other .... MAX return(Math.Min(Math.Min(other.GoalPosition1, other.GoalPosition2), other.TargetPosition) - other.Width / 2 < Math.Max(Math.Max(GoalPosition1, GoalPosition2), TargetPosition) + Width / 2); } } return(false); }
public virtual CraneScheduleStoreGet Get(ICraneAgent agent) { var get = new CraneScheduleStoreGet(Environment.Environment, agent); GetQueue.AddLast(get); TriggerGet(); return(get); }
protected virtual void DoRequest(ZoneRequest request) { if (!Users.Any(x => IsOverlap(x, request))) { // there is no other ZoC request overlapping var cranesInZoC = World.CraneAgents.Where(x => IsOverlap(Math.Min(x.GetGirderPosition(), x.TargetPosition), Math.Max(x.GetGirderPosition(), x.TargetPosition), request.LowerPosition, request.HigherPosition)).ToList(); if (cranesInZoC.Count == 0) { // there is no crane within the ZoC Users.Add(request); request.Succeed(); } else { if (cranesInZoC.All(x => x.State == CraneAgentState.Waiting)) { // all cranes within the requested ZoC are waiting -> dodge them if possible // to calculate this, we compute how much space is available left of the ZoC and how much is available right of the ZoC var zocLeft = Users.Where(x => x.HigherPosition <= request.LowerPosition).MaxItems(x => x.HigherPosition).FirstOrDefault(); var zocRight = Users.Where(x => x.LowerPosition >= request.HigherPosition).MaxItems(x => - x.LowerPosition).FirstOrDefault(); var cranesLeft = World.CraneAgents.Where(x => x.GetGirderPosition() > (zocLeft?.LowerPosition ?? 0) && x.GetGirderPosition() <= request.LowerPosition).Sum(x => x.Width); var cranesRight = World.CraneAgents.Where(x => x.GetGirderPosition() < (zocRight?.HigherPosition ?? World.Width) && x.GetGirderPosition() >= request.HigherPosition).Sum(x => x.Width); var spaceLeftOfZoC = request.LowerPosition - (zocLeft?.HigherPosition ?? 0) - cranesLeft; var spaceRightOfZoC = (zocRight?.LowerPosition ?? World.Width) - request.HigherPosition - cranesRight; if (IsEnoughSpaceForDodge(cranesInZoC, spaceLeftOfZoC, spaceRightOfZoC)) { var sumWidth = cranesInZoC.Sum(x => x.Width); ICraneAgent goLeft = null, goRight = null; foreach (var c in cranesInZoC.OrderBy(x => x.GetGirderPosition())) { if (sumWidth <= spaceRightOfZoC) { // we can either go left or right if (c.GetGirderPosition() - request.LowerPosition > request.HigherPosition - c.GetGirderPosition()) { // going right is shorter from this crane onward goRight = c; break; } } // not enough space to accomodate all remaining cranes on the right -> this has to go left sumWidth -= c.Width; goLeft = c; } // the goLeft and goRight crane will dodge all others to move out of the way goLeft?.Dodge(request.LowerPosition - goLeft.Width / 2, 0); goRight?.Dodge(request.HigherPosition + goRight.Width / 2, 0); } } } } }
public virtual double GetClosestToTarget(ICraneAgent agent, double to) { var pos = agent.GetGirderPosition(); foreach (var u in Users) { if (IsOverlap(u.LowerPosition, u.HigherPosition, Math.Min(pos, to), Math.Max(pos, to))) { if (u.LowerPosition < pos && pos < u.HigherPosition) { World.Environment.Log($"WARNING: Crane {agent.Id} at position {pos} is within blocked zone [{u.LowerPosition}; {u.HigherPosition}] -> should not be!"); return(pos); } to = to > pos ? u.LowerPosition : u.HigherPosition; } } return(to); }
private bool IsExecutable(ICraneMoveEvent move, ICraneAgent agent) { if (move.Predecessors > 0 || move.ReleaseTime > _world.Now) { return(false); } if (!agent.CanReach(move.PickupGirderPosition) || !agent.CanReach(move.DropoffGirderPosition)) { return(false); } if (_world.CraneAgents.Any(other => other != agent && other.State != CraneAgentState.Waiting && ((other.GetGirderPosition() < agent.GetGirderPosition() && (Math.Max(other.GoalPosition1, other.GoalPosition2) + other.Width / 2 > Math.Min(move.PickupGirderPosition, move.DropoffGirderPosition) - agent.Width / 2)) || (other.GetGirderPosition() > agent.GetGirderPosition() && (Math.Min(other.GoalPosition1, other.GoalPosition2) - other.Width / 2 < Math.Max(move.PickupGirderPosition, move.DropoffGirderPosition) + agent.Width / 2))))) { return(false); } return(true); }
public virtual bool HasMovesWaiting(ICraneAgent agent) { return(Schedule.TaskSequence.Any(x => x.craneId == agent.Id)); }