public void Start()
        {
            /*if (!housekeeping())
             *      return;*/

            for (int s = 0; s < 8; ++s)
            {
                ushort segmentId = Singleton <NetManager> .instance.m_nodes.m_buffer[NodeId].GetSegment(s);
                if (segmentId == 0)
                {
                    continue;
                }
                bool needsAlwaysGreenPedestrian = true;
                foreach (TimedTrafficLightsStep step in Steps)
                {
                    if (!step.segmentLights.ContainsKey(segmentId))
                    {
                        continue;
                    }
                    if (step.segmentLights[segmentId].PedestrianLightState == RoadBaseAI.TrafficLightState.Green)
                    {
                        needsAlwaysGreenPedestrian = false;
                        break;
                    }
                }

                CustomTrafficLights.GetOrLiveSegmentLights(NodeId, segmentId).InvalidPedestrianLight = needsAlwaysGreenPedestrian;
            }

            CurrentStep = 0;
            Steps[0].Start();
            Steps[0].SetLights();

            started = true;
        }
 /// <summary>
 /// Adds a new segment to this step. After adding all steps the method `rebuildSegmentIds` must be called.
 /// </summary>
 /// <param name="segmentId"></param>
 internal void addSegment(ushort segmentId, bool makeRed)
 {
     segmentLights.Add(segmentId, (CustomSegmentLights)CustomTrafficLights.GetOrLiveSegmentLights(timedNode.NodeId, segmentId).Clone());
     if (makeRed)
     {
         segmentLights[segmentId].MakeRed();
     }
     else
     {
         segmentLights[segmentId].MakeRedOrGreen();
     }
 }
        /// <summary>
        /// Updates timed segment lights according to "real-world" traffic light states
        /// </summary>
        public void UpdateLights()
        {
            foreach (KeyValuePair <ushort, CustomSegmentLights> e in segmentLights)
            {
                var segmentId = e.Key;
                var segLights = e.Value;

                //if (segment == 0) continue;
                var liveSegLights = CustomTrafficLights.GetSegmentLights(timedNode.NodeId, segmentId);
                if (liveSegLights == null)
                {
                    continue;
                }

                segLights.SetLights(liveSegLights);
            }
        }
        /// <summary>
        /// Updates timed segment lights according to "real-world" traffic light states
        /// </summary>
        public void UpdateLights()
        {
#if TRACE
            Singleton <CodeProfiler> .instance.Start("TimedTrafficLightsStep.UpdateLights");
#endif
            foreach (KeyValuePair <ushort, CustomSegmentLights> e in segmentLights)
            {
                var segmentId = e.Key;
                var segLights = e.Value;

                //if (segment == 0) continue;
                var liveSegLights = CustomTrafficLights.GetSegmentLights(timedNode.NodeId, segmentId);
                if (liveSegLights == null)
                {
                    continue;
                }

                segLights.SetLights(liveSegLights);
            }
#if TRACE
            Singleton <CodeProfiler> .instance.Stop("TimedTrafficLightsStep.UpdateLights");
#endif
        }
Esempio n. 5
0
        public TimedTrafficLights(ushort nodeId, IEnumerable <ushort> nodeGroup)
        {
            this.NodeId  = nodeId;
            NodeGroup    = new List <ushort>(nodeGroup);
            masterNodeId = NodeGroup[0];

            // setup priority segments & live traffic lights
            foreach (ushort slaveNodeId in nodeGroup)
            {
                for (int s = 0; s < 8; ++s)
                {
                    ushort segmentId = Singleton <NetManager> .instance.m_nodes.m_buffer[slaveNodeId].GetSegment(s);
                    if (segmentId <= 0)
                    {
                        continue;
                    }
                    CustomRoadAI.GetSegmentGeometry(segmentId).Recalculate(true, true);
                    TrafficPriority.AddPrioritySegment(slaveNodeId, segmentId, SegmentEnd.PriorityType.None);
                    CustomTrafficLights.AddLiveSegmentLights(slaveNodeId, segmentId);
                }
            }

            started = false;
        }
        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
        }
Esempio n. 7
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();
                        }
                    }
                }
            }
        }
Esempio n. 8
0
        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 = CustomTrafficLights.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);
        }
Esempio n. 9
0
        internal bool housekeeping(bool housekeepCustomLights)
        {
            bool          mayStart        = true;
            List <ushort> nodeIdsToDelete = new List <ushort>();

            int i = 0;

            foreach (ushort otherNodeId in NodeGroup)
            {
                if ((Singleton <NetManager> .instance.m_nodes.m_buffer[otherNodeId].m_flags & NetNode.Flags.Created) == NetNode.Flags.None)
                {
                    Log.Warning($"Timed housekeeping: Remove node {otherNodeId}");
                    nodeIdsToDelete.Add(otherNodeId);
                    if (otherNodeId == NodeId)
                    {
                        Log.Warning($"Timed housekeeping: Other is this. mayStart = false");
                        mayStart = false;
                    }
                }
                ++i;
            }

            foreach (ushort nodeIdToDelete in nodeIdsToDelete)
            {
                NodeGroup.Remove(nodeIdToDelete);
                TrafficLightSimulation.RemoveNodeFromSimulation(nodeIdToDelete, false);
            }

            // check that live lights exist (TODO refactor?)
            foreach (ushort timedNodeId in NodeGroup)
            {
                for (int s = 0; s < 8; s++)
                {
                    var segmentId = Singleton <NetManager> .instance.m_nodes.m_buffer[timedNodeId].GetSegment(s);

                    if (segmentId == 0)
                    {
                        continue;
                    }
                    CustomTrafficLights.AddLiveSegmentLights(timedNodeId, segmentId);
                }
            }

            if (NodeGroup.Count <= 0)
            {
                Log.Warning($"Timed housekeeping: No lights left. mayStart = false");
                mayStart = false;
                return(mayStart);
            }
            //Log.Warning($"Timed housekeeping: Setting master node to {NodeGroup[0]}");
            masterNodeId = NodeGroup[0];

            if (housekeepCustomLights)
            {
                foreach (TimedTrafficLightsStep step in Steps)
                {
                    foreach (KeyValuePair <ushort, CustomSegmentLights> e in step.segmentLights)
                    {
                        e.Value.housekeeping(true);
                    }
                }
            }

            return(mayStart);
        }
        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;
            }

            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 (!TrafficPriority.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];
                        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)
                        {
                            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 = CustomTrafficLights.GetSegmentLights(NodeId, segmentId);
                            if (liveSegLights == null)
                            {
                                Log.Error($"No live segment lights for seg. {segmentId} @ node {NodeId} found!");
                                CustomTrafficLights.AddSegmentLights(NodeId, segmentId);
                                liveSegLights = CustomTrafficLights.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();
                        }
                    }
                }
            }
        }