public static void AddPrioritySegment(ushort nodeId, int segmentId, PrioritySegment.PriorityType type) { if (PrioritySegments.ContainsKey(segmentId)) { var prioritySegment = PrioritySegments[segmentId]; prioritySegment.Node2 = nodeId; prioritySegment.Instance2 = new PrioritySegment(nodeId, segmentId, type); } else { PrioritySegments.Add(segmentId, new TrafficSegment()); PrioritySegments[segmentId].Segment = segmentId; PrioritySegments[segmentId].Node1 = nodeId; PrioritySegments[segmentId].Instance1 = new PrioritySegment(nodeId, segmentId, type); } }
public static void AddPrioritySegment(ushort nodeId, ushort segmentId, PrioritySegment.PriorityType type) { if (nodeId <= 0 || segmentId <= 0) return; Log.Message("adding PrioritySegment @ node " + nodeId + ", seg. " + segmentId + ", type " + type); var prioritySegment = PrioritySegments[segmentId]; if (prioritySegment != null) { // do not replace with IsPrioritySegment! prioritySegment.Segment = segmentId; Log.Message("Priority segment already exists. Node1=" + prioritySegment.Node1 + " Node2=" + prioritySegment.Node2); if (prioritySegment.Node1 == nodeId || prioritySegment.Node1 == 0) { Log.Message("Updating Node1"); prioritySegment.Node1 = nodeId; PrioritySegments[segmentId].Instance1 = new PrioritySegment(nodeId, segmentId, type); return; } if (prioritySegment.Node2 != 0) { // overwrite Node2 Log.Warning("Overwriting priority segment for node " + nodeId + ", seg. " + segmentId + ", type " + type); prioritySegment.Node2 = nodeId; prioritySegment.Instance2 = new PrioritySegment(nodeId, segmentId, type); rebuildPriorityNodes(); } else { // add Node2 Log.Message("Adding as Node2"); prioritySegment.Node2 = nodeId; prioritySegment.Instance2 = new PrioritySegment(nodeId, segmentId, type); } } else { // add Node1 Log.Message("Adding as Node1"); prioritySegment = new TrafficSegment(); prioritySegment.Segment = segmentId; prioritySegment.Node1 = nodeId; prioritySegment.Instance1 = new PrioritySegment(nodeId, segmentId, type); PrioritySegments[segmentId] = prioritySegment; } priorityNodes.Add(nodeId); }
private static bool isValidPriorityNode(ushort nodeId, out NodeValidityState nodeState) { nodeState = NodeValidityState.Valid; if (nodeId <= 0) { nodeState = NodeValidityState.Invalid; return(false); } var node = Singleton <NetManager> .instance.m_nodes.m_buffer[nodeId]; if (node.m_flags == NetNode.Flags.None) { nodeState = NodeValidityState.Unused; return(false); // node is unused } var nodeSim = GetNodeSimulation(nodeId); if (nodeSim != null) { if ((node.m_flags & NetNode.Flags.TrafficLights) == NetNode.Flags.None) { // traffic light simulation is active but node does not have a traffic light nodeState = NodeValidityState.SimWithoutLight; return(false); } else { // check if all timed step segments are valid if (nodeSim.FlagTimedTrafficLights && nodeSim.TimedTrafficLightsActive) { TrafficLightsTimed timedLight = TrafficLightsTimed.GetTimedLight(nodeId); if (timedLight == null || timedLight.Steps.Count <= 0) { Log.Warning("Housekeeping: Timed light is null or no steps!"); RemoveNodeFromSimulation(nodeId); return(false); } /*foreach (var segmentId in timedLight.Steps[0].segmentIds) { * if (! IsPrioritySegment(nodeId, segmentId)) { * Log.Warning("Housekeeping: Timed light - Priority segment has gone away!"); * RemoveNodeFromSimulation(nodeId); * return false; * } * }*/ } return(true); } } else { bool ok = false; for (var s = 0; s < 8; s++) { var segmentId = node.GetSegment(s); if (segmentId <= 0) { continue; } NetSegment segment = Singleton <NetManager> .instance.m_segments.m_buffer[segmentId]; if (segment.m_startNode != nodeId && segment.m_endNode != nodeId) { continue; } PrioritySegment prioritySegment = GetPrioritySegment(nodeId, segmentId); if (prioritySegment == null) { continue; } // if node is a traffic light, it must not have priority signs if ((node.m_flags & NetNode.Flags.TrafficLights) != NetNode.Flags.None) { prioritySegment.Type = PrioritySegment.PriorityType.None; } // if a priority sign is set, everything is ok if (prioritySegment.Type != PrioritySegment.PriorityType.None) { ok = true; break; } } if (!ok) { nodeState = NodeValidityState.NoValidSegments; } return(ok); } }
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); }