/// <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);
            }
        }
Пример #2
0
 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);
 }
Пример #4
0
        /// <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);
                    }
                }
            }
        }
Пример #5
0
        /// <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;
        }