Beispiel #1
0
        internal CustomSegmentLight GetCustomLight(byte laneIndex)
        {
            if (!VehicleTypeByLaneIndex.ContainsKey(laneIndex))
            {
#if DEBUGGET
                Log._Debug($"CustomSegmentLights.GetCustomLight({laneIndex}): No vehicle type found for lane index");
#endif
                return(mainSegmentLight);
            }
            ExtVehicleType vehicleType = VehicleTypeByLaneIndex[laneIndex];
#if DEBUGGET
            Log._Debug($"CustomSegmentLights.GetCustomLight({laneIndex}): Vehicle type is {vehicleType}");
#endif
            if (!CustomLights.ContainsKey(vehicleType))
            {
#if DEBUGGET
                Log._Debug($"CustomSegmentLights.GetCustomLight({laneIndex}): No custom light found for vehicle type {vehicleType}");
#endif
                return(mainSegmentLight);
            }
            CustomSegmentLight light = CustomLights[vehicleType];
#if DEBUGGET
            Log._Debug($"CustomSegmentLights.GetCustomLight({laneIndex}): Returning custom light for vehicle type {vehicleType}");
#endif
            return(light);
        }
        public RoadBaseAI.TrafficLightState GetLight(ushort segmentId, ExtVehicleType vehicleType, int lightType)
        {
            CustomSegmentLight segLight = segmentLights[segmentId].GetCustomLight(vehicleType);

            if (segLight != null)
            {
                switch (lightType)
                {
                case 0:
                    return(segLight.LightMain);

                case 1:
                    return(segLight.LightLeft);

                case 2:
                    return(segLight.LightRight);

                case 3:
                    RoadBaseAI.TrafficLightState?pedState = segmentLights[segmentId].PedestrianLightState;
                    return(pedState == null ? RoadBaseAI.TrafficLightState.Red : (RoadBaseAI.TrafficLightState)pedState);
                }
            }

            return(RoadBaseAI.TrafficLightState.Green);
        }
Beispiel #3
0
        internal CustomSegmentLight GetCustomLight(ExtVehicleType vehicleType)
        {
#if TRACE
            Singleton <CodeProfiler> .instance.Start("CustomSegmentLights.GetCustomLight(vehicleType)");
#endif

            CustomSegmentLight ret = null;
            if (CustomLights.ContainsKey(vehicleType))
            {
                ret = CustomLights[vehicleType];
            }
            else
            {
                ret = mainSegmentLight;
            }

#if TRACE
            Singleton <CodeProfiler> .instance.Stop("CustomSegmentLights.GetCustomLight(vehicleType)");
#endif

            return(ret);

            /*if (vehicleType != ExtVehicleType.None)
             *      Log._Debug($"No traffic light for vehicle type {vehicleType} defined at segment {segmentId}, node {nodeId}.");*/
        }
        internal void ChangeLightMode(ushort segmentId, ExtVehicleType vehicleType, CustomSegmentLight.Mode mode)
        {
            CustomSegmentLight light = segmentLights[segmentId].GetCustomLight(vehicleType);

            if (light != null)
            {
                light.CurrentMode = mode;
            }
        }
Beispiel #5
0
        internal void SetLights(CustomSegmentLights otherLights)
        {
            foreach (KeyValuePair <ExtVehicleType, CustomSegmentLight> e in otherLights.CustomLights)
            {
                CustomSegmentLight ourLight = null;
                if (!CustomLights.TryGetValue(e.Key, out ourLight))
                {
                    continue;
                }

                ourLight.SetStates(e.Value.LightMain, e.Value.LightLeft, e.Value.LightRight, false);
                //ourLight.LightPedestrian = e.Value.LightPedestrian;
            }
            pedestrianLightState     = otherLights.pedestrianLightState;
            manualPedestrianMode     = otherLights.manualPedestrianMode;
            AutoPedestrianLightState = otherLights.AutoPedestrianLightState;
        }
Beispiel #6
0
        internal CustomSegmentLight GetCustomLight(ExtVehicleType vehicleType)
        {
            CustomSegmentLight ret = null;

            if (CustomLights.ContainsKey(vehicleType))
            {
                ret = CustomLights[vehicleType];
            }
            else
            {
                ret = mainSegmentLight;
            }

            return(ret);

            /*if (vehicleType != ExtVehicleType.None)
             *      Log._Debug($"No traffic light for vehicle type {vehicleType} defined at segment {segmentId}, node {nodeId}.");*/
        }
Beispiel #7
0
 public RoadBaseAI.TrafficLightState GetAutoPedestrianLightState()
 {
     RoadBaseAI.TrafficLightState?vehicleState = null;
     foreach (KeyValuePair <ExtVehicleType, CustomSegmentLight> e in CustomLights)
     {
         if (vehicleState == null || e.Value.GetLightMain() != RoadBaseAI.TrafficLightState.Red)
         {
             vehicleState = e.Value.GetLightMain();
         }
         if (vehicleState == RoadBaseAI.TrafficLightState.Green)
         {
             break;
         }
     }
     if (vehicleState == null)
     {
         return(RoadBaseAI.TrafficLightState.Red);
     }
     return(CustomSegmentLight.InvertLight((RoadBaseAI.TrafficLightState)vehicleState));
 }
