/// <summary> /// Compares itself to other dominint monitors /// </summary> /// <param name="other"></param> /// <returns></returns> public int CompareToOtherDominant(IDominantMonitor other) { if (this.involved.TurnDirection == ArbiterTurnDirection.Left && this.involved.Exit != null && this.involved.Exit is ArbiterWaypoint && other.Involved.Exit != null && other.Involved.Exit is ArbiterWaypoint) { ArbiterWaypoint one = (ArbiterWaypoint)this.involved.Exit; ArbiterWaypoint two = (ArbiterWaypoint)other.Involved.Exit; if (one.Lane.Way.Segment.Equals(two.Lane.Way.Segment) && !one.Lane.Way.Equals(two.Lane.Way) && two.Exits != null && two.Exits.Count > 0) { foreach (ArbiterInterconnect ai in two.Exits) { if (ai.TurnDirection == ArbiterTurnDirection.Left) { return(0); } } } } if (this.involved.TurnDirection < other.Involved.TurnDirection) { return(-1); } else if (this.involved.TurnDirection == other.Involved.TurnDirection) { return(0); } else { return(1); } }
public int CompareToOtherDominant(IDominantMonitor other) { return(this.involved.TurnDirection.CompareTo(other.Involved.TurnDirection)); }
public int CompareToOtherDominant(IDominantMonitor other) { return this.involved.TurnDirection.CompareTo(other.Involved.TurnDirection); }
/// <summary> /// Constructor /// </summary> /// <param name="ourExit"></param> public IntersectionMonitor(ITraversableWaypoint ourExit, ArbiterIntersection ai, VehicleState ourState, IConnectAreaWaypoints desired) { // set intersection this.Intersection = ai; // create monitors this.AllMonitors = new List <IIntersectionQueueable>(); this.PriorityMonitors = new List <IIntersectionQueueable>(); this.IntersectionPriorityQueue = new List <IIntersectionQueueable>(); this.InsideIntersectionVehicles = new List <IntersectionVehicleMonitor>(); this.NonStopPriorityAreas = new List <IDominantMonitor>(); this.PreviouslyWaiting = new List <IDominantMonitor>(); this.AllMonitors = new List <IIntersectionQueueable>(); this.cooldownTimer = new Stopwatch(); #region Stopped Exits // get ours IIntersectionQueueable ourMonitor = null; // get stopped exits foreach (ArbiterStoppedExit ase in ai.StoppedExits) { // add a monitor SubmissiveEntryMonitor sem = new SubmissiveEntryMonitor(this, ase.Waypoint, ase.Waypoint.Equals(ourExit)); // add to monitors PriorityMonitors.Add(sem); // check not our if (!sem.IsOurs) { // initial update sem.Update(ourState); // check if add first if (!sem.Clear(ourState)) { IntersectionPriorityQueue.Add(sem); } } else { // set ours ourMonitor = sem; this.OurMonitor = ourMonitor; } } // check if our monitor exists if (ourMonitor != null) { // add ours this.IntersectionPriorityQueue.Add(ourMonitor); } #endregion #region Priority Areas Over Interconnect // check contains priority lane for this if (ai.PriorityLanes.ContainsKey(desired.ToInterconnect)) { // loop through all other priority monitors over this interconnect foreach (IntersectionInvolved ii in ai.PriorityLanes[desired.ToInterconnect]) { // check area type if lane if (ii.Area is ArbiterLane) { // add lane to non stop priority areas this.NonStopPriorityAreas.Add(new DominantLaneEntryMonitor(this, ii)); } // otherwise is zone else if (ii.Area is ArbiterZone) { // add lane to non stop priority areas this.NonStopPriorityAreas.Add( new DominantZoneEntryMonitor((ArbiterPerimeterWaypoint)ii.Exit, ((ArbiterInterconnect)desired), false, this, ii)); } else { throw new ArgumentException("unknown intersection involved area", "ii"); } } } // otherwise be like, wtf? else { ArbiterOutput.Output("Exception: intersection: " + this.Intersection.ToString() + " priority lanes does not contain interconnect: " + desired.ToString() + " returning can go"); //ArbiterOutput.Output("Error in intersection monitor!!!!!!!!!@Q!!, desired interconnect: " + desired.ToInterconnect.ToString() + " not found in intersection: " + ai.ToString() + ", not setting any dominant monitors"); } #endregion #region Entry Area if (desired.FinalGeneric is ArbiterWaypoint) { this.EntryAreaMonitor = new LaneEntryAreaMonitor((ArbiterWaypoint)desired.FinalGeneric); } else if (desired.FinalGeneric is ArbiterPerimeterWaypoint) { this.EntryAreaMonitor = new ZoneAreaEntryMonitor((ArbiterPerimeterWaypoint)desired.FinalGeneric, (ArbiterInterconnect)desired, false, this, new IntersectionInvolved(ourExit, ((ArbiterPerimeterWaypoint)desired.FinalGeneric).Perimeter.Zone, ((ArbiterInterconnect)desired).TurnDirection)); } else { throw new Exception("unhandled desired interconnect final type"); } #endregion #region Our Monitor // check ours if (ourExit is ArbiterWaypoint) { this.OurMonitor = new DominantLaneEntryMonitor(this, new IntersectionInvolved(ourExit, ((ArbiterWaypoint)ourExit).Lane, desired is ArbiterInterconnect ? ((ArbiterInterconnect)desired).TurnDirection : ArbiterTurnDirection.Straight)); } else if (ourExit is ArbiterPerimeterWaypoint) { // add lane to non stop priority areas this.OurMonitor = new DominantZoneEntryMonitor((ArbiterPerimeterWaypoint)desired.InitialGeneric, ((ArbiterInterconnect)desired), true, this, new IntersectionInvolved(ourExit, ((ArbiterPerimeterWaypoint)desired.InitialGeneric).Perimeter.Zone, ((ArbiterInterconnect)desired).TurnDirection)); } #endregion // add to all this.AllMonitors.AddRange(this.PriorityMonitors); foreach (IIntersectionQueueable iiq in this.NonStopPriorityAreas) { this.AllMonitors.Add(iiq); } this.AllMonitors.Add(this.EntryAreaMonitor); // update all this.Update(ourState); // check if we need to populate previously waiting if (this.OurMonitor is IDominantMonitor) { // cast our IDominantMonitor ours = (IDominantMonitor)this.OurMonitor; // loop through to determine those previously waiting foreach (IDominantMonitor idm in this.NonStopPriorityAreas) { if (idm.Waypoint != null && !idm.Waypoint.IsStop && idm.WaitingTimerRunning) { this.PreviouslyWaiting.Add(idm); } } } }
/// <summary> /// Checks if it is available for us to traverse the interconnect passed in /// </summary> /// <param name="ai"></param> /// <returns></returns> public bool CanTraverse(IConnectAreaWaypoints ai, VehicleState ourState) { // if we can go bool?canGo = null; // check for bug where interconnect not in intersection if (!this.Intersection.PriorityLanes.ContainsKey(ai.ToInterconnect)) { ArbiterOutput.Output("Exception: intersection: " + this.Intersection.ToString() + " priority lanes does not contain interconnect: " + ai.ToString() + " returning can go"); //ArbiterOutput.Output("Exception: intersection: " + this.Intersection.ToString() + " priority lanes does not contain interconnect: " + ai.ToString() + " returning can go"); //return true; } // check entry clear if (!this.EntryAreaMonitor.Clear(ourState)) { canGo = false; } // Check if we have priority if we're a stop if (ai.InitialGeneric is ArbiterWaypoint && ((ArbiterWaypoint)ai.InitialGeneric).IsStop && IntersectionPriorityQueue[0].IsOurs) { // check if intersection clear at the moment foreach (IntersectionVehicleMonitor ivm in this.InsideIntersectionVehicles) { if (!ivm.Failed(true)) { canGo = false; } } // check all priorities over us if clear foreach (IIntersectionQueueable iiq in this.NonStopPriorityAreas) { if (!iiq.Clear(ourState)) { canGo = false; } } // clear if (!canGo.HasValue) { canGo = true; } } // check if not a stop if clear else if (ai.InitialGeneric is ITraversableWaypoint && !((ITraversableWaypoint)ai.InitialGeneric).IsStop) { // get our monitor IDominantMonitor ours = (IDominantMonitor)this.OurMonitor; // check if intersection clear at the moment foreach (IntersectionVehicleMonitor ivm in this.InsideIntersectionVehicles) { if (!ivm.Failed(true)) { canGo = false; } } // check all priorities over us if clear foreach (IDominantMonitor iiq in this.NonStopPriorityAreas) { // checks if clear by default bool isClear = iiq.Clear(ourState); if (!isClear && !iiq.Waiting) { canGo = false; } if (iiq.Waiting) { ArbiterOutput.Output("DLEM: " + iiq.Area.ToString() + " vehicle waiting, hence clear"); } } // quick check if (canGo.HasValue && this.PreviouslyWaiting.Count > 0) { canGo = false; } else { // check if previously waiting doesn't exist foreach (IDominantMonitor idm in this.PreviouslyWaiting) { // check if waiting for this person excessively if (!idm.ExcessiveWaiting) { canGo = false; } } } // clear if (!canGo.HasValue) { canGo = true; } } // nope, can't go if fall through if (!canGo.HasValue) { canGo = false; } #region Cooldown // final boolean if we can go bool finalGo = canGo.Value; if (finalGo) { ArbiterOutput.Output("Can Traverse, Cooling Down"); if (cooldownTimer.IsRunning) { if ((cooldownTimer.ElapsedMilliseconds / 1000.0) > 1.0) { return(true); } else { return(false); } } else { cooldownTimer.Reset(); cooldownTimer.Start(); return(false); } } else { if (cooldownTimer.IsRunning) { cooldownTimer.Stop(); cooldownTimer.Reset(); } return(false); } #endregion }
/// <summary> /// Compares itself to other dominint monitors /// </summary> /// <param name="other"></param> /// <returns></returns> public int CompareToOtherDominant(IDominantMonitor other) { if (this.involved.TurnDirection == ArbiterTurnDirection.Left && this.involved.Exit != null && this.involved.Exit is ArbiterWaypoint && other.Involved.Exit != null && other.Involved.Exit is ArbiterWaypoint) { ArbiterWaypoint one = (ArbiterWaypoint)this.involved.Exit; ArbiterWaypoint two = (ArbiterWaypoint)other.Involved.Exit; if (one.Lane.Way.Segment.Equals(two.Lane.Way.Segment) && !one.Lane.Way.Equals(two.Lane.Way) && two.Exits != null && two.Exits.Count > 0) { foreach (ArbiterInterconnect ai in two.Exits) { if (ai.TurnDirection == ArbiterTurnDirection.Left) return 0; } } } if (this.involved.TurnDirection < other.Involved.TurnDirection) return -1; else if (this.involved.TurnDirection == other.Involved.TurnDirection) return 0; else return 1; }