示例#1
0
        public void SetLights(bool noTransition)
        {
            try {
                bool atEndTransition   = !noTransition && isInEndTransition();                       // = yellow
                bool atStartTransition = !noTransition && !atEndTransition && isInStartTransition(); // = red + yellow

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

                foreach (KeyValuePair <ushort, ManualSegmentLight> e in segmentLightStates)
                {
                    var segmentId      = e.Key;
                    var segLightState  = e.Value;
                    var prevLightState = previousStep.segmentLightStates[segmentId];
                    var nextLightState = nextStep.segmentLightStates[segmentId];

                    var segmentLight = TrafficLightsManual.GetSegmentLight(nodeId, segmentId);
                    if (segmentLight == null)
                    {
                        continue;
                    }

                    segmentLight.LightMain       = calcLightState(prevLightState.LightMain, segLightState.LightMain, nextLightState.LightMain, atStartTransition, atEndTransition);
                    segmentLight.LightLeft       = calcLightState(prevLightState.LightLeft, segLightState.LightLeft, nextLightState.LightLeft, atStartTransition, atEndTransition);
                    segmentLight.LightRight      = calcLightState(prevLightState.LightRight, segLightState.LightRight, nextLightState.LightRight, atStartTransition, atEndTransition);
                    segmentLight.LightPedestrian = calcLightState(prevLightState.LightPedestrian, segLightState.LightPedestrian, nextLightState.LightPedestrian, atStartTransition, atEndTransition);

                    segmentLight.UpdateVisuals();
                }
            } catch (Exception e) {
                Log.Error($"Exception in TimedTrafficStep.SetLights: {e.Message}");
                invalid = true;
            }
        }
示例#2
0
        public bool StepDone()
        {
            if (stepDone)
            {
                return(true);
            }

            if (startFrame + maxTime <= getCurrentFrame())
            {
                // maximum time reached. switch!
#if DEBUG
                //Log.Message("step finished @ " + nodeId);
#endif
                stepDone           = true;
                endTransitionStart = (int)getCurrentFrame();
                return(stepDone);
            }

            if (startFrame + minTime <= getCurrentFrame())
            {
                if (masterNodeId != null && TrafficLightsTimed.IsTimedLight((ushort)masterNodeId))
                {
                    TrafficLightsTimed masterTimedNode = TrafficLightsTimed.GetTimedLight((ushort)masterNodeId);
                    bool done = masterTimedNode.Steps[masterTimedNode.CurrentStep].StepDone();
#if DEBUG
                    //Log.Message("step finished (1) @ " + nodeId);
#endif
                    stepDone = done;
                    if (stepDone)
                    {
                        endTransitionStart = (int)getCurrentFrame();
                    }
                    return(stepDone);
                }
                else
                {
                    int   numFlows    = 0;
                    int   numWaits    = 0;
                    float curMeanFlow = 0;
                    float curMeanWait = 0;

                    // we are the master node. calculate traffic data
                    foreach (ushort timedNodeId in groupNodeIds)
                    {
                        if (!TrafficLightsTimed.IsTimedLight(timedNodeId))
                        {
                            continue;
                        }
                        TrafficLightsTimed slaveTimedNode = TrafficLightsTimed.GetTimedLight(timedNodeId);
                        TimedTrafficStep   slaveStep      = slaveTimedNode.Steps[timedNode.CurrentStep];

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

                        // minimum time reached. check traffic!
                        foreach (KeyValuePair <ushort, ManualSegmentLight> e in slaveStep.segmentLightStates)
                        {
                            var   fromSegmentId = e.Key;
                            var   segLightState = e.Value;
                            float segmentWeight = Singleton <NetManager> .instance.m_segments.m_buffer[fromSegmentId].m_averageLength / maxSegmentLength;

                            // one of the traffic lights at this segment is green: count minimum traffic flowing through
                            PrioritySegment prioSeg = TrafficPriority.GetPrioritySegment(timedNodeId, fromSegmentId);
                            if (prioSeg == null)
                            {
                                //Log.Warning("stepDone(): prioSeg is null");
                                //segmentIdsToDelete.Add(fromSegmentId);
                                continue;                                 // skip invalid segment
                            }
                            foreach (KeyValuePair <ushort, int> f in prioSeg.numCarsGoingToSegmentId)
                            {
                                var toSegmentId = f.Key;
                                var numCars     = f.Value;

                                TrafficPriority.Direction dir = TrafficPriority.GetDirection(fromSegmentId, toSegmentId, timedNodeId);
                                bool addToFlow = false;
                                switch (dir)
                                {
                                case TrafficPriority.Direction.Left:
                                    if (segLightState.isLeftGreen())
                                    {
                                        addToFlow = true;
                                    }
                                    break;

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

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

                                if (addToFlow)
                                {
                                    ++numFlows;
                                    curMeanFlow += (float)numCars * segmentWeight;
                                }
                                else
                                {
                                    ++numWaits;
                                    curMeanWait += (float)numCars * segmentWeight;
                                }
                            }
                        }

                        // delete invalid segments from step

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

                        if (slaveStep.segmentLightStates.Count <= 0)
                        {
                            invalid = true;
                            return(true);
                        }
                    }

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

                    float decisionValue = 0.8f;                     // a value smaller than 1 rewards steady traffic currents
                    curMeanFlow /= decisionValue;

                    if (Single.IsNaN(minFlow))
                    {
                        minFlow = curMeanFlow;
                    }
                    else
                    {
                        minFlow = Math.Min(curMeanFlow, minFlow);
                    }

                    if (Single.IsNaN(maxWait))
                    {
                        maxWait = curMeanWait;
                    }
                    else
                    {
                        maxWait = Math.Max(curMeanWait, maxWait);
                    }

                    // if more cars are waiting than flowing, we change the step
                    bool done = maxWait > 0 && minFlow < maxWait;
#if DEBUG
                    //Log.Message("step finished (2) @ " + nodeId);
#endif
                    stepDone = done;
                    if (stepDone)
                    {
                        endTransitionStart = (int)getCurrentFrame();
                    }
                    return(stepDone);
                }
            }
            return(false);
        }