Beispiel #8
0
        internal void SetLights(CustomSegmentLights otherLights)
        {
#if TRACE
            Singleton <CodeProfiler> .instance.Start("CustomSegmentLights.SetLights");
#endif
            foreach (KeyValuePair <ExtVehicleType, CustomSegmentLight> e in otherLights.CustomLights)
            {
                CustomSegmentLight ourLight = null;
                if (!CustomLights.TryGetValue(e.Key, out ourLight))
                {
                    continue;
                }

                ourLight.LightMain  = e.Value.LightMain;
                ourLight.LightLeft  = e.Value.LightLeft;
                ourLight.LightRight = e.Value.LightRight;
                //ourLight.LightPedestrian = e.Value.LightPedestrian;
            }
            pedestrianLightState = otherLights.pedestrianLightState;
            ManualPedestrianMode = otherLights.ManualPedestrianMode;
#if TRACE
            Singleton <CodeProfiler> .instance.Stop("CustomSegmentLights.SetLights");
#endif
        }
        public void SetLights(bool noTransition)
        {
#if TRACE
            Singleton <CodeProfiler> .instance.Start("TimedTrafficLightsStep.SetLights");
#endif
            try {
                bool atEndTransition   = !noTransition && isInEndTransition();                       // = yellow
                bool atStartTransition = !noTransition && !atEndTransition && isInStartTransition(); // = red + yellow

#if DEBUG
                if (timedNode == null)
                {
                    Log.Error($"TimedTrafficLightsStep: timedNode is null!");
#if TRACE
                    Singleton <CodeProfiler> .instance.Stop("TimedTrafficLightsStep.SetLights");
#endif
                    return;
                }
#endif

                TimedTrafficLightsStep previousStep = timedNode.Steps[(timedNode.CurrentStep + timedNode.Steps.Count - 1) % timedNode.Steps.Count];
                TimedTrafficLightsStep nextStep     = timedNode.Steps[(timedNode.CurrentStep + 1) % timedNode.Steps.Count];

#if DEBUG
                if (previousStep == null)
                {
                    Log.Error($"TimedTrafficLightsStep: previousStep is null!");
#if TRACE
                    Singleton <CodeProfiler> .instance.Stop("TimedTrafficLightsStep.SetLights");
#endif
                    return;
                }

                if (nextStep == null)
                {
                    Log.Error($"TimedTrafficLightsStep: nextStep is null!");
#if TRACE
                    Singleton <CodeProfiler> .instance.Stop("TimedTrafficLightsStep.SetLights");
#endif
                    return;
                }

                if (previousStep.segmentLights == null)
                {
                    Log.Error($"TimedTrafficLightsStep: previousStep.segmentLights is null!");
                    return;
                }

                if (nextStep.segmentLights == null)
                {
                    Log.Error($"TimedTrafficLightsStep: nextStep.segmentLights is null!");
#if TRACE
                    Singleton <CodeProfiler> .instance.Stop("TimedTrafficLightsStep.SetLights");
#endif
                    return;
                }

                if (segmentLights == null)
                {
                    Log.Error($"TimedTrafficLightsStep: segmentLights is null!");
#if TRACE
                    Singleton <CodeProfiler> .instance.Stop("TimedTrafficLightsStep.SetLights");
#endif
                    return;
                }
#endif

                foreach (KeyValuePair <ushort, CustomSegmentLights> e in segmentLights)
                {
                    var segmentId            = e.Key;
                    var curStepSegmentLights = e.Value;

#if DEBUG
                    if (!previousStep.segmentLights.ContainsKey(segmentId))
                    {
                        Log.Error($"TimedTrafficLightsStep: previousStep does not contain lights for segment {segmentId}!");
#if TRACE
                        Singleton <CodeProfiler> .instance.Stop("TimedTrafficLightsStep.SetLights");
#endif
                        return;
                    }

                    if (!nextStep.segmentLights.ContainsKey(segmentId))
                    {
                        Log.Error($"TimedTrafficLightsStep: nextStep does not contain lights for segment {segmentId}!");
#if TRACE
                        Singleton <CodeProfiler> .instance.Stop("TimedTrafficLightsStep.SetLights");
#endif
                        return;
                    }
#endif

                    var prevStepSegmentLights = previousStep.segmentLights[segmentId];
                    var nextStepSegmentLights = nextStep.segmentLights[segmentId];

                    //segLightState.makeRedOrGreen(); // TODO temporary fix

                    var liveSegmentLights = CustomTrafficLights.GetOrLiveSegmentLights(timedNode.NodeId, segmentId);
                    if (liveSegmentLights == null)
                    {
                        continue;
                    }

                    if (curStepSegmentLights.PedestrianLightState != null && prevStepSegmentLights.PedestrianLightState != null && nextStepSegmentLights.PedestrianLightState != null)
                    {
                        RoadBaseAI.TrafficLightState pedLightState = calcLightState((RoadBaseAI.TrafficLightState)prevStepSegmentLights.PedestrianLightState, (RoadBaseAI.TrafficLightState)curStepSegmentLights.PedestrianLightState, (RoadBaseAI.TrafficLightState)nextStepSegmentLights.PedestrianLightState, atStartTransition, atEndTransition);
                        //Log._Debug($"TimedStep.SetLights: Setting pedestrian light state @ seg. {segmentId} to {pedLightState} {curStepSegmentLights.ManualPedestrianMode}");
                        liveSegmentLights.ManualPedestrianMode = curStepSegmentLights.ManualPedestrianMode;
                        liveSegmentLights.PedestrianLightState = pedLightState;
                        //Log._Debug($"Step @ {timedNode.NodeId}: Segment {segmentId}: Ped.: {liveSegmentLights.PedestrianLightState.ToString()}");
                    }

#if DEBUG
                    if (curStepSegmentLights.VehicleTypes == null)
                    {
                        Log.Error($"TimedTrafficLightsStep: curStepSegmentLights.VehicleTypes is null!");
#if TRACE
                        Singleton <CodeProfiler> .instance.Stop("TimedTrafficLightsStep.SetLights");
#endif
                        return;
                    }
#endif

                    foreach (ExtVehicleType vehicleType in curStepSegmentLights.VehicleTypes)
                    {
                        CustomSegmentLight liveSegmentLight = liveSegmentLights.GetCustomLight(vehicleType);
                        if (liveSegmentLight == null)
                        {
#if DEBUG
                            Log._Debug($"Timed step @ seg. {segmentId}, node {timedNode.NodeId} has a traffic light for {vehicleType} but the live segment does not have one.");
#endif
                            continue;
                        }
                        CustomSegmentLight curStepSegmentLight  = curStepSegmentLights.GetCustomLight(vehicleType);
                        CustomSegmentLight prevStepSegmentLight = prevStepSegmentLights.GetCustomLight(vehicleType);
                        CustomSegmentLight nextStepSegmentLight = nextStepSegmentLights.GetCustomLight(vehicleType);
#if DEBUG
                        if (curStepSegmentLight == null)
                        {
                            Log.Error($"TimedTrafficLightsStep: curStepSegmentLight is null!");
#if TRACE
                            Singleton <CodeProfiler> .instance.Stop("TimedTrafficLightsStep.SetLights");
#endif
                            return;
                        }

                        if (prevStepSegmentLight == null)
                        {
                            Log.Error($"TimedTrafficLightsStep: prevStepSegmentLight is null!");
#if TRACE
                            Singleton <CodeProfiler> .instance.Stop("TimedTrafficLightsStep.SetLights");
#endif
                            return;
                        }

                        if (nextStepSegmentLight == null)
                        {
                            Log.Error($"TimedTrafficLightsStep: nextStepSegmentLight is null!");
#if TRACE
                            Singleton <CodeProfiler> .instance.Stop("TimedTrafficLightsStep.SetLights");
#endif
                            return;
                        }
#endif

                        liveSegmentLight.CurrentMode = curStepSegmentLight.CurrentMode;
                        liveSegmentLight.LightMain   = calcLightState(prevStepSegmentLight.LightMain, curStepSegmentLight.LightMain, nextStepSegmentLight.LightMain, atStartTransition, atEndTransition);
                        liveSegmentLight.LightLeft   = calcLightState(prevStepSegmentLight.LightLeft, curStepSegmentLight.LightLeft, nextStepSegmentLight.LightLeft, atStartTransition, atEndTransition);
                        liveSegmentLight.LightRight  = calcLightState(prevStepSegmentLight.LightRight, curStepSegmentLight.LightRight, nextStepSegmentLight.LightRight, atStartTransition, atEndTransition);

                        //Log._Debug($"Step @ {timedNode.NodeId}: Segment {segmentId} for vehicle type {vehicleType}: L: {liveSegmentLight.LightLeft.ToString()} F: {liveSegmentLight.LightMain.ToString()} R: {liveSegmentLight.LightRight.ToString()}");
                    }

                    /*if (timedNode.NodeId == 20164) {
                     *      Log._Debug($"Step @ {timedNode.NodeId}: Segment {segmentId}: {segmentLight.LightLeft.ToString()} {segmentLight.LightMain.ToString()} {segmentLight.LightRight.ToString()} {segmentLight.LightPedestrian.ToString()}");
                     * }*/

                    liveSegmentLights.UpdateVisuals();
                }
            } catch (Exception e) {
                Log.Error($"Exception in TimedTrafficStep.SetLights: {e.ToString()}");
                invalid = true;
            }
#if TRACE
            Singleton <CodeProfiler> .instance.Stop("TimedTrafficLightsStep.SetLights");
#endif
        }
        /// <summary>
        /// Calculates the current metrics for flowing and waiting vehicles
        /// </summary>
        /// <param name="wait"></param>
        /// <param name="flow"></param>
        /// <returns>true if the values could be calculated, false otherwise</returns>
        public bool calcWaitFlow(out float wait, out float flow)
        {
#if DEBUG
            bool debug = timedNode.NodeId == 17857;
#else
            bool debug = false;
#endif

            uint numFlows    = 0;
            uint numWaits    = 0;
            uint curMeanFlow = 0;
            uint curMeanWait = 0;

            // we are the master node. calculate traffic data
            foreach (ushort timedNodeId in groupNodeIds)
            {
                TrafficLightSimulation sim = TrafficLightSimulation.GetNodeSimulation(timedNodeId);
                if (sim == null || !sim.IsTimedLight())
                {
                    continue;
                }
                TimedTrafficLights slaveTimedNode = sim.TimedLight;
                if (slaveTimedNode.NumSteps() <= timedNode.CurrentStep)
                {
                    for (int i = 0; i < slaveTimedNode.NumSteps(); ++i)
                    {
                        slaveTimedNode.GetStep(i).invalid = true;
                    }
                    continue;
                }
                TimedTrafficLightsStep slaveStep = slaveTimedNode.Steps[timedNode.CurrentStep];

                //List<int> segmentIdsToDelete = new List<int>();

                // minimum time reached. check traffic!
                foreach (KeyValuePair <ushort, CustomSegmentLights> e in slaveStep.segmentLights)
                {
                    var fromSegmentId = e.Key;
                    var segLights     = e.Value;

                    // one of the traffic lights at this segment is green: count minimum traffic flowing through
                    SegmentEnd fromSeg = TrafficPriority.GetPrioritySegment(timedNodeId, fromSegmentId);
                    if (fromSeg == null)
                    {
                        //Log.Warning("stepDone(): prioSeg is null");
                        //segmentIdsToDelete.Add(fromSegmentId);
                        continue;                         // skip invalid segment
                    }

                    bool           startPhase        = getCurrentFrame() <= startFrame + minTime + 2;    // during start phase all vehicles on "green" segments are counted as flowing
                    ExtVehicleType validVehicleTypes = VehicleRestrictionsManager.GetAllowedVehicleTypes(fromSegmentId, timedNode.NodeId);

                    foreach (ExtVehicleType vehicleType in segLights.VehicleTypes)
                    {
                        if (vehicleType != ExtVehicleType.None && (validVehicleTypes & vehicleType) == ExtVehicleType.None)
                        {
                            continue;
                        }
                        CustomSegmentLight segLight = segLights.GetCustomLight(vehicleType);
                        if (segLight == null)
                        {
                            Log.Warning($"Timed traffic light step: Failed to get custom light for vehicleType {vehicleType} @ seg. {fromSegmentId}, node {timedNode.NodeId}!");
                            continue;
                        }

                        Dictionary <ushort, uint>[] carsToSegmentMetrics = new Dictionary <ushort, uint> [startPhase ? 1: 2];
                        try {
                            carsToSegmentMetrics[0] = fromSeg.GetVehicleMetricGoingToSegment(null, vehicleType, segLights.SeparateVehicleTypes, debug);
                        } catch (Exception ex) {
                            Log.Warning("calcWaitFlow: " + ex.ToString());
                        }
                        if (!startPhase)
                        {
                            try {
                                carsToSegmentMetrics[1] = fromSeg.GetVehicleMetricGoingToSegment(0.1f, vehicleType, segLights.SeparateVehicleTypes, debug);
                            } catch (Exception ex) {
                                Log.Warning("calcWaitFlow: " + ex.ToString());
                            }
                        }

                        if (carsToSegmentMetrics[0] == null)
                        {
                            continue;
                        }

                        // build directions from toSegment to fromSegment
                        Dictionary <ushort, Direction> directions = new Dictionary <ushort, Direction>();
                        foreach (KeyValuePair <ushort, uint> f in carsToSegmentMetrics[0])
                        {
                            var             toSegmentId = f.Key;
                            SegmentGeometry geometry    = CustomRoadAI.GetSegmentGeometry(fromSegmentId);
                            Direction       dir         = geometry.GetDirection(toSegmentId, timedNodeId);
                            directions[toSegmentId] = dir;
                        }

                        // calculate waiting/flowing traffic
                        for (int i = 0; i < carsToSegmentMetrics.Length; ++i)
                        {
                            if (carsToSegmentMetrics[i] == null)
                            {
                                continue;
                            }

                            foreach (KeyValuePair <ushort, uint> f in carsToSegmentMetrics[i])
                            {
                                ushort toSegmentId        = f.Key;
                                uint   totalNormCarLength = f.Value;

                                bool addToFlow = false;
                                switch (directions[toSegmentId])
                                {
                                case Direction.Left:
                                    if (segLight.isLeftGreen())
                                    {
                                        addToFlow = true;
                                    }
                                    break;

                                case Direction.Right:
                                    if (segLight.isRightGreen())
                                    {
                                        addToFlow = true;
                                    }
                                    break;

                                case Direction.Forward:
                                default:
                                    if (segLight.isForwardGreen())
                                    {
                                        addToFlow = true;
                                    }
                                    break;
                                }

                                if (addToFlow)
                                {
                                    if (i > 0 || startPhase)
                                    {
                                        ++numFlows;
                                        curMeanFlow += totalNormCarLength;
                                    }
                                }
                                else if (i == 0)
                                {
                                    ++numWaits;
                                    curMeanWait += totalNormCarLength;
                                }
                            }
                        }
                    }
                }

                // delete invalid segments from step

                /*foreach (int segmentId in segmentIdsToDelete) {
                 *      slaveStep.segmentLightStates.Remove(segmentId);
                 * }*/

                if (slaveStep.segmentLights.Count <= 0)
                {
                    invalid = true;
                    flow    = 0f;
                    wait    = 0f;
                    return(false);
                }
            }

            if (numFlows > 0)
            {
                curMeanFlow /= numFlows;
            }
            if (numWaits > 0)
            {
                curMeanWait /= numWaits;
            }

            float fCurMeanFlow = curMeanFlow;
            fCurMeanFlow /= 100f * waitFlowBalance;             // a value smaller than 1 rewards steady traffic currents

            wait = (float)curMeanWait / 100f;
            flow = fCurMeanFlow;
            return(true);
        }
