/// <summary>
        /// Helps with parameterizations for lateral reasoning
        /// </summary>
        /// <param name="referenceLane"></param>
        /// <param name="fqmLane"></param>
        /// <param name="goal"></param>
        /// <param name="vehicleFront"></param>
        /// <returns></returns>
        public TravelingParameters ParameterizationHelper(ArbiterLane referenceLane, ArbiterLane fqmLane,
            Coordinates goal, Coordinates vehicleFront, IState nextState, VehicleState state, VehicleAgent va)
        {
            // get traveling parameterized list
            List<TravelingParameters> tps = new List<TravelingParameters>();

            // get distance to the goal
            double goalDistance;
            double goalSpeed;
            this.StoppingParams(goal, referenceLane, vehicleFront, new double[] { }, out goalSpeed, out goalDistance);
            tps.Add(this.GetParameters(referenceLane, goalSpeed, goalDistance, state));

            // get next stop
            ArbiterWaypoint stopPoint;
            double stopSpeed;
            double stopDistance;
            StopType stopType;
            this.NextLaneStop(fqmLane, vehicleFront, new double[] { }, new List<ArbiterWaypoint>(),
                out stopPoint, out stopSpeed, out stopDistance, out stopType);
            this.StoppingParams(stopPoint.Position, referenceLane, vehicleFront, new double[] { },
                out stopSpeed, out stopDistance);
            tps.Add(this.GetParameters(referenceLane, stopSpeed, stopDistance, state));

            // get vehicle
            if (va != null)
            {
                VehicleAgent tmp = this.ForwardVehicle.CurrentVehicle;
                double tmpDist = this.ForwardVehicle.currentDistance;
                this.ForwardVehicle.CurrentVehicle = va;
                this.ForwardVehicle.currentDistance = referenceLane.DistanceBetween(state.Front, va.ClosestPosition);
                TravelingParameters tp = this.ForwardVehicle.Follow(referenceLane, state, new List<ArbiterWaypoint>());
                tps.Add(tp);
                this.ForwardVehicle.CurrentVehicle = tmp;
                this.ForwardVehicle.currentDistance = tmpDist;
            }

            // parameterize
            tps.Sort();
            return tps[0];
        }
        public bool VehiclePassableInPolygon(ArbiterLane al, VehicleAgent va, Polygon p, VehicleState ourState, Polygon circ)
        {
            Polygon vehiclePoly = va.GetAbsolutePolygon(ourState);
            vehiclePoly = Polygon.ConvexMinkowskiConvolution(circ, vehiclePoly);
            List<Coordinates> pointsOutside = new List<Coordinates>();
            ArbiterLanePartition alp = al.GetClosestPartition(va.ClosestPosition);

            foreach(Coordinates c in vehiclePoly)
            {
                if (!p.IsInside(c))
                    pointsOutside.Add(c);
            }

            foreach (Coordinates m in pointsOutside)
            {
                foreach (Coordinates n in pointsOutside)
                {
                    if(!m.Equals(n))
                    {
                        if (GeneralToolkit.TriangleArea(alp.Initial.Position, m, alp.Final.Position) *
                            GeneralToolkit.TriangleArea(alp.Initial.Position, n, alp.Final.Position) < 0)
                        {
                            return false;
                        }
                    }
                }
            }

            return true;
        }
        /// <summary>
        /// Updates this monitor
        /// </summary>
        public void Update(VehicleState ourState)
        {
            // make sure not our vehicle
            if (!isOurs)
            {
                // get a list of vehicles possibly in the exit
                List<VehicleAgent> stopVehicles = new List<VehicleAgent>();

                // check all valid vehicles
                foreach (VehicleAgent va in TacticalDirector.ValidVehicles.Values)
                {
                    // check if any of the point inside the polygon
                    for (int i = 0; i < va.StateMonitor.Observed.relativePoints.Length; i++)
                    {
                        // get abs coord
                        Coordinates c = va.TransformCoordAbs(va.StateMonitor.Observed.relativePoints[i], ourState);

                        // check if inside poly
                        if (this.stoppedExit.ExitPolygon.IsInside(c) && !stopVehicles.Contains(va))
                        {
                            // add vehicle
                            stopVehicles.Add(va);
                        }
                    }
                }

                // check occluded
                foreach (VehicleAgent va in TacticalDirector.OccludedVehicles.Values)
                {
                    // check if any of the point inside the polygon
                    for (int i = 0; i < va.StateMonitor.Observed.relativePoints.Length; i++)
                    {
                        // get abs coord
                        Coordinates c = va.TransformCoordAbs(va.StateMonitor.Observed.relativePoints[i], ourState);

                        // check if inside poly
                        if (this.stoppedExit.ExitPolygon.IsInside(c) && !stopVehicles.Contains(va))
                        {
                            // add vehicle
                            ArbiterOutput.Output("Added occluded vehicle: " + va.ToString() + " to SEM: " + this.stoppedExit.ToString());
                            stopVehicles.Add(va);
                        }
                    }
                }

                // check if we already have a vehicle we are referencing
                if (this.currentVehicle != null && !stopVehicles.Contains(this.currentVehicle))
                {
                    // get the polygon of the current vehicle	and inflate a tiny bit?
                    Polygon p = this.currentVehicle.GetAbsolutePolygon(ourState);
                    p = p.Inflate(1.0);

                    // Vehicle agent to switch to if exists
                    VehicleAgent newer = null;
                    double distance = Double.MaxValue;

                    // check for closest vehicle to exist in that polygon
                    foreach (VehicleAgent va in TacticalDirector.ValidVehicles.Values)
                    {
                        // check if vehicle is stopped
                        if (stopVehicles.Contains(va))
                        {
                            // get distance to stop
                            double stopLineDist;
                            va.ClosestPointTo(this.stoppedExit.Waypoint.Position, ourState, out stopLineDist);

                            // check all vehicle points
                            foreach (Coordinates rel in va.StateMonitor.Observed.relativePoints)
                            {
                                Coordinates abs = va.TransformCoordAbs(rel, ourState);
                                double tmpDist = stopLineDist;

                                // check for the clsoest with points inside vehicle
                                if (p.IsInside(abs) && (newer == null || tmpDist < distance))
                                {
                                    newer = va;
                                    distance = tmpDist;
                                }
                            }
                        }
                    }

                    // check if we can switch vehicles
                    if (newer != null)
                    {
                        ArbiterOutput.Output("For StopLine: " + this.stoppedExit.ToString() + " switched vehicleId: " + this.currentVehicle.VehicleId.ToString() + " for vehicleId: " + newer.VehicleId.ToString());
                        this.currentVehicle = newer;
                        this.NotFoundPrevious = notFoundDefault;
                    }
                    else if(NotFoundPrevious == 0)
                    {
                        // set this as not having a vehicle
                        this.currentVehicle = null;

                        // set not found before
                        this.NotFoundPrevious = this.notFoundDefault;

                        // stop timers
                        this.timer.Stop();
                        this.timer.Reset();
                    }
                    else
                    {
                        // set not found before
                        this.NotFoundPrevious--;
                        ArbiterOutput.Output("current not found, not found previous: " + this.NotFoundPrevious.ToString() + ", at stopped exit: " + this.stoppedExit.Waypoint.ToString());
                    }
                }
                // update the current vehicle
                else if (this.currentVehicle != null && stopVehicles.Contains(this.currentVehicle))
                {
                    // udpate current
                    this.currentVehicle = stopVehicles[stopVehicles.IndexOf(this.currentVehicle)];

                    // set as found previous
                    this.NotFoundPrevious = this.notFoundDefault;

                    // check if need to update timer
                    if (this.currentVehicle.IsStopped && !this.timer.IsRunning)
                    {
                        this.timer.Stop();
                        this.timer.Reset();
                        this.timer.Start();
                    }
                    // otherwise check if moving
                    else if (!this.currentVehicle.IsStopped && this.timer.IsRunning)
                    {
                        this.timer.Stop();
                        this.timer.Reset();
                    }
                }
                // otherwise if we have no vehicle and exist vehicles in stop area
                else if (this.currentVehicle == null && stopVehicles.Count > 0)
                {
                    // get closest vehicle to the stop
                    VehicleAgent toTrack = null;
                    double distance = Double.MaxValue;

                    // set as found previous
                    this.NotFoundPrevious = this.notFoundDefault;

                    // loop through
                    foreach (VehicleAgent va in stopVehicles)
                    {
                        // check if vehicle is stopped
                        if (va.IsStopped)
                        {
                            // distance of vehicle to stop line
                            double distanceToStop;
                            Coordinates closestToStop = va.ClosestPointTo(this.stoppedExit.Waypoint.Position, ourState, out distanceToStop).Value;

                            // check if we don't have one or tmp closer than tracked
                            if (toTrack == null || distanceToStop < distance)
                            {
                                toTrack = va;
                                distance = distanceToStop;
                            }
                        }
                    }

                    // check if we have one to track
                    if (toTrack != null)
                        this.currentVehicle = toTrack;
                }
            }
        }
        /// <summary>
        /// Populates mapping of vehicles we want to track given state
        /// </summary>
        /// <param name="vehicles"></param>
        public void PopulateValidVehicles(SceneEstimatorTrackedClusterCollection vehicles)
        {
            TacticalDirector.NewVehicles = new List<VehicleAgent>();
            TacticalDirector.OccludedVehicles = new Dictionary<int, VehicleAgent>();

            if (TacticalDirector.ValidVehicles == null)
                TacticalDirector.ValidVehicles = new Dictionary<int, VehicleAgent>();

            List<int> toRemove = new List<int>();
            foreach (VehicleAgent va in TacticalDirector.ValidVehicles.Values)
            {
                bool found = false;
                for (int i = 0; i < vehicles.clusters.Length; i++)
                {
                    if (vehicles.clusters[i].id.Equals(va.VehicleId))
                        found = true;
                }

                if (!found)
                    toRemove.Add(va.VehicleId);
            }
            foreach (int r in toRemove)
                TacticalDirector.ValidVehicles.Remove(r);

            for(int i = 0; i < vehicles.clusters.Length; i++)
            {
                SceneEstimatorTrackedCluster ov = vehicles.clusters[i];
                bool clusterStopped = ov.isStopped;
                if (ov.statusFlag == SceneEstimatorTargetStatusFlag.TARGET_STATE_ACTIVE ||
                    (ov.statusFlag == SceneEstimatorTargetStatusFlag.TARGET_STATE_OCCLUDED_PART && !clusterStopped) ||
                    (ov.statusFlag == SceneEstimatorTargetStatusFlag.TARGET_STATE_OCCLUDED_FULL && !clusterStopped))
                {
                    if (ov.targetClass == SceneEstimatorTargetClass.TARGET_CLASS_CARLIKE)
                    {
                        if (TacticalDirector.ValidVehicles.ContainsKey(ov.id))
                            TacticalDirector.ValidVehicles[ov.id].StateMonitor.Observed = ov;
                        else
                        {
                            VehicleAgent ovNew = new VehicleAgent(ov);
                            TacticalDirector.ValidVehicles.Add(ovNew.VehicleId, ovNew);
                            TacticalDirector.NewVehicles.Add(ovNew);
                        }
                    }
                    else
                    {
                        if (TacticalDirector.ValidVehicles.ContainsKey(ov.id))
                            TacticalDirector.ValidVehicles.Remove(ov.id);
                    }
                }
                else
                {
                    if (TacticalDirector.ValidVehicles.ContainsKey(ov.id))
                        TacticalDirector.ValidVehicles.Remove(ov.id);
                }

                if ((ov.statusFlag == SceneEstimatorTargetStatusFlag.TARGET_STATE_OCCLUDED_PART && clusterStopped) ||
                    (ov.statusFlag == SceneEstimatorTargetStatusFlag.TARGET_STATE_OCCLUDED_FULL && clusterStopped))
                    TacticalDirector.OccludedVehicles.Add(ov.id, new VehicleAgent(ov));
            }
        }
        public bool VehicleExistsInsidePolygon(VehicleAgent va, Polygon p, VehicleState ourState)
        {
            for (int i = 0; i < va.StateMonitor.Observed.relativePoints.Length; i++)
            {
                Coordinates c = va.TransformCoordAbs(va.StateMonitor.Observed.relativePoints[i], ourState);
                if (p.IsInside(c))
                    return true;
            }

            return false;
        }
        /// <summary>
        /// Resets values held over time
        /// </summary>
        public void Reset()
        {
            if (this.CurrentVehicle != null)
                this.CurrentVehicle.Reset();

            this.CurrentVehicle = null;
            this.currentDistance = Double.MaxValue;
        }
        /// <summary>
        /// Given vehicles and there locations determines if the lane adjacent to us is occupied adjacent to the vehicle
        /// </summary>
        /// <param name="lane"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        public bool Occupied(ArbiterLane lane, VehicleState state)
        {
            // check stopwatch time for proper elapsed
            if (this.LateralClearStopwatch.ElapsedMilliseconds / 1000.0 > 10)
                this.Reset();

            if (TacticalDirector.VehicleAreas.ContainsKey(lane))
            {
                // vehicles in the lane
                List<VehicleAgent> laneVehicles = TacticalDirector.VehicleAreas[lane];

                // position of the center of our vehicle
                Coordinates center = state.Front - state.Heading.Normalize(TahoeParams.VL / 2.0);

                // cutoff for allowing vehicles outside this range
                double dCutOff = TahoeParams.VL * 1.5;

                // loop through vehicles
                foreach (VehicleAgent va in laneVehicles)
                {
                    // vehicle high level distance
                    double d = Math.Abs(lane.DistanceBetween(center, va.ClosestPosition));

                    // check less than distance cutoff
                    if (d < dCutOff)
                    {
                        ArbiterOutput.Output("Forward Lateral: " + this.VehicleSide.ToString() + " filled with vehicle: " + va.ToString());
                        this.CurrentVehicle = va;
                        this.Reset();
                        return true;
                    }
                }
            }

            // now check the lateral sensor for being occupied
            if (this.SideSickObstacleDetected(lane, state))
            {
                this.CurrentVehicle = new VehicleAgent(true, true);
                this.Reset();
                ArbiterOutput.Output("Forward Lateral: " + this.VehicleSide.ToString() + " SIDE OBSTACLE DETECTED");
                return true;
            }

            // none found
            this.CurrentVehicle = null;

            // if none found, timer not running start timer
            if (!this.LateralClearStopwatch.IsRunning)
            {
                this.CurrentVehicle = new VehicleAgent(true, true);
                this.Reset();
                this.LateralClearStopwatch.Start();
                ArbiterOutput.Output("Forward Lateral: " + this.VehicleSide.ToString() + " Clear, starting cooldown");
                return true;
            }
            // check enough time
            else if (this.LateralClearStopwatch.IsRunning && this.LateralClearStopwatch.ElapsedMilliseconds / 1000.0 > 0.5)
            {
                this.CurrentVehicle = null;
                ArbiterOutput.Output("Forward Lateral: " + this.VehicleSide.ToString() + " Clear, cooldown complete");
                return false;
            }
            // not enough time
            else
            {
                this.CurrentVehicle = new VehicleAgent(true, true);
                double timer = this.LateralClearStopwatch.ElapsedMilliseconds / 1000.0;
                ArbiterOutput.Output("Forward Lateral: " + this.VehicleSide.ToString() + " Clear, cooldown timer: " + timer.ToString("F2"));
                return true;
            }
        }
        /// <summary>
        /// Update the rear monitor with the closest vehicle in the rear
        /// </summary>
        /// <param name="state"></param>
        public void Update(VehicleState state)
        {
            // get the forward path
            LinePath p = lane.LanePath();

            // get our position
            Coordinates f = state.Front - state.Heading.Normalize(TahoeParams.VL);

            // get all vehicles associated with those components
            List<VehicleAgent> vas = new List<VehicleAgent>();
            foreach (IVehicleArea iva in lane.AreaComponents)
            {
                if (TacticalDirector.VehicleAreas.ContainsKey(iva))
                    vas.AddRange(TacticalDirector.VehicleAreas[iva]);
            }

            // get the closest forward of us
            double minDistance = Double.MaxValue;
            VehicleAgent closest = null;

            // get clsoest
            foreach (VehicleAgent va in vas)
            {
                // get position of front
                Coordinates frontPos = va.ClosestPosition;
                double frontDist = lane.DistanceBetween(frontPos, f);

                if (frontDist >= 0 && frontDist < minDistance)
                {
                    minDistance = frontDist;
                    closest = va;
                }
            }

            this.CurrentVehicle = closest;
            this.currentDistance = minDistance;
        }
        public void Update(VehicleState ourState)
        {
            if (TacticalDirector.VehicleAreas.ContainsKey(this.finalWaypoint.Perimeter.Zone))
            {
                VehicleAgent closest = null;
                double tmpDist = Double.MaxValue;

                foreach (VehicleAgent va in TacticalDirector.VehicleAreas[this.finalWaypoint.Perimeter.Zone])
                {
                    if (this.entryPolygon.IsInside(va.ClosestPosition))
                    {
                        double tmp = va.ClosestPosition.DistanceTo(this.finalWaypoint.Position);
                        if (closest == null || tmp < tmpDist)
                        {
                            tmpDist = tmp;
                            closest = va;
                        }
                    }
                }

                if (closest != null && closest.IsStopped)
                {
                    if (this.currentVehicle == null || !this.currentVehicle.Equals(closest))
                    {
                        this.currentVehicle = closest;
                        this.ResetTiming();
                        this.failedTimer.Start();
                    }
                    else
                    {
                        this.currentVehicle = closest;
                    }
                }
                else
                {
                    this.currentVehicle = closest;
                    this.ResetTiming();
                }
            }
            else
            {
                this.currentVehicle = null;
                this.ResetTiming();
            }
        }
        public void Update(UrbanChallenge.Common.Vehicle.VehicleState ourState)
        {
            // get lane
            ArbiterLane lane = this.turnFinalWaypoint.Lane;

            // get the possible vehicles that could be in this stop
            if (TacticalDirector.VehicleAreas.ContainsKey(lane))
            {
                // get vehicles in the the lane of the exit
                List<VehicleAgent> possibleVehicles = TacticalDirector.VehicleAreas[lane];

                // get the point we are looking from
                LinePath.PointOnPath referencePoint = lane.LanePath().GetClosestPoint(this.turnFinalWaypoint.Position);

                // tmp
                VehicleAgent tmp = null;
                double tmpDist = Double.MaxValue;

                // check over all possible vehicles
                foreach (VehicleAgent possible in possibleVehicles)
                {
                    // get vehicle point on lane
                    LinePath.PointOnPath vehiclePoint = lane.LanePath().GetClosestPoint(possible.ClosestPosition);

                    // check if the vehicle is in front of the reference point
                    double vehicleDist = lane.LanePath().DistanceBetween(referencePoint, vehiclePoint);
                    if (vehicleDist >= 0 && vehicleDist < TahoeParams.VL * 2.0)
                    {
                        tmp = possible;
                        tmpDist = vehicleDist;
                    }
                }

                if (tmp != null)
                {
                    if (this.currentVehicle == null || !this.currentVehicle.Equals(tmp))
                    {
                        this.timer.Stop();
                        this.timer.Reset();
                        this.currentVehicle = tmp;
                    }
                    else
                        this.currentVehicle = tmp;

                    if (this.currentVehicle.IsStopped && !this.timer.IsRunning)
                    {
                        this.timer.Stop();
                        this.timer.Reset();
                        this.timer.Start();
                    }
                    else if (!this.currentVehicle.IsStopped && this.timer.IsRunning)
                    {
                        this.timer.Stop();
                        this.timer.Reset();
                    }
                }
                else
                {
                    this.currentVehicle = null;
                    this.timer.Stop();
                    this.timer.Reset();
                }
            }
            else
            {
                this.timer.Stop();
                this.timer.Reset();
                this.currentVehicle = null;
            }
        }
 /// <summary>
 /// Resets values held over time
 /// </summary>
 public void Reset()
 {
     this.CurrentVehicle = null;
     this.currentDistance = 0.0;
     this.ResetTiming();
 }
        /// <summary>
        /// Gets closest vehicle on lane before either the exit or where we are clsoest
        /// </summary>
        /// <param name="ourState"></param>
        public void Update(VehicleState ourState)
        {
            #region Exit Polygon

            // check the exit polygon
            if (exit != null)
            {
                // create the polygon
                Polygon p = this.exitPolygon;

                // closest vehicle
                VehicleAgent closest = null;
                double closestDist = Double.MinValue;

                // check all inside the polygon
                foreach (VehicleAgent va in TacticalDirector.ValidVehicles.Values)
                {
                    // check if stopped
                    if (va.IsStopped)// && va.StateMonitor.Observed.speedValid)
                    {
                        // get distance to exit
                        double distToExit;
                        Coordinates c = va.ClosestPointTo(this.exit.Position, ourState, out distToExit).Value;

                        // check inside polygon
                        if (p.IsInside(c))
                        {
                            // check dist
                            if (closest == null || distToExit < closestDist)
                            {
                                closest = va;
                                closestDist = distToExit;
                            }
                        }
                    }
                }

                // check closest not null
                if (closest != null)
                {
                    // check vehicle switch
                    if (currentVehicle != closest)
                    {
                        this.ResetTiming();
                    }

                    // check if waiting timer not running
                    if (!this.waitingTimer.IsRunning)
                    {
                        this.ResetTiming();
                        this.waitingTimer.Start();
                    }

                    // set the new vehicle
                    this.currentVehicle = closest;

                    // return to stop update
                    return;
                }
                else
                {
                    // check if we were waiting for something in this area
                    if (this.globalMonitor.PreviouslyWaiting.Contains(this))
                    {
                        // remove the previous waiting
                        this.globalMonitor.PreviouslyWaiting.Remove(this);
                    }
                }
            }

            #endregion

            #region Lane Vehicles

            // get the possible vehicles that could be in this stop
            if (TacticalDirector.VehicleAreas.ContainsKey(this.lane))
            {
                // get vehicles in the the lane of the exit
                List<VehicleAgent> possibleVehicles = TacticalDirector.VehicleAreas[this.lane];

                // get the point we are looking from
                LinePath.PointOnPath referencePoint;

                // reference from exit if exists
                if (exit != null)
                {
                    LinePath.PointOnPath pop = lane.LanePath().GetClosestPoint(exit.Position);
                    referencePoint = lane.LanePath().AdvancePoint(pop, 3.0);
                }
                // otherwise look from where we are closest
                else
                    referencePoint = lane.LanePath().GetClosestPoint(ourState.Front);

                // tmp
                VehicleAgent tmp = null;
                double tmpDist = Double.MaxValue;

                // check over all possible vehicles in the lane
                foreach (VehicleAgent possible in possibleVehicles)
                {
                    // get vehicle point on lane
                    LinePath.PointOnPath vehiclePoint = lane.LanePath().GetClosestPoint(possible.ClosestPosition);

                    // check if the vehicle is behind the reference point
                    double vehicleDist = lane.LanePath().DistanceBetween(vehiclePoint, referencePoint);

                    // check for closest
                    if (vehicleDist > 0 && (tmp == null || vehicleDist < tmpDist))
                    {
                        tmp = possible;
                        tmpDist = vehicleDist;
                    }
                }

                // set the closest
                this.currentVehicle = tmp;
            }
            else
            {
                // set the closest
                this.currentVehicle = null;
            }

            #endregion

            // reset the timing if got this far
            this.ResetTiming();
        }
        /// <summary>
        /// Updates the montitor with the closest forward vehicle along the lane
        /// </summary>
        /// <param name="vehicleState"></param>
        /// <param name="final"></param>
        public void Update(VehicleState vehicleState, ArbiterWaypoint final, LinePath fullPath)
        {
            this.VehiclesToIgnore = new List<int>();

            if (TacticalDirector.VehicleAreas.ContainsKey(final.Lane))
            {
                List<VehicleAgent> laneVehicles = TacticalDirector.VehicleAreas[final.Lane];

                this.CurrentVehicle = null;
                double currentDistance = Double.MaxValue;

                foreach (VehicleAgent va in laneVehicles)
                {
                    double endDistance = final.Lane.DistanceBetween(final.Position, va.ClosestPosition);
                    if (endDistance > 0)
                        this.VehiclesToIgnore.Add(va.VehicleId);

                    double tmpDist = endDistance;

                    if (tmpDist > 0 && (this.CurrentVehicle == null || tmpDist < currentDistance))
                    {
                        this.CurrentVehicle = va;
                        currentDistance = tmpDist;
                    }
                }
            }
            else
                this.CurrentVehicle = null;
        }
 /// <summary>
 /// Plans a lane change from the initial lane to the adjacent lane
 /// </summary>
 /// <param name="initial"></param>
 /// <param name="adjacent"></param>
 /// <param name="vehicleState"></param>
 /// <param name="forwardVehicle"></param>
 /// <returns></returns>
 public Maneuver? PlanLaneChange(ArbiterLane initial, ArbiterWaypoint goal, LateralReasoning adjacent, VehicleState vehicleState, VehicleAgent forwardVehicle, LaneChangeInformation lci)
 {
     bool toLeft = initial.LaneOnLeft != null && adjacent.LateralLane.Equals(initial.LaneOnLeft);
     LaneChangeParameters updatedLCP;
     return this.LaneChangeManeuver(initial, toLeft, goal, vehicleState, new List<ITacticalBlockage>(), new List<ArbiterWaypoint>(), lci, null, out updatedLCP);
 }
        /// <summary>
        /// Update the monitor
        /// </summary>
        public void Update()
        {
            // flag if vehicle exists anymore
            bool contains = false;

            // get updated agent form tactical direction
            foreach (VehicleAgent va in TacticalDirector.ValidVehicles.Values)
            {
                if (this.intersectionVehicle.Equals(va))
                {
                    Polygon vaP = va.GetAbsolutePolygon(CoreCommon.Communications.GetVehicleState());
                    if(this.globalMonitor.Intersection.IntersectionPolygon.IsInside(vaP))
                    {
                        this.intersectionVehicle = va;
                        contains = true;
                    }
                }
            }

            if (contains)
            {
                if (this.intersectionVehicle.StateMonitor.Observed.speedValid && this.intersectionVehicle.IsStopped && !this.stopwatch.IsRunning)
                {
                    this.ResetTimer();
                    this.stopwatch.Start();
                }
                else if(!this.intersectionVehicle.StateMonitor.Observed.speedValid ||
                    !this.intersectionVehicle.StateMonitor.Observed.isStopped)
                {
                    this.ResetTimer();
                }
            }
            else
            {
                this.intersectionVehicle = null;
                this.ResetTimer();
            }
        }
        /// <summary>
        /// ALl polygons of all obstacles and stopped vehicles
        /// </summary>
        /// <param name="vehicleState"></param>
        /// <returns></returns>
        public static List<Polygon> AllObstacleAndStoppedVehiclePolygons(VehicleState vehicleState, bool failedVehiclesPersistentlyOnly)
        {
            // all polygons to include
            List<Polygon> allPolys = new List<Polygon>();

            // get list of all point collections
            List<Coordinates[]> includePolys = new List<Coordinates[]>();

            // get all stopped vehicle polys
            SceneEstimatorTrackedClusterCollection setcc = CoreCommon.Communications.GetObservedVehicles();
            for (int i = 0; i < setcc.clusters.Length; i++)
            {
                // check failed vehicle
                if (failedVehiclesPersistentlyOnly && TacticalDirector.ValidVehicles.ContainsKey(setcc.clusters[i].id))
                {
                    VehicleAgent va = TacticalDirector.ValidVehicles[setcc.clusters[i].id];
                    if (va.QueuingState.Queuing == QueuingState.Failed)
                    {
                        if (setcc.clusters[i].relativePoints.Length > 2)
                            includePolys.Add(setcc.clusters[i].relativePoints);
                    }
                }
                // check stopped
                else if (setcc.clusters[i].relativePoints.Length > 2 && setcc.clusters[i].isStopped)
                    includePolys.Add(setcc.clusters[i].relativePoints);
            }

            // get all static polygons
            SceneEstimatorUntrackedClusterCollection seucc = CoreCommon.Communications.GetObservedObstacles();
            for (int i = 0; i < seucc.clusters.Length; i++)
            {
                if (seucc.clusters[i].points.Length > 2)
                    includePolys.Add(seucc.clusters[i].points);
            }

            // loop through point collections
            VehicleAgent tmp = new VehicleAgent(-1);
            foreach (Coordinates[] points in includePolys)
            {
                List<Coordinates> polyPoints = new List<Coordinates>();
                for (int j = 0; j < points.Length; j++)
                {
                    polyPoints.Add(tmp.TransformCoordAbs(points[j], vehicleState));
                }
                allPolys.Add(Polygon.GrahamScan(polyPoints));
            }

            return allPolys;
        }
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="vehicle"></param>
 public IntersectionVehicleMonitor(IntersectionMonitor global, VehicleAgent vehicle)
 {
     this.stopwatch = new Stopwatch();
     this.intersectionVehicle = vehicle;
     this.globalMonitor = global;
 }
        /// <summary>
        /// Updates the current vehicle
        /// </summary>
        /// <param name="lane"></param>
        /// <param name="state"></param>
        public void Update(IFQMPlanable lane, VehicleState state)
        {
            // get the forward path
            LinePath p = lane.LanePath();

            // get our position
            Coordinates f = state.Front;

            // get all vehicles associated with those components
            List<VehicleAgent> vas = new List<VehicleAgent>();
            foreach (IVehicleArea iva in lane.AreaComponents)
            {
                if (TacticalDirector.VehicleAreas.ContainsKey(iva))
                    vas.AddRange(TacticalDirector.VehicleAreas[iva]);
            }

            // get the closest forward of us
            double minDistance = Double.MaxValue;
            VehicleAgent closest = null;

            // set the vehicles to ignore
            this.VehiclesToIgnore = new List<int>();

            // get clsoest
            foreach (VehicleAgent va in vas)
            {
                // get position of front
                Coordinates frontPos = va.ClosestPosition;

                // check relatively inside
                if (lane.RelativelyInside(frontPos))
                {
                    // distance to vehicle
                    double frontDist = lane.DistanceBetween(f, frontPos);

                    // check forward of us
                    if (frontDist > 0)
                    {
                        // add to ignorable
                        this.VehiclesToIgnore.Add(va.VehicleId);

                        // check for closest
                        if (frontDist < minDistance)
                        {
                            minDistance = frontDist;
                            closest = va;
                        }
                    }
                }
            }

            this.CurrentVehicle = closest;
            this.currentDistance = minDistance;
        }