GetPrioritySegment() public static method

public static GetPrioritySegment ( ushort nodeId, ushort segmentId ) : SegmentEnd
nodeId ushort
segmentId ushort
return SegmentEnd
        /*public VehiclePosition GetCurrentPosition() {
         *      LinkedListNode<VehiclePosition> firstNode = CurrentPosition;
         *      if (firstNode == null)
         *              return null;
         *      return firstNode.Value;
         * }*/

        internal void UpdatePosition(ref Vehicle vehicleData, ref PathUnit.Position curPos, ref PathUnit.Position nextPos, bool skipCheck = false)
        {
            if (!skipCheck && !CheckValidity(ref vehicleData))
            {
                return;
            }

            LastPositionUpdate = Singleton <SimulationManager> .instance.m_currentFrameIndex;

            SegmentEnd end = TrafficPriority.GetPrioritySegment(GetTransitNodeId(ref curPos, ref nextPos), curPos.m_segment);

            if (CurrentSegmentEnd != end)
            {
                if (CurrentSegmentEnd != null)
                {
                    Unlink();
                }

                WaitTime = 0;
                if (end != null)
                {
                    Link(end);
                    JunctionTransitState = VehicleJunctionTransitState.Enter;
                }
                else
                {
                    JunctionTransitState = VehicleJunctionTransitState.None;
                }
            }
        }
Exemplo n.º 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);
        }
Exemplo n.º 3
0
        internal void Recalculate()
        {
#if DEBUGGEO
            Log._Debug($"NodeGeometry: Recalculate @ {NodeId}");
#endif

            Cleanup();

            Flags.applyNodeTrafficLightFlag(NodeId);

            // check if node is valid
            if (!IsValid())
            {
                for (int i = 0; i < 8; ++i)
                {
                    SegmentEndGeometries[i] = null;
                }
                TrafficLightSimulation.RemoveNodeFromSimulation(NodeId, false, true);
                Flags.setNodeTrafficLight(NodeId, false);
            }
            else
            {
                NetManager netManager      = Singleton <NetManager> .instance;
                bool       hasTrafficLight = (netManager.m_nodes.m_buffer[NodeId].m_flags & NetNode.Flags.TrafficLights) != NetNode.Flags.None;
                var        nodeSim         = TrafficLightSimulation.GetNodeSimulation(NodeId);
                if (nodeSim == null)
                {
                    byte numSegmentsWithSigns = 0;
                    for (var s = 0; s < 8; s++)
                    {
                        var segmentId = netManager.m_nodes.m_buffer[NodeId].GetSegment(s);
                        if (segmentId <= 0)
                        {
                            continue;
                        }

#if DEBUGx
                        Log._Debug($"NodeGeometry.Recalculate: Housekeeping segment {segmentId}");
#endif

                        SegmentEnd prioritySegment = TrafficPriority.GetPrioritySegment(NodeId, segmentId);
                        if (prioritySegment == null)
                        {
                            continue;
                        }

                        // if node is a traffic light, it must not have priority signs
                        if (hasTrafficLight && prioritySegment.Type != SegmentEnd.PriorityType.None)
                        {
                            Log.Warning($"Housekeeping: Node {NodeId}, Segment {segmentId} is a priority sign but node has a traffic light!");
                            prioritySegment.Type = SegmentEnd.PriorityType.None;
                        }

                        // if a priority sign is set, everything is ok
                        if (prioritySegment.Type != SegmentEnd.PriorityType.None)
                        {
                            ++numSegmentsWithSigns;
                        }
                    }

                    if (numSegmentsWithSigns > 0)
                    {
                        // add priority segments for newly created segments
                        numSegmentsWithSigns += TrafficPriority.AddPriorityNode(NodeId);
                    }
                }

                // calculate node properties
                byte incomingSegments = 0;
                byte outgoingSegments = 0;
                for (int i = 0; i < 8; ++i)
                {
                    if (SegmentEndGeometries[i] == null)
                    {
                        continue;
                    }
#if DEBUGGEO
                    Log._Debug($"NodeGeometry.Recalculate: Iterating over segment end {SegmentEndGeometries[i].SegmentId} @ node {NodeId}");
#endif

                    bool startNode = SegmentEndGeometries[i].StartNode;
                    if (SegmentEndGeometries[i].GetSegmentGeometry().IsIncoming(startNode))
                    {
                        ++incomingSegments;
                    }
                    if (SegmentEndGeometries[i].GetSegmentGeometry().IsOutgoing(startNode))
                    {
                        ++outgoingSegments;
                    }
                }

                IsSimpleJunction = incomingSegments == 1 || outgoingSegments == 1;
#if DEBUGGEO
                Log._Debug($"NodeGeometry.Recalculate: Node {NodeId} has {incomingSegments} incoming and {outgoingSegments} outgoing segments.");
#endif
            }

            NotifyObservers();
        }