Beispiel #11
0
        internal void housekeeping(bool mayDelete, bool calculateAutoPedLight, RoadBaseAI.TrafficLightState mainState = RoadBaseAI.TrafficLightState.Red, RoadBaseAI.TrafficLightState leftState = RoadBaseAI.TrafficLightState.Red, RoadBaseAI.TrafficLightState rightState = RoadBaseAI.TrafficLightState.Red, RoadBaseAI.TrafficLightState pedState = RoadBaseAI.TrafficLightState.Red)
        {
            // we intentionally never delete vehicle types (because we may want to retain traffic light states if a segment is upgraded or replaced)

            ushort nodeId = NodeId;
            HashSet <ExtVehicleType>          setupLights     = new HashSet <ExtVehicleType>();
            Dictionary <byte, ExtVehicleType> allAllowedTypes = VehicleRestrictionsManager.Instance.GetAllowedVehicleTypesAsDict(segmentId, nodeId);
            ExtVehicleType allAllowedMask = VehicleRestrictionsManager.Instance.GetAllowedVehicleTypes(segmentId, nodeId);

            SeparateVehicleTypes = ExtVehicleType.None;
#if DEBUGHK
            Log._Debug($"CustomSegmentLights: housekeeping @ seg. {segmentId}, node {nodeId}, allAllowedTypes={string.Join(", ", allAllowedTypes.Select(x => x.ToString()).ToArray())}");
#endif
            bool addPedestrianLight = false;
            uint numLights          = 0;
            VehicleTypeByLaneIndex.Clear();
            HashSet <byte> laneIndicesWithoutSeparateLights = new HashSet <byte>(allAllowedTypes.Keys);
            foreach (KeyValuePair <byte, ExtVehicleType> e in allAllowedTypes)
            {
                byte           laneIndex    = e.Key;
                ExtVehicleType allowedTypes = e.Value;

                foreach (ExtVehicleType mask in singleLaneVehicleTypes)
                {
                    if (setupLights.Contains(mask))
                    {
                        break;
                    }

                    if ((allowedTypes & mask) != ExtVehicleType.None && (allowedTypes & ~(mask | ExtVehicleType.Emergency)) == ExtVehicleType.None)
                    {
#if DEBUGHK
                        Log._Debug($"CustomSegmentLights: housekeeping @ seg. {segmentId}, node {nodeId}: adding {mask} light");
#endif

                        if (!CustomLights.ContainsKey(mask))
                        {
                            CustomLights.Add(mask, new TrafficLight.CustomSegmentLight(this, mainState, leftState, rightState));
                            VehicleTypes.AddFirst(mask);
                        }
                        VehicleTypeByLaneIndex[laneIndex] = mask;
                        laneIndicesWithoutSeparateLights.Remove(laneIndex);
                        ++numLights;
                        addPedestrianLight = true;
                        mainSegmentLight   = CustomLights[mask];
                        setupLights.Add(mask);
                        SeparateVehicleTypes |= mask;
                        break;
                    }
                }
            }

            if (allAllowedTypes.Count > numLights)
            {
#if DEBUGHK
                Log._Debug($"CustomSegmentLights: housekeeping @ seg. {segmentId}, node {nodeId}: adding main vehicle light: {mainVehicleType}");
#endif

                // traffic lights for cars
                if (!CustomLights.ContainsKey(mainVehicleType))
                {
                    CustomLights.Add(mainVehicleType, new TrafficLight.CustomSegmentLight(this, mainState, leftState, rightState));
                    VehicleTypes.AddFirst(mainVehicleType);
                }
                mainSegmentLight = CustomLights[mainVehicleType];
                foreach (byte laneIndex in laneIndicesWithoutSeparateLights)
                {
                    VehicleTypeByLaneIndex[laneIndex] = ExtVehicleType.None;
                }
                addPedestrianLight = allAllowedMask == ExtVehicleType.None || (allAllowedMask & ~ExtVehicleType.RailVehicle) != ExtVehicleType.None;
            }
            else
            {
                addPedestrianLight = true;
            }

#if DEBUGHK
            if (addPedestrianLight)
            {
                Log._Debug($"CustomSegmentLights: housekeeping @ seg. {segmentId}, node {nodeId}: adding ped. light");
            }
#endif

            if (mayDelete)
            {
                // delete traffic lights for non-existing configurations
                HashSet <ExtVehicleType> vehicleTypesToDelete = new HashSet <ExtVehicleType>();
                foreach (KeyValuePair <ExtVehicleType, CustomSegmentLight> e in CustomLights)
                {
                    if (e.Key == mainVehicleType)
                    {
                        continue;
                    }
                    if (!setupLights.Contains(e.Key))
                    {
                        vehicleTypesToDelete.Add(e.Key);
                    }
                }

                foreach (ExtVehicleType vehicleType in vehicleTypesToDelete)
                {
#if DEBUGHK
                    Log._Debug($"Deleting traffic light for {vehicleType} at segment {segmentId}, node {nodeId}");
#endif
                    CustomLights.Remove(vehicleType);
                    VehicleTypes.Remove(vehicleType);
                }
            }

            if (CustomLights.ContainsKey(mainVehicleType) && VehicleTypes.First.Value != mainVehicleType)
            {
                VehicleTypes.Remove(mainVehicleType);
                VehicleTypes.AddFirst(mainVehicleType);
            }

            if (addPedestrianLight)
            {
#if DEBUGHK
                Log._Debug($"CustomSegmentLights: housekeeping @ seg. {segmentId}, node {nodeId}: adding pedestrian light");
#endif
                if (pedestrianLightState == null)
                {
                    pedestrianLightState = pedState;
                }
            }
            else
            {
                pedestrianLightState = null;
            }

            OnChange(calculateAutoPedLight);
#if DEBUGHK
            Log._Debug($"CustomSegmentLights: housekeeping @ seg. {segmentId}, node {nodeId}: Housekeeping complete. VehicleTypeByLaneIndex={string.Join("; ", VehicleTypeByLaneIndex.Select(x => x.Key + "=" + x.Value).ToArray())} CustomLights={string.Join("; ", CustomLights.Select(x => x.Key.ToString()).ToArray())}");
#endif
        }
        public long CheckNextChange(ushort segmentId, ExtVehicleType vehicleType, int lightType)
        {
            var curStep   = CurrentStep;
            var nextStep  = (CurrentStep + 1) % NumSteps();
            var numFrames = Steps[CurrentStep].MaxTimeRemaining();

            RoadBaseAI.TrafficLightState currentState;
            CustomSegmentLights          segmentLights = CustomTrafficLightsManager.Instance().GetSegmentLights(NodeId, segmentId);

            if (segmentLights == null)
            {
                Log._Debug($"CheckNextChange: No segment lights at node {NodeId}, segment {segmentId}");
                return(99);
            }
            CustomSegmentLight segmentLight = segmentLights.GetCustomLight(vehicleType);

            if (segmentLight == null)
            {
                Log._Debug($"CheckNextChange: No segment light at node {NodeId}, segment {segmentId}");
                return(99);
            }

            if (lightType == 0)
            {
                currentState = segmentLight.GetLightMain();
            }
            else if (lightType == 1)
            {
                currentState = segmentLight.GetLightLeft();
            }
            else if (lightType == 2)
            {
                currentState = segmentLight.GetLightRight();
            }
            else
            {
                currentState = segmentLights.PedestrianLightState == null ? RoadBaseAI.TrafficLightState.Red : (RoadBaseAI.TrafficLightState)segmentLights.PedestrianLightState;
            }


            while (true)
            {
                if (nextStep == curStep)
                {
                    numFrames = 99;
                    break;
                }

                var light = Steps[nextStep].GetLight(segmentId, vehicleType, lightType);

                if (light != currentState)
                {
                    break;
                }
                else
                {
                    numFrames += Steps[nextStep].maxTime;
                }

                nextStep = (nextStep + 1) % NumSteps();
            }

            return(numFrames);
        }
        internal void handleNewSegments()
        {
            if (NumSteps() <= 0)
            {
                // no steps defined, just create live traffic lights

                /*for (int s = 0; s < 8; ++s) {
                 *      ushort segmentId = Singleton<NetManager>.instance.m_nodes.m_buffer[NodeId].GetSegment(s);
                 *      if (segmentId <= 0)
                 *              continue;
                 *      if (! CustomTrafficLights.IsSegmentLight(NodeId, segmentId))
                 *              CustomTrafficLights.AddSegmentLights(NodeId, segmentId);
                 * }*/


                return;
            }

            CustomTrafficLightsManager customTrafficLightsManager = CustomTrafficLightsManager.Instance();
            TrafficPriorityManager     prioMan = TrafficPriorityManager.Instance();

            for (int s = 0; s < 8; ++s)
            {
                ushort segmentId = Singleton <NetManager> .instance.m_nodes.m_buffer[NodeId].GetSegment(s);
                if (segmentId <= 0)
                {
                    continue;
                }

                List <ushort> invalidSegmentIds = new List <ushort>();
                bool          isNewSegment      = !Steps[0].segmentLights.ContainsKey(segmentId);

                if (isNewSegment)
                {
                    // segment was created
                    Log._Debug($"New segment detected: {segmentId} @ {NodeId}");

                    foreach (KeyValuePair <ushort, CustomSegmentLights> e in Steps[0].segmentLights)
                    {
                        var fromSegmentId = e.Key;

                        if (!prioMan.IsPrioritySegment(NodeId, fromSegmentId))
                        {
                            Log._Debug($"Identified old segment {fromSegmentId} @ {NodeId}");
                            invalidSegmentIds.Add(fromSegmentId);
                        }
                    }

                    Log._Debug($"Setting up segment end for new segment {segmentId} @ {NodeId}");
                    SetupSegmentEnd(segmentId);

                    if (invalidSegmentIds.Count > 0)
                    {
                        var oldSegmentId = invalidSegmentIds[0];
                        prioMan.RemovePrioritySegment(NodeId, oldSegmentId);
                        Log._Debug($"Replacing old segment {oldSegmentId} @ {NodeId} with new segment {segmentId}");

                        // replace the old segment with the newly created one
                        for (int i = 0; i < NumSteps(); ++i)
                        {
                            if (!Steps[i].segmentLights.ContainsKey(oldSegmentId))
                            {
                                Log.Error($"Step {i} at node {NodeId} does not contain step lights for old segment {oldSegmentId}");
                                Steps[i].addSegment(segmentId, true);
                                Steps[i].calcMaxSegmentLength();
                                continue;
                            }

                            CustomSegmentLights customLights = Steps[i].segmentLights[oldSegmentId];
                            Log._Debug($"Removing old segment {oldSegmentId} @ {NodeId} from step {i}");
                            Steps[i].segmentLights.Remove(oldSegmentId);
                            Log._Debug($"Setting new segment id {segmentId} at custom light from step {i}");
                            customLights.SegmentId = segmentId;
                            Steps[i].segmentLights.Add(segmentId, customLights);
                            Steps[i].calcMaxSegmentLength();
                            Log._Debug($"Getting live segment lights of new segment {segmentId} @ {NodeId} and applying mode @ step {i}");
                            CustomSegmentLights liveSegLights = customTrafficLightsManager.GetSegmentLights(NodeId, segmentId);
                            if (liveSegLights == null)
                            {
                                Log.Error($"No live segment lights for seg. {segmentId} @ node {NodeId} found!");
                                customTrafficLightsManager.AddSegmentLights(NodeId, segmentId);
                                liveSegLights = customTrafficLightsManager.GetSegmentLights(NodeId, segmentId);
                            }

                            foreach (KeyValuePair <ExtVehicleType, CustomSegmentLight> e in customLights.CustomLights)
                            {
                                CustomSegmentLight liveSegLight = liveSegLights.GetCustomLight(e.Key);
                                if (liveSegLight == null)
                                {
                                    continue;
                                }
                                Log._Debug($"Updating live segment light mode of new segment {segmentId} @ {NodeId} for vehicle type {e.Key} @ step {i}");
                                liveSegLight.CurrentMode = e.Value.CurrentMode;
                            }
                            Log._Debug($"Finished applying new segment {segmentId} @ {NodeId} @ step {i}");
                        }
                    }
                    else
                    {
                        Log._Debug($"Adding new segment {segmentId} to node {NodeId}");

                        // create a new manual light
                        for (int i = 0; i < NumSteps(); ++i)
                        {
                            Steps[i].addSegment(segmentId, true);
                            Steps[i].calcMaxSegmentLength();
                        }
                    }
                }
            }
        }
