public static void RemoveNodeFromSimulation(ushort nodeId) { //lock (simLock) { if (!LightSimByNodeId.ContainsKey(nodeId)) { return; } var nodeSim = LightSimByNodeId[nodeId]; var isTimedLight = nodeSim.TimedTrafficLights; TrafficLightsTimed timedLights = null; if (isTimedLight) { timedLights = TrafficLightsTimed.GetTimedLight(nodeId); } nodeSim.Destroy(); if (isTimedLight && timedLights != null) { foreach (ushort otherNodeId in timedLights.NodeGroup) { Log.Message($"Removing simulation @ node {otherNodeId} (group)"); LightSimByNodeId.Remove(otherNodeId); } } LightSimByNodeId.Remove(nodeId); //} }
private bool invalid = false; // TODO rework public TimedTrafficStep(int minTime, int maxTime, ushort nodeId, ushort masterNodeId, List <ushort> groupNodeIds) { this.nodeId = nodeId; this.minTime = minTime; this.maxTime = maxTime; this.timedNode = TrafficLightsTimed.GetTimedLight(nodeId); if (nodeId == masterNodeId) { this.masterNodeId = null; } else { this.masterNodeId = masterNodeId; } this.groupNodeIds = groupNodeIds; var node = TrafficLightTool.GetNetNode(nodeId); minFlow = Single.NaN; maxWait = Single.NaN; endTransitionStart = -1; stepDone = false; for (var s = 0; s < 8; s++) { var segmentId = node.GetSegment(s); if (segmentId <= 0) { continue; } addSegment(segmentId); } rebuildSegmentIds(); }
public static void housekeeping() { try { // delete invalid segments List <ushort> segmentIdsToDelete = new List <ushort>(); foreach (KeyValuePair <ushort, TrafficSegment> e in PrioritySegments) { var segmentId = e.Key; if (segmentId <= 0) { segmentIdsToDelete.Add(segmentId); continue; } NetSegment segment = Singleton <NetManager> .instance.m_segments.m_buffer[segmentId]; if (segment.m_flags == NetSegment.Flags.None || (!priorityNodes.Contains(segment.m_startNode) && !priorityNodes.Contains(segment.m_endNode))) { segmentIdsToDelete.Add(segmentId); } } foreach (var sId in segmentIdsToDelete) { Log.Warning("Housekeeping: Deleting segment " + sId); PrioritySegments.Remove(sId); TrafficLightsManual.RemoveSegmentLight(sId); } // delete invalid nodes List <ushort> nodeIdsToDelete = new List <ushort>(); foreach (ushort nodeId in priorityNodes) { NodeValidityState nodeState = NodeValidityState.Valid; if (!isValidPriorityNode(nodeId, out nodeState)) { if (nodeState != NodeValidityState.SimWithoutLight) { nodeIdsToDelete.Add(nodeId); } switch (nodeState) { case NodeValidityState.SimWithoutLight: Log.Warning("Housekeeping: Re-adding traffic light at node " + nodeId); Singleton <NetManager> .instance.m_nodes.m_buffer[nodeId].m_flags |= NetNode.Flags.TrafficLights; break; case NodeValidityState.Unused: // delete traffic light simulation Log.Warning("Housekeeping: RemoveNodeFromSimulation " + nodeId); RemoveNodeFromSimulation(nodeId); break; default: break; } } } foreach (var nId in nodeIdsToDelete) { Log.Warning("Housekeeping: Deleting node " + nId); RemovePrioritySegments(nId); } // add newly created segments to timed traffic lights foreach (KeyValuePair <ushort, TrafficLightsTimed> e in TrafficLightsTimed.TimedScripts) { TrafficLightsTimed timedLights = e.Value; ushort nodeId = e.Key; timedLights.handleNewSegments(); } } catch (Exception e) { Log.Warning($"Housekeeping failed: {e.Message}"); } }
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); }