Beispiel #14
0
        public void UpdateLiveLights(bool noTransition)
        {
            try {
                CustomSegmentLightsManager customTrafficLightsManager = CustomSegmentLightsManager.Instance;

                bool atEndTransition   = !noTransition && (IsInEndTransition() || IsEndTransitionDone());            // = yellow
                bool atStartTransition = !noTransition && !atEndTransition && IsInStartTransition();                 // = red + yellow

#if DEBUG
                if (timedNode == null)
                {
                    Log.Error($"TimedTrafficLightsStep: timedNode is null!");
                    return;
                }
#endif

                if (PreviousStepRefIndex >= timedNode.NumSteps())
                {
                    PreviousStepRefIndex = -1;
                }
                if (NextStepRefIndex >= timedNode.NumSteps())
                {
                    NextStepRefIndex = -1;
                }
                TimedTrafficLightsStep previousStep = timedNode.Steps[PreviousStepRefIndex >= 0 ? PreviousStepRefIndex : ((timedNode.CurrentStep + timedNode.Steps.Count - 1) % timedNode.Steps.Count)];
                TimedTrafficLightsStep nextStep     = timedNode.Steps[NextStepRefIndex >= 0 ? NextStepRefIndex : ((timedNode.CurrentStep + 1) % timedNode.Steps.Count)];

#if DEBUG
                if (previousStep == null)
                {
                    Log.Error($"TimedTrafficLightsStep: previousStep is null!");
                    return;
                }

                if (nextStep == null)
                {
                    Log.Error($"TimedTrafficLightsStep: nextStep is null!");
                    return;
                }

                if (previousStep.segmentLights == null)
                {
                    Log.Error($"TimedTrafficLightsStep: previousStep.segmentLights is null!");
                    return;
                }

                if (nextStep.segmentLights == null)
                {
                    Log.Error($"TimedTrafficLightsStep: nextStep.segmentLights is null!");
                    return;
                }

                if (segmentLights == null)
                {
                    Log.Error($"TimedTrafficLightsStep: segmentLights is null!");
                    return;
                }
#endif

#if DEBUG
                //Log._Debug($"TimedTrafficLightsStep.SetLights({noTransition}) called for NodeId={timedNode.NodeId}. atStartTransition={atStartTransition} atEndTransition={atEndTransition}");
#endif

                foreach (KeyValuePair <ushort, CustomSegmentLights> e in segmentLights)
                {
                    var segmentId            = e.Key;
                    var curStepSegmentLights = e.Value;

#if DEBUG
                    //Log._Debug($"TimedTrafficLightsStep.SetLights({noTransition})   -> segmentId={segmentId} @ NodeId={timedNode.NodeId}");
#endif

                    if (!previousStep.segmentLights.ContainsKey(segmentId))
                    {
#if DEBUG
                        Log._Debug($"TimedTrafficLightsStep: previousStep does not contain lights for segment {segmentId}!");
#endif
                        continue;
                    }

                    if (!nextStep.segmentLights.ContainsKey(segmentId))
                    {
#if DEBUG
                        Log._Debug($"TimedTrafficLightsStep: nextStep does not contain lights for segment {segmentId}!");
#endif
                        continue;
                    }

                    var prevStepSegmentLights = previousStep.segmentLights[segmentId];
                    var nextStepSegmentLights = nextStep.segmentLights[segmentId];

                    //segLightState.makeRedOrGreen(); // TODO temporary fix

                    var liveSegmentLights = customTrafficLightsManager.GetSegmentLights(segmentId, curStepSegmentLights.StartNode, false);
                    if (liveSegmentLights == null)
                    {
                        continue;
                    }

                    RoadBaseAI.TrafficLightState pedLightState = calcLightState((RoadBaseAI.TrafficLightState)prevStepSegmentLights.PedestrianLightState, (RoadBaseAI.TrafficLightState)curStepSegmentLights.PedestrianLightState, (RoadBaseAI.TrafficLightState)nextStepSegmentLights.PedestrianLightState, atStartTransition, atEndTransition);
                    //Log._Debug($"TimedStep.SetLights: Setting pedestrian light state @ seg. {segmentId} to {pedLightState} {curStepSegmentLights.ManualPedestrianMode}");
                    liveSegmentLights.ManualPedestrianMode = curStepSegmentLights.ManualPedestrianMode;
                    liveSegmentLights.PedestrianLightState = liveSegmentLights.AutoPedestrianLightState = pedLightState;
                    //Log.Warning($"Step @ {timedNode.NodeId}: Segment {segmentId}: Ped.: {liveSegmentLights.PedestrianLightState.ToString()} / {liveSegmentLights.AutoPedestrianLightState.ToString()}");

#if DEBUG
                    if (curStepSegmentLights.VehicleTypes == null)
                    {
                        Log.Error($"TimedTrafficLightsStep: curStepSegmentLights.VehicleTypes is null!");
                        return;
                    }
#endif

                    foreach (ExtVehicleType vehicleType in curStepSegmentLights.VehicleTypes)
                    {
#if DEBUG
                        //Log._Debug($"TimedTrafficLightsStep.SetLights({noTransition})     -> segmentId={segmentId} @ NodeId={timedNode.NodeId} for vehicle {vehicleType}");
#endif

                        CustomSegmentLight liveSegmentLight = liveSegmentLights.GetCustomLight(vehicleType);
                        if (liveSegmentLight == null)
                        {
#if DEBUG
                            Log._Debug($"Timed step @ seg. {segmentId}, node {timedNode.NodeId} has a traffic light for {vehicleType} but the live segment does not have one.");
#endif
                            continue;
                        }
                        CustomSegmentLight curStepSegmentLight  = curStepSegmentLights.GetCustomLight(vehicleType);
                        CustomSegmentLight prevStepSegmentLight = prevStepSegmentLights.GetCustomLight(vehicleType);
                        CustomSegmentLight nextStepSegmentLight = nextStepSegmentLights.GetCustomLight(vehicleType);

#if DEBUG
                        if (curStepSegmentLight == null)
                        {
                            Log.Error($"TimedTrafficLightsStep: curStepSegmentLight is null!");
                            return;
                        }

                        if (prevStepSegmentLight == null)
                        {
                            Log.Error($"TimedTrafficLightsStep: prevStepSegmentLight is null!");
                            return;
                        }

                        if (nextStepSegmentLight == null)
                        {
                            Log.Error($"TimedTrafficLightsStep: nextStepSegmentLight is null!");
                            return;
                        }
#endif

                        liveSegmentLight.currentMode = curStepSegmentLight.CurrentMode;

                        /*curStepSegmentLight.EnsureModeLights();
                         * prevStepSegmentLight.EnsureModeLights();
                         * nextStepSegmentLight.EnsureModeLights();*/

                        RoadBaseAI.TrafficLightState mainLight  = calcLightState(prevStepSegmentLight.LightMain, curStepSegmentLight.LightMain, nextStepSegmentLight.LightMain, atStartTransition, atEndTransition);
                        RoadBaseAI.TrafficLightState leftLight  = calcLightState(prevStepSegmentLight.LightLeft, curStepSegmentLight.LightLeft, nextStepSegmentLight.LightLeft, atStartTransition, atEndTransition);
                        RoadBaseAI.TrafficLightState rightLight = calcLightState(prevStepSegmentLight.LightRight, curStepSegmentLight.LightRight, nextStepSegmentLight.LightRight, atStartTransition, atEndTransition);
                        liveSegmentLight.SetStates(mainLight, leftLight, rightLight, false);

#if DEBUGTTL
                        Log._Debug($"TimedTrafficLightsStep.SetLights({noTransition})     -> *SETTING* LightLeft={liveSegmentLight.LightLeft} LightMain={liveSegmentLight.LightMain} LightRight={liveSegmentLight.LightRight} for segmentId={segmentId} @ NodeId={timedNode.NodeId} for vehicle {vehicleType}");
#endif

                        //Log._Debug($"Step @ {timedNode.NodeId}: Segment {segmentId} for vehicle type {vehicleType}: L: {liveSegmentLight.LightLeft.ToString()} F: {liveSegmentLight.LightMain.ToString()} R: {liveSegmentLight.LightRight.ToString()}");
                    }

                    /*if (timedNode.NodeId == 20164) {
                     *      Log._Debug($"Step @ {timedNode.NodeId}: Segment {segmentId}: {segmentLight.LightLeft.ToString()} {segmentLight.LightMain.ToString()} {segmentLight.LightRight.ToString()} {segmentLight.LightPedestrian.ToString()}");
                     * }*/

                    liveSegmentLights.UpdateVisuals();
                }
            } catch (Exception e) {
                Log.Error($"Exception in TimedTrafficStep.SetLights for node {timedNode.NodeId}: {e.ToString()}");
                //invalid = true;
            }
        }
		internal void ChangeLightMode(ushort segmentId, ExtVehicleType vehicleType, CustomSegmentLight.Mode mode) {
			CustomSegmentLight light = segmentLights[segmentId].GetCustomLight(vehicleType);
			if (light != null)
				light.CurrentMode = mode;
		}
		private bool RightArrowLightMode(int segmentId, Vector3 screenPos, float lightWidth,
			float pedestrianWidth, float zoom, float lightHeight, CustomSegmentLight segmentDict, bool hoveredSegment) {
			SetAlpha(segmentId, 5);

			var myRect5 =
				new Rect(screenPos.x - lightWidth / 2 - lightWidth - pedestrianWidth + 5f * zoom,
					screenPos.y - lightHeight / 2, lightWidth, lightHeight);

			switch (segmentDict.LightRight) {
				case RoadBaseAI.TrafficLightState.Green:
					GUI.DrawTexture(myRect5, TrafficLightToolTextureResources.GreenLightRightTexture2D);
					break;
				case RoadBaseAI.TrafficLightState.Red:
					GUI.DrawTexture(myRect5, TrafficLightToolTextureResources.RedLightRightTexture2D);
					break;
			}

			if (!myRect5.Contains(Event.current.mousePosition))
				return hoveredSegment;

			_hoveredButton[0] = segmentId;
			_hoveredButton[1] = 5;

			if (!Input.GetMouseButtonDown(0) || mouseClickProcessed)
				return true;

			mouseClickProcessed = true;
			segmentDict.ChangeLightRight();
			return true;
		}
		private bool GetHoveredSegment(Rect myRect1, int segmentId, bool hoveredSegment, CustomSegmentLight segmentDict) {
			if (!myRect1.Contains(Event.current.mousePosition))
				return hoveredSegment;

			//Log.Message("mouse in myRect1");
			_hoveredButton[0] = segmentId;
			_hoveredButton[1] = -1;

			if (!Input.GetMouseButtonDown(0) || mouseClickProcessed)
				return true;
			mouseClickProcessed = true;
			segmentDict.ChangeMode();
			return true;
		}
		internal void housekeeping(bool mayDelete, RoadBaseAI.TrafficLightState mainState = RoadBaseAI.TrafficLightState.Red, RoadBaseAI.TrafficLightState leftState = RoadBaseAI.TrafficLightState.Red, RoadBaseAI.TrafficLightState rightState = RoadBaseAI.TrafficLightState.Red, RoadBaseAI.TrafficLightState pedState = RoadBaseAI.TrafficLightState.Red) {
			// we intentionally never delete vehicle types (because we may want to retain traffic light states if a segment is upgraded or replaced)

			HashSet<ExtVehicleType> setupLights = new HashSet<ExtVehicleType>();
			HashSet<ExtVehicleType> allAllowedTypes = VehicleRestrictionsManager.GetAllowedVehicleTypesAsSet(segmentId, nodeId);
			ExtVehicleType allAllowedMask = VehicleRestrictionsManager.GetAllowedVehicleTypes(segmentId, nodeId);
			SeparateVehicleTypes = ExtVehicleType.None;
#if DEBUGHK
			Log._Debug($"CustomSegmentLights: housekeeping @ seg. {segmentId}, node {nodeId}, allAllowedTypes={string.Join(", ", allAllowedTypes.Select(x => x.ToString()).ToArray())}");
#endif
			bool addPedestrianLight = false;
			uint numLights = 0;
			foreach (ExtVehicleType allowedTypes in allAllowedTypes) {
				foreach (ExtVehicleType mask in singleLaneVehicleTypes) {
					if (setupLights.Contains(mask))
						continue;

					if ((allowedTypes & mask) != ExtVehicleType.None && (allowedTypes & ~(mask | ExtVehicleType.Emergency)) == ExtVehicleType.None) {
#if DEBUGHK
						Log._Debug($"CustomSegmentLights: housekeeping @ seg. {segmentId}, node {nodeId}: adding {mask} light");
#endif

						if (!CustomLights.ContainsKey(mask)) {
							CustomLights.Add(mask, new TrafficLight.CustomSegmentLight(this, nodeId, segmentId, mainState, leftState, rightState));
							VehicleTypes.AddFirst(mask);
						}
						++numLights;
						addPedestrianLight = true;
						autoPedestrianVehicleType = mask;
						mainSegmentLight = CustomLights[mask];
						setupLights.Add(mask);
						SeparateVehicleTypes |= mask;
						break;
					}
				}
			}

			if (allAllowedTypes.Count > numLights) {
#if DEBUGHK
				Log._Debug($"CustomSegmentLights: housekeeping @ seg. {segmentId}, node {nodeId}: adding main vehicle light: {mainVehicleType}");
#endif

				// traffic lights for cars
				if (!CustomLights.ContainsKey(mainVehicleType)) {
					CustomLights.Add(mainVehicleType, new TrafficLight.CustomSegmentLight(this, nodeId, segmentId, mainState, leftState, rightState));
					VehicleTypes.AddFirst(mainVehicleType);
				}
				autoPedestrianVehicleType = mainVehicleType;
				mainSegmentLight = CustomLights[mainVehicleType];
				addPedestrianLight = allAllowedMask == ExtVehicleType.None || (allAllowedMask & ~ExtVehicleType.RailVehicle) != ExtVehicleType.None;
			} else {
				addPedestrianLight = true;
			}

#if DEBUGHK
			if (addPedestrianLight) {
				Log._Debug($"CustomSegmentLights: housekeeping @ seg. {segmentId}, node {nodeId}: adding ped. light");
			}
#endif

			if (mayDelete) {
				// delete traffic lights for non-existing configurations
				HashSet<ExtVehicleType> vehicleTypesToDelete = new HashSet<ExtVehicleType>();
				foreach (KeyValuePair<ExtVehicleType, CustomSegmentLight> e in CustomLights) {
					if (e.Key == mainVehicleType)
						continue;
					if (!setupLights.Contains(e.Key))
						vehicleTypesToDelete.Add(e.Key);
				}

				foreach (ExtVehicleType vehicleType in vehicleTypesToDelete) {
#if DEBUGHK
					Log._Debug($"Deleting traffic light for {vehicleType} at segment {segmentId}, node {nodeId}");
#endif
					CustomLights.Remove(vehicleType);
					VehicleTypes.Remove(vehicleType);
				}
			}

			if (CustomLights.ContainsKey(mainVehicleType) && VehicleTypes.First.Value != mainVehicleType) {
				VehicleTypes.Remove(mainVehicleType);
				VehicleTypes.AddFirst(mainVehicleType);
			}

			if (addPedestrianLight) {
#if DEBUGHK
				Log._Debug($"CustomSegmentLights: housekeeping @ seg. {segmentId}, node {nodeId}: adding pedestrian light");
#endif
				if (pedestrianLightState == null)
					pedestrianLightState = pedState;
			} else {
				pedestrianLightState = null;
			}
		}
        /// <summary>
        /// Calculates the current metrics for flowing and waiting vehicles
        /// </summary>
        /// <param name="wait"></param>
        /// <param name="flow"></param>
        /// <returns>true if the values could be calculated, false otherwise</returns>
        public bool calcWaitFlow(out float wait, out float flow)
        {
#if TRACE
            Singleton <CodeProfiler> .instance.Start("TimedTrafficLightsStep.calcWaitFlow");
#endif

#if DEBUGMETRIC
            bool debug = timedNode.NodeId == 3201;
#else
            bool debug = false;
#endif

#if DEBUGMETRIC
            if (debug)
            {
                Log.Warning($"TimedTrafficLightsStep.calcWaitFlow: ***START*** @ node {timedNode.NodeId}");
            }
#endif

            uint numFlows    = 0;
            uint numWaits    = 0;
            uint curMeanFlow = 0;
            uint curMeanWait = 0;

            // we are the master node. calculate traffic data
            foreach (ushort timedNodeId in timedNode.NodeGroup)
            {
                TrafficLightSimulation sim = TrafficLightSimulation.GetNodeSimulation(timedNodeId);
                if (sim == null || !sim.IsTimedLight())
                {
                    continue;
                }
                TimedTrafficLights slaveTimedNode = sim.TimedLight;
                if (slaveTimedNode.NumSteps() <= timedNode.CurrentStep)
                {
                    for (int i = 0; i < slaveTimedNode.NumSteps(); ++i)
                    {
                        slaveTimedNode.GetStep(i).invalid = true;
                    }
                    continue;
                }
                TimedTrafficLightsStep slaveStep = slaveTimedNode.Steps[timedNode.CurrentStep];

                //List<int> segmentIdsToDelete = new List<int>();

                // minimum time reached. check traffic!
                foreach (KeyValuePair <ushort, CustomSegmentLights> e in slaveStep.segmentLights)
                {
                    var fromSegmentId = e.Key;
                    var segLights     = e.Value;

                    // one of the traffic lights at this segment is green: count minimum traffic flowing through
                    SegmentEnd fromSeg = TrafficPriority.GetPrioritySegment(timedNodeId, fromSegmentId);
                    if (fromSeg == null)
                    {
#if DEBUGMETRIC
                        if (debug)
                        {
                            Log.Warning($"TimedTrafficLightsStep.calcWaitFlow: No priority segment @ seg. {fromSegmentId} found!");
                        }
#endif
                        //Log.Warning("stepDone(): prioSeg is null");
                        //segmentIdsToDelete.Add(fromSegmentId);
                        continue;                         // skip invalid segment
                    }

                    //bool startPhase = getCurrentFrame() <= startFrame + minTime + 2; // during start phase all vehicles on "green" segments are counted as flowing
                    ExtVehicleType validVehicleTypes = VehicleRestrictionsManager.GetAllowedVehicleTypes(fromSegmentId, timedNode.NodeId);

                    foreach (KeyValuePair <byte, ExtVehicleType> e2 in segLights.VehicleTypeByLaneIndex)
                    {
                        byte           laneIndex   = e2.Key;
                        ExtVehicleType vehicleType = e2.Value;
                        if (vehicleType != ExtVehicleType.None && (validVehicleTypes & vehicleType) == ExtVehicleType.None)
                        {
                            continue;
                        }
                        CustomSegmentLight segLight = segLights.GetCustomLight(laneIndex);
                        if (segLight == null)
                        {
                            Log.Warning($"Timed traffic light step: Failed to get custom light for vehicleType {vehicleType} @ seg. {fromSegmentId}, node {timedNode.NodeId}!");
                            continue;
                        }

#if DEBUGMETRIC
                        if (debug)
                        {
                            Log._Debug($"TimedTrafficLightsStep.calcWaitFlow: Checking lane {laneIndex} @ seg. {fromSegmentId}. Vehicle types: {vehicleType}");
                        }
#endif

                        Dictionary <ushort, uint> carsFlowingToSegmentMetric = null;
                        Dictionary <ushort, uint> allCarsToSegmentMetric     = null;
                        try {
                            carsFlowingToSegmentMetric = fromSeg.GetVehicleMetricGoingToSegment(false, laneIndex, debug);
                        } catch (Exception ex) {
                            Log.Warning("calcWaitFlow (1): " + ex.ToString());
                        }

                        try {
                            allCarsToSegmentMetric = fromSeg.GetVehicleMetricGoingToSegment(true, laneIndex, debug);
                        } catch (Exception ex) {
                            Log.Warning("calcWaitFlow (2): " + ex.ToString());
                        }

                        if (carsFlowingToSegmentMetric == null)
                        {
                            continue;
                        }

                        // build directions from toSegment to fromSegment
                        Dictionary <ushort, Direction> directions = new Dictionary <ushort, Direction>();
                        foreach (KeyValuePair <ushort, uint> f in allCarsToSegmentMetric)
                        {
                            var             toSegmentId = f.Key;
                            SegmentGeometry geometry    = SegmentGeometry.Get(fromSegmentId);
                            Direction       dir         = geometry.GetDirection(toSegmentId, timedNodeId == geometry.StartNodeId());
                            directions[toSegmentId] = dir;
#if DEBUGMETRIC
                            if (debug)
                            {
                                Log._Debug($"TimedTrafficLightsStep.calcWaitFlow: Calculated direction for seg. {fromSegmentId} -> seg. {toSegmentId}: {dir}");
                            }
#endif
                        }

                        // calculate waiting/flowing traffic
                        foreach (KeyValuePair <ushort, uint> f in allCarsToSegmentMetric)
                        {
                            ushort toSegmentId               = f.Key;
                            uint   totalNormCarLength        = f.Value;
                            uint   totalFlowingNormCarLength = carsFlowingToSegmentMetric[f.Key];

#if DEBUGMETRIC
                            if (debug)
                            {
                                Log._Debug($"TimedTrafficLightsStep.calcWaitFlow: Total norm. car length of vehicles on lane {laneIndex} going to seg. {toSegmentId}: {totalNormCarLength}");
                            }
#endif

                            bool addToFlow = false;
                            switch (directions[toSegmentId])
                            {
                            case Direction.Turn:
                                addToFlow = TrafficPriority.IsLeftHandDrive() ? segLight.isRightGreen() : segLight.isLeftGreen();
                                break;

                            case Direction.Left:
                                addToFlow = segLight.isLeftGreen();
                                break;

                            case Direction.Right:
                                addToFlow = segLight.isRightGreen();
                                break;

                            case Direction.Forward:
                            default:
                                addToFlow = segLight.isForwardGreen();
                                break;
                            }

                            if (addToFlow)
                            {
                                ++numFlows;
                                curMeanFlow += totalFlowingNormCarLength;
                            }
                            else
                            {
                                ++numWaits;
                                curMeanWait += totalNormCarLength;
                            }

#if DEBUGMETRIC
                            if (debug)
                            {
                                Log._Debug($"TimedTrafficLightsStep.calcWaitFlow: Vehicles on lane {laneIndex} on seg. {fromSegmentId} going to seg. {toSegmentId} flowing? {addToFlow} curMeanFlow={curMeanFlow}, curMeanWait={curMeanWait}");
                            }
#endif
                        }
                    }
                }

                // delete invalid segments from step

                /*foreach (int segmentId in segmentIdsToDelete) {
                 *      slaveStep.segmentLightStates.Remove(segmentId);
                 * }*/

                if (slaveStep.segmentLights.Count <= 0)
                {
                    invalid = true;
                    flow    = 0f;
                    wait    = 0f;
#if TRACE
                    Singleton <CodeProfiler> .instance.Stop("TimedTrafficLightsStep.calcWaitFlow");
#endif
                    return(false);
                }
            }

#if DEBUGMETRIC
            if (debug)
            {
                Log._Debug($"TimedTrafficLightsStep.calcWaitFlow: ### Calculation completed. numFlows={numFlows}, numWaits={numWaits}, curMeanFlow={curMeanFlow}, curMeanWait={curMeanWait}");
            }

            wait = curMeanWait;
            flow = curMeanFlow;
#else
            if (numFlows > 0)
            {
                curMeanFlow /= numFlows;
            }
            if (numWaits > 0)
            {
                curMeanWait /= numWaits;
            }

            float fCurMeanFlow = curMeanFlow;
            fCurMeanFlow /= waitFlowBalance;             // a value smaller than 1 rewards steady traffic currents

            wait = (float)curMeanWait;
            flow = fCurMeanFlow;
#endif
#if TRACE
            Singleton <CodeProfiler> .instance.Stop("TimedTrafficLightsStep.calcWaitFlow");
#endif
            return(true);
        }
		internal void ChangeLightMode(ushort segmentId, ExtVehicleType vehicleType, CustomSegmentLight.Mode mode) {
			foreach (TimedTrafficLightsStep step in Steps) {
				step.ChangeLightMode(segmentId, vehicleType, mode);
			}
		}
Beispiel #21
0
        /// <summary>
        /// Calculates the current metrics for flowing and waiting vehicles
        /// </summary>
        /// <param name="wait"></param>
        /// <param name="flow"></param>
        /// <returns>true if the values could be calculated, false otherwise</returns>
        public bool calcWaitFlow(bool onlyMoving, int stepRefIndex, out float wait, out float flow)
        {
            uint numFlows    = 0;
            uint numWaits    = 0;
            uint curMeanFlow = 0;
            uint curMeanWait = 0;

            // TODO checking agains getCurrentFrame() is only valid if this is the current step
            if (onlyMoving && getCurrentFrame() <= startFrame + minTime + 1)               // during start phase all vehicles on "green" segments are counted as flowing
            {
                onlyMoving = false;
            }

            TrafficLightSimulationManager tlsMan  = TrafficLightSimulationManager.Instance;
            TrafficPriorityManager        prioMan = TrafficPriorityManager.Instance;

            foreach (ushort timedNodeId in timedNode.NodeGroup)
            {
                TrafficLightSimulation sim = tlsMan.GetNodeSimulation(timedNodeId);
                if (sim == null || !sim.IsTimedLight())
                {
                    continue;
                }
                TimedTrafficLights     slaveTimedNode = sim.TimedLight;
                TimedTrafficLightsStep slaveStep      = slaveTimedNode.Steps[stepRefIndex];

                //List<int> segmentIdsToDelete = new List<int>();

                // minimum time reached. check traffic!
                foreach (KeyValuePair <ushort, CustomSegmentLights> e in slaveStep.segmentLights)
                {
                    var sourceSegmentId = e.Key;
                    var segLights       = e.Value;

#if DEBUGMETRIC
                    bool debug = sourceSegmentId == 20857 && GlobalConfig.Instance.DebugSwitches[1];
#elif DEBUG
                    bool debug = GlobalConfig.Instance.DebugSwitches[7] && GlobalConfig.Instance.TTLDebugNodeId == timedNodeId;
#else
                    bool debug = false;
#endif

                    Dictionary <ushort, ArrowDirection> directions = null;
                    if (slaveStep.timedNode.Directions.ContainsKey(sourceSegmentId))
                    {
                        directions = slaveStep.timedNode.Directions[sourceSegmentId];
                    }
                    else
                    {
#if DEBUG
                        if (debug)
                        {
                            Log._Debug($"calcWaitFlow: No arrow directions defined for segment {sourceSegmentId} @ {timedNodeId}");
                        }
#endif
                        continue;
                    }

                    // one of the traffic lights at this segment is green: count minimum traffic flowing through
                    SegmentEnd sourceSegmentEnd = prioMan.GetPrioritySegment(timedNodeId, sourceSegmentId);
                    if (sourceSegmentEnd == null)
                    {
                        Log.Warning($"TimedTrafficLightsStep.calcWaitFlow: No priority segment @ seg. {sourceSegmentId} found!");
                        continue;                         // skip invalid segment
                    }

                    ExtVehicleType validVehicleTypes = VehicleRestrictionsManager.Instance.GetAllowedVehicleTypes(sourceSegmentId, timedNode.NodeId);

                    foreach (KeyValuePair <byte, ExtVehicleType> e2 in segLights.VehicleTypeByLaneIndex)
                    {
                        byte           laneIndex   = e2.Key;
                        ExtVehicleType vehicleType = e2.Value;
                        if (vehicleType != ExtVehicleType.None && (validVehicleTypes & vehicleType) == ExtVehicleType.None)
                        {
                            continue;
                        }
                        CustomSegmentLight segLight = segLights.GetCustomLight(laneIndex);
                        if (segLight == null)
                        {
                            Log.Warning($"Timed traffic light step: Failed to get custom light for vehicleType {vehicleType} @ seg. {sourceSegmentId}, node {timedNode.NodeId}!");
                            continue;
                        }

#if DEBUG
                        if (debug)
                        {
                            Log._Debug($"TimedTrafficLightsStep.calcWaitFlow: Checking lane {laneIndex} @ seg. {sourceSegmentId}. Vehicle types: {vehicleType}");
                        }
#endif

                        Dictionary <ushort, uint> carsFlowingToSegmentMetric = null;
                        Dictionary <ushort, uint> allCarsToSegmentMetric     = null;
                        bool evalFlowingVehicles = segLight.IsAnyGreen();                         // flowing vehicle need only to be evaluated if a light is green
                        if (evalFlowingVehicles && onlyMoving)
                        {
                            carsFlowingToSegmentMetric = sourceSegmentEnd.GetVehicleMetricGoingToSegment(false, laneIndex, debug);
                        }
                        allCarsToSegmentMetric = sourceSegmentEnd.GetVehicleMetricGoingToSegment(true, laneIndex, debug);

                        // calculate waiting/flowing traffic
                        foreach (KeyValuePair <ushort, uint> f in allCarsToSegmentMetric)
                        {
                            ushort targetSegmentId = f.Key;
                            uint   totalNumCars    = f.Value;

                            if (!directions.ContainsKey(targetSegmentId))
                            {
                                Log._Debug($"TimedTrafficLightsStep.calcWaitFlow: Direction undefined for target segment {targetSegmentId} @ {timedNodeId}");
                                continue;
                            }

                            if (evalFlowingVehicles)
                            {
                                uint totalNumFlowingCars = onlyMoving ? carsFlowingToSegmentMetric[f.Key] : totalNumCars;

#if DEBUG
                                if (debug)
                                {
                                    Log._Debug($"TimedTrafficLightsStep.calcWaitFlow: Total num of flowing cars on seg. {sourceSegmentId}, lane {laneIndex} going to seg. {targetSegmentId}: {totalNumFlowingCars}");
                                }
#endif

                                bool addToFlow = false;
                                switch (directions[targetSegmentId])
                                {
                                case ArrowDirection.Turn:
                                    addToFlow = TrafficPriorityManager.IsLeftHandDrive() ? segLight.IsRightGreen() : segLight.IsLeftGreen();
                                    break;

                                case ArrowDirection.Left:
                                    addToFlow = segLight.IsLeftGreen();
                                    break;

                                case ArrowDirection.Right:
                                    addToFlow = segLight.IsRightGreen();
                                    break;

                                case ArrowDirection.Forward:
                                default:
                                    addToFlow = segLight.IsMainGreen();
                                    break;
                                }

                                if (addToFlow)
                                {
                                    curMeanFlow += totalNumFlowingCars;
                                    ++numFlows;
                                }
                                else
                                {
                                    curMeanWait += totalNumCars;
                                    ++numWaits;
                                }
                            }
                            else
                            {
                                curMeanWait += totalNumCars;
                                ++numWaits;
                            }

#if DEBUG
                            if (debug)
                            {
                                Log._Debug($"TimedTrafficLightsStep.calcWaitFlow: Vehicles on lane {laneIndex} on seg. {sourceSegmentId} going to seg. {targetSegmentId} curMeanFlow={curMeanFlow}, curMeanWait={curMeanWait}, numFlows={numFlows}, numWaits={numWaits}");
                            }
#endif
                        }
                    }
                }
            }

            /*if (numFlows > 0)
             *      curMeanFlow /= numFlows;
             * if (numWaits > 0)
             *      curMeanWait /= numWaits;*/

            float fCurMeanFlow = numFlows > 0 ? (float)curMeanFlow / (float)numFlows : 0;
            float fCurMeanWait = numWaits > 0 ? (float)curMeanWait / (float)numWaits : 0;
            fCurMeanFlow /= waitFlowBalance;             // a value smaller than 1 rewards steady traffic currents

            wait = (float)fCurMeanWait;
            flow = fCurMeanFlow;

            return(true);
        }
		private bool LeftForwardRManualSegmentLightMode(bool hasLeftSegment, int segmentId, Vector3 screenPos, float lightWidth,
			float pedestrianWidth, float zoom, float lightHeight, CustomSegmentLight segmentDict, bool hoveredSegment,
			bool hasForwardSegment, bool hasRightSegment) {
			if (hasLeftSegment) {
				// left arrow light
				SetAlpha(segmentId, 3);

				var myRect4 =
					new Rect(screenPos.x - lightWidth / 2 - lightWidth * 2 - pedestrianWidth + 5f * zoom,
						screenPos.y - lightHeight / 2, lightWidth, lightHeight);

				switch (segmentDict.LightLeft) {
					case RoadBaseAI.TrafficLightState.Green:
						GUI.DrawTexture(myRect4, TrafficLightToolTextureResources.GreenLightLeftTexture2D);
						break;
					case RoadBaseAI.TrafficLightState.Red:
						GUI.DrawTexture(myRect4, TrafficLightToolTextureResources.RedLightLeftTexture2D);
						break;
				}

				if (myRect4.Contains(Event.current.mousePosition)) {
					_hoveredButton[0] = segmentId;
					_hoveredButton[1] = 3;
					hoveredSegment = true;

					if (checkClicked()) {
						segmentDict.ChangeLightLeft();
					}
				}
			}

			// forward-right arrow light
			SetAlpha(segmentId, 4);

			var myRect5 =
				new Rect(screenPos.x - lightWidth / 2 - lightWidth - pedestrianWidth + 5f * zoom,
					screenPos.y - lightHeight / 2, lightWidth, lightHeight);

			if (hasForwardSegment && hasRightSegment) {
				switch (segmentDict.LightMain) {
					case RoadBaseAI.TrafficLightState.Green:
						GUI.DrawTexture(myRect5, TrafficLightToolTextureResources.GreenLightForwardRightTexture2D);
						break;
					case RoadBaseAI.TrafficLightState.Red:
						GUI.DrawTexture(myRect5, TrafficLightToolTextureResources.RedLightForwardRightTexture2D);
						break;
				}
			} else if (!hasRightSegment) {
				switch (segmentDict.LightMain) {
					case RoadBaseAI.TrafficLightState.Green:
						GUI.DrawTexture(myRect5, TrafficLightToolTextureResources.GreenLightStraightTexture2D);
						break;
					case RoadBaseAI.TrafficLightState.Red:
						GUI.DrawTexture(myRect5, TrafficLightToolTextureResources.RedLightStraightTexture2D);
						break;
				}
			} else {
				switch (segmentDict.LightMain) {
					case RoadBaseAI.TrafficLightState.Green:
						GUI.DrawTexture(myRect5, TrafficLightToolTextureResources.GreenLightRightTexture2D);
						break;
					case RoadBaseAI.TrafficLightState.Red:
						GUI.DrawTexture(myRect5, TrafficLightToolTextureResources.RedLightRightTexture2D);
						break;
				}
			}

			if (!myRect5.Contains(Event.current.mousePosition))
				return hoveredSegment;
			_hoveredButton[0] = segmentId;
			_hoveredButton[1] = 4;

			if (!Input.GetMouseButtonDown(0) || mouseClickProcessed)
				return true;
			mouseClickProcessed = true;
			segmentDict.ChangeLightMain();
			return true;
		}
Beispiel #23
0
        /*public static TimedTrafficLights AddTimedLight(ushort nodeid, List<ushort> nodeGroup, bool vehiclesMayEnterBlockedJunctions) {
         *      TimedScripts.Add(nodeid, new TimedTrafficLights(nodeid, nodeGroup, vehiclesMayEnterBlockedJunctions));
         *      return TimedScripts[nodeid];
         * }
         *
         * public static void RemoveTimedLight(ushort nodeid) {
         *      TimedScripts.Remove(nodeid);
         * }
         *
         * public static bool IsTimedLight(ushort nodeid) {
         *      return TimedScripts.ContainsKey(nodeid);
         * }
         *
         * public static TimedTrafficLights GetTimedLight(ushort nodeid) {
         *      if (!IsTimedLight(nodeid))
         *              return null;
         *      return TimedScripts[nodeid];
         * }
         *
         * internal static void OnLevelUnloading() {
         *      TimedScripts.Clear();
         * }*/

        internal void handleNewSegments()
        {
            if (NumSteps() <= 0)
            {
                // no steps defined, just create live traffic lights
                for (int s = 0; s < 8; ++s)
                {
                    ushort segmentId = Singleton <NetManager> .instance.m_nodes.m_buffer[NodeId].GetSegment(s);
                    if (segmentId <= 0)
                    {
                        continue;
                    }
                    CustomTrafficLights.AddLiveSegmentLights(NodeId, segmentId);
                }

                return;
            }

            for (int s = 0; s < 8; ++s)
            {
                ushort segmentId = Singleton <NetManager> .instance.m_nodes.m_buffer[NodeId].GetSegment(s);
                if (segmentId <= 0)
                {
                    continue;
                }

                List <ushort> invalidSegmentIds = new List <ushort>();
                bool          isNewSegment      = true;

                foreach (KeyValuePair <ushort, CustomSegmentLights> e in Steps[0].segmentLights)
                {
                    var fromSegmentId = e.Key;

                    if (fromSegmentId == segmentId)
                    {
                        isNewSegment = false;
                    }

                    if (!TrafficPriority.IsPrioritySegment(NodeId, fromSegmentId))
                    {
                        invalidSegmentIds.Add(fromSegmentId);
                    }
                }

                if (isNewSegment)
                {
                    Log._Debug($"New segment detected: {segmentId} @ {NodeId}");
                    // segment was created
                    CustomTrafficLights.AddLiveSegmentLights(NodeId, segmentId);
                    TrafficPriority.AddPrioritySegment(NodeId, segmentId, SegmentEnd.PriorityType.None);

                    if (invalidSegmentIds.Count > 0)
                    {
                        var oldSegmentId = invalidSegmentIds[0];
                        TrafficPriority.RemovePrioritySegment(NodeId, oldSegmentId);
                        Log._Debug($"Replacing old segment {oldSegmentId} @ {NodeId} with new segment {segmentId}");

                        // replace the old segment with the newly created one
                        for (int i = 0; i < NumSteps(); ++i)
                        {
                            CustomSegmentLights segmentLights = Steps[i].segmentLights[oldSegmentId];
                            Steps[i].segmentLights.Remove(oldSegmentId);
                            segmentLights.SegmentId = segmentId;
                            Steps[i].segmentLights.Add(segmentId, segmentLights);
                            Steps[i].calcMaxSegmentLength();
                            CustomSegmentLights liveSegLights = CustomTrafficLights.GetSegmentLights(NodeId, segmentId);
                            foreach (KeyValuePair <ExtVehicleType, CustomSegmentLight> e in segmentLights.CustomLights)
                            {
                                CustomSegmentLight liveSegLight = liveSegLights.GetCustomLight(e.Key);
                                if (liveSegLight == null)
                                {
                                    continue;
                                }
                                liveSegLight.CurrentMode = e.Value.CurrentMode;
                            }
                        }
                    }
                    else
                    {
                        Log._Debug($"Adding new segment {segmentId} to node {NodeId}");

                        // create a new manual light
                        for (int i = 0; i < NumSteps(); ++i)
                        {
                            Steps[i].addSegment(segmentId, true);
                            Steps[i].calcMaxSegmentLength();
                        }
                    }
                }
            }
        }