internal CustomSegmentLight GetCustomLight(byte laneIndex) { if (!VehicleTypeByLaneIndex.ContainsKey(laneIndex)) { #if DEBUGGET Log._Debug($"CustomSegmentLights.GetCustomLight({laneIndex}): No vehicle type found for lane index"); #endif return(mainSegmentLight); } ExtVehicleType vehicleType = VehicleTypeByLaneIndex[laneIndex]; #if DEBUGGET Log._Debug($"CustomSegmentLights.GetCustomLight({laneIndex}): Vehicle type is {vehicleType}"); #endif if (!CustomLights.ContainsKey(vehicleType)) { #if DEBUGGET Log._Debug($"CustomSegmentLights.GetCustomLight({laneIndex}): No custom light found for vehicle type {vehicleType}"); #endif return(mainSegmentLight); } CustomSegmentLight light = CustomLights[vehicleType]; #if DEBUGGET Log._Debug($"CustomSegmentLights.GetCustomLight({laneIndex}): Returning custom light for vehicle type {vehicleType}"); #endif return(light); }
public RoadBaseAI.TrafficLightState GetLight(ushort segmentId, ExtVehicleType vehicleType, int lightType) { CustomSegmentLight segLight = segmentLights[segmentId].GetCustomLight(vehicleType); if (segLight != null) { switch (lightType) { case 0: return(segLight.LightMain); case 1: return(segLight.LightLeft); case 2: return(segLight.LightRight); case 3: RoadBaseAI.TrafficLightState?pedState = segmentLights[segmentId].PedestrianLightState; return(pedState == null ? RoadBaseAI.TrafficLightState.Red : (RoadBaseAI.TrafficLightState)pedState); } } return(RoadBaseAI.TrafficLightState.Green); }
internal CustomSegmentLight GetCustomLight(ExtVehicleType vehicleType) { #if TRACE Singleton <CodeProfiler> .instance.Start("CustomSegmentLights.GetCustomLight(vehicleType)"); #endif CustomSegmentLight ret = null; if (CustomLights.ContainsKey(vehicleType)) { ret = CustomLights[vehicleType]; } else { ret = mainSegmentLight; } #if TRACE Singleton <CodeProfiler> .instance.Stop("CustomSegmentLights.GetCustomLight(vehicleType)"); #endif return(ret); /*if (vehicleType != ExtVehicleType.None) * Log._Debug($"No traffic light for vehicle type {vehicleType} defined at segment {segmentId}, node {nodeId}.");*/ }
internal void ChangeLightMode(ushort segmentId, ExtVehicleType vehicleType, CustomSegmentLight.Mode mode) { CustomSegmentLight light = segmentLights[segmentId].GetCustomLight(vehicleType); if (light != null) { light.CurrentMode = mode; } }
internal void SetLights(CustomSegmentLights otherLights) { foreach (KeyValuePair <ExtVehicleType, CustomSegmentLight> e in otherLights.CustomLights) { CustomSegmentLight ourLight = null; if (!CustomLights.TryGetValue(e.Key, out ourLight)) { continue; } ourLight.SetStates(e.Value.LightMain, e.Value.LightLeft, e.Value.LightRight, false); //ourLight.LightPedestrian = e.Value.LightPedestrian; } pedestrianLightState = otherLights.pedestrianLightState; manualPedestrianMode = otherLights.manualPedestrianMode; AutoPedestrianLightState = otherLights.AutoPedestrianLightState; }
internal CustomSegmentLight GetCustomLight(ExtVehicleType vehicleType) { CustomSegmentLight ret = null; if (CustomLights.ContainsKey(vehicleType)) { ret = CustomLights[vehicleType]; } else { ret = mainSegmentLight; } return(ret); /*if (vehicleType != ExtVehicleType.None) * Log._Debug($"No traffic light for vehicle type {vehicleType} defined at segment {segmentId}, node {nodeId}.");*/ }
public RoadBaseAI.TrafficLightState GetAutoPedestrianLightState() { RoadBaseAI.TrafficLightState?vehicleState = null; foreach (KeyValuePair <ExtVehicleType, CustomSegmentLight> e in CustomLights) { if (vehicleState == null || e.Value.GetLightMain() != RoadBaseAI.TrafficLightState.Red) { vehicleState = e.Value.GetLightMain(); } if (vehicleState == RoadBaseAI.TrafficLightState.Green) { break; } } if (vehicleState == null) { return(RoadBaseAI.TrafficLightState.Red); } return(CustomSegmentLight.InvertLight((RoadBaseAI.TrafficLightState)vehicleState)); }
internal void SetLights(CustomSegmentLights otherLights) { #if TRACE Singleton <CodeProfiler> .instance.Start("CustomSegmentLights.SetLights"); #endif foreach (KeyValuePair <ExtVehicleType, CustomSegmentLight> e in otherLights.CustomLights) { CustomSegmentLight ourLight = null; if (!CustomLights.TryGetValue(e.Key, out ourLight)) { continue; } ourLight.LightMain = e.Value.LightMain; ourLight.LightLeft = e.Value.LightLeft; ourLight.LightRight = e.Value.LightRight; //ourLight.LightPedestrian = e.Value.LightPedestrian; } pedestrianLightState = otherLights.pedestrianLightState; ManualPedestrianMode = otherLights.ManualPedestrianMode; #if TRACE Singleton <CodeProfiler> .instance.Stop("CustomSegmentLights.SetLights"); #endif }
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 }
/// <summary> /// Calculates the current metrics for flowing and waiting vehicles /// </summary> /// <param name="wait"></param> /// <param name="flow"></param> /// <returns>true if the values could be calculated, false otherwise</returns> public bool calcWaitFlow(out float wait, out float flow) { #if DEBUG bool debug = timedNode.NodeId == 17857; #else bool debug = false; #endif uint numFlows = 0; uint numWaits = 0; uint curMeanFlow = 0; uint curMeanWait = 0; // we are the master node. calculate traffic data foreach (ushort timedNodeId in groupNodeIds) { TrafficLightSimulation sim = TrafficLightSimulation.GetNodeSimulation(timedNodeId); if (sim == null || !sim.IsTimedLight()) { continue; } TimedTrafficLights slaveTimedNode = sim.TimedLight; if (slaveTimedNode.NumSteps() <= timedNode.CurrentStep) { for (int i = 0; i < slaveTimedNode.NumSteps(); ++i) { slaveTimedNode.GetStep(i).invalid = true; } continue; } TimedTrafficLightsStep slaveStep = slaveTimedNode.Steps[timedNode.CurrentStep]; //List<int> segmentIdsToDelete = new List<int>(); // minimum time reached. check traffic! foreach (KeyValuePair <ushort, CustomSegmentLights> e in slaveStep.segmentLights) { var fromSegmentId = e.Key; var segLights = e.Value; // one of the traffic lights at this segment is green: count minimum traffic flowing through SegmentEnd fromSeg = TrafficPriority.GetPrioritySegment(timedNodeId, fromSegmentId); if (fromSeg == null) { //Log.Warning("stepDone(): prioSeg is null"); //segmentIdsToDelete.Add(fromSegmentId); continue; // skip invalid segment } bool startPhase = getCurrentFrame() <= startFrame + minTime + 2; // during start phase all vehicles on "green" segments are counted as flowing ExtVehicleType validVehicleTypes = VehicleRestrictionsManager.GetAllowedVehicleTypes(fromSegmentId, timedNode.NodeId); foreach (ExtVehicleType vehicleType in segLights.VehicleTypes) { if (vehicleType != ExtVehicleType.None && (validVehicleTypes & vehicleType) == ExtVehicleType.None) { continue; } CustomSegmentLight segLight = segLights.GetCustomLight(vehicleType); if (segLight == null) { Log.Warning($"Timed traffic light step: Failed to get custom light for vehicleType {vehicleType} @ seg. {fromSegmentId}, node {timedNode.NodeId}!"); continue; } Dictionary <ushort, uint>[] carsToSegmentMetrics = new Dictionary <ushort, uint> [startPhase ? 1: 2]; try { carsToSegmentMetrics[0] = fromSeg.GetVehicleMetricGoingToSegment(null, vehicleType, segLights.SeparateVehicleTypes, debug); } catch (Exception ex) { Log.Warning("calcWaitFlow: " + ex.ToString()); } if (!startPhase) { try { carsToSegmentMetrics[1] = fromSeg.GetVehicleMetricGoingToSegment(0.1f, vehicleType, segLights.SeparateVehicleTypes, debug); } catch (Exception ex) { Log.Warning("calcWaitFlow: " + ex.ToString()); } } if (carsToSegmentMetrics[0] == null) { continue; } // build directions from toSegment to fromSegment Dictionary <ushort, Direction> directions = new Dictionary <ushort, Direction>(); foreach (KeyValuePair <ushort, uint> f in carsToSegmentMetrics[0]) { var toSegmentId = f.Key; SegmentGeometry geometry = CustomRoadAI.GetSegmentGeometry(fromSegmentId); Direction dir = geometry.GetDirection(toSegmentId, timedNodeId); directions[toSegmentId] = dir; } // calculate waiting/flowing traffic for (int i = 0; i < carsToSegmentMetrics.Length; ++i) { if (carsToSegmentMetrics[i] == null) { continue; } foreach (KeyValuePair <ushort, uint> f in carsToSegmentMetrics[i]) { ushort toSegmentId = f.Key; uint totalNormCarLength = f.Value; bool addToFlow = false; switch (directions[toSegmentId]) { case Direction.Left: if (segLight.isLeftGreen()) { addToFlow = true; } break; case Direction.Right: if (segLight.isRightGreen()) { addToFlow = true; } break; case Direction.Forward: default: if (segLight.isForwardGreen()) { addToFlow = true; } break; } if (addToFlow) { if (i > 0 || startPhase) { ++numFlows; curMeanFlow += totalNormCarLength; } } else if (i == 0) { ++numWaits; curMeanWait += totalNormCarLength; } } } } } // delete invalid segments from step /*foreach (int segmentId in segmentIdsToDelete) { * slaveStep.segmentLightStates.Remove(segmentId); * }*/ if (slaveStep.segmentLights.Count <= 0) { invalid = true; flow = 0f; wait = 0f; return(false); } } if (numFlows > 0) { curMeanFlow /= numFlows; } if (numWaits > 0) { curMeanWait /= numWaits; } float fCurMeanFlow = curMeanFlow; fCurMeanFlow /= 100f * waitFlowBalance; // a value smaller than 1 rewards steady traffic currents wait = (float)curMeanWait / 100f; flow = fCurMeanFlow; return(true); }
internal void housekeeping(bool mayDelete, bool calculateAutoPedLight, RoadBaseAI.TrafficLightState mainState = RoadBaseAI.TrafficLightState.Red, RoadBaseAI.TrafficLightState leftState = RoadBaseAI.TrafficLightState.Red, RoadBaseAI.TrafficLightState rightState = RoadBaseAI.TrafficLightState.Red, RoadBaseAI.TrafficLightState pedState = RoadBaseAI.TrafficLightState.Red) { // we intentionally never delete vehicle types (because we may want to retain traffic light states if a segment is upgraded or replaced) ushort nodeId = NodeId; HashSet <ExtVehicleType> setupLights = new HashSet <ExtVehicleType>(); Dictionary <byte, ExtVehicleType> allAllowedTypes = VehicleRestrictionsManager.Instance.GetAllowedVehicleTypesAsDict(segmentId, nodeId); ExtVehicleType allAllowedMask = VehicleRestrictionsManager.Instance.GetAllowedVehicleTypes(segmentId, nodeId); SeparateVehicleTypes = ExtVehicleType.None; #if DEBUGHK Log._Debug($"CustomSegmentLights: housekeeping @ seg. {segmentId}, node {nodeId}, allAllowedTypes={string.Join(", ", allAllowedTypes.Select(x => x.ToString()).ToArray())}"); #endif bool addPedestrianLight = false; uint numLights = 0; VehicleTypeByLaneIndex.Clear(); HashSet <byte> laneIndicesWithoutSeparateLights = new HashSet <byte>(allAllowedTypes.Keys); foreach (KeyValuePair <byte, ExtVehicleType> e in allAllowedTypes) { byte laneIndex = e.Key; ExtVehicleType allowedTypes = e.Value; foreach (ExtVehicleType mask in singleLaneVehicleTypes) { if (setupLights.Contains(mask)) { break; } if ((allowedTypes & mask) != ExtVehicleType.None && (allowedTypes & ~(mask | ExtVehicleType.Emergency)) == ExtVehicleType.None) { #if DEBUGHK Log._Debug($"CustomSegmentLights: housekeeping @ seg. {segmentId}, node {nodeId}: adding {mask} light"); #endif if (!CustomLights.ContainsKey(mask)) { CustomLights.Add(mask, new TrafficLight.CustomSegmentLight(this, mainState, leftState, rightState)); VehicleTypes.AddFirst(mask); } VehicleTypeByLaneIndex[laneIndex] = mask; laneIndicesWithoutSeparateLights.Remove(laneIndex); ++numLights; addPedestrianLight = true; mainSegmentLight = CustomLights[mask]; setupLights.Add(mask); SeparateVehicleTypes |= mask; break; } } } if (allAllowedTypes.Count > numLights) { #if DEBUGHK Log._Debug($"CustomSegmentLights: housekeeping @ seg. {segmentId}, node {nodeId}: adding main vehicle light: {mainVehicleType}"); #endif // traffic lights for cars if (!CustomLights.ContainsKey(mainVehicleType)) { CustomLights.Add(mainVehicleType, new TrafficLight.CustomSegmentLight(this, mainState, leftState, rightState)); VehicleTypes.AddFirst(mainVehicleType); } mainSegmentLight = CustomLights[mainVehicleType]; foreach (byte laneIndex in laneIndicesWithoutSeparateLights) { VehicleTypeByLaneIndex[laneIndex] = ExtVehicleType.None; } addPedestrianLight = allAllowedMask == ExtVehicleType.None || (allAllowedMask & ~ExtVehicleType.RailVehicle) != ExtVehicleType.None; } else { addPedestrianLight = true; } #if DEBUGHK if (addPedestrianLight) { Log._Debug($"CustomSegmentLights: housekeeping @ seg. {segmentId}, node {nodeId}: adding ped. light"); } #endif if (mayDelete) { // delete traffic lights for non-existing configurations HashSet <ExtVehicleType> vehicleTypesToDelete = new HashSet <ExtVehicleType>(); foreach (KeyValuePair <ExtVehicleType, CustomSegmentLight> e in CustomLights) { if (e.Key == mainVehicleType) { continue; } if (!setupLights.Contains(e.Key)) { vehicleTypesToDelete.Add(e.Key); } } foreach (ExtVehicleType vehicleType in vehicleTypesToDelete) { #if DEBUGHK Log._Debug($"Deleting traffic light for {vehicleType} at segment {segmentId}, node {nodeId}"); #endif CustomLights.Remove(vehicleType); VehicleTypes.Remove(vehicleType); } } if (CustomLights.ContainsKey(mainVehicleType) && VehicleTypes.First.Value != mainVehicleType) { VehicleTypes.Remove(mainVehicleType); VehicleTypes.AddFirst(mainVehicleType); } if (addPedestrianLight) { #if DEBUGHK Log._Debug($"CustomSegmentLights: housekeeping @ seg. {segmentId}, node {nodeId}: adding pedestrian light"); #endif if (pedestrianLightState == null) { pedestrianLightState = pedState; } } else { pedestrianLightState = null; } OnChange(calculateAutoPedLight); #if DEBUGHK Log._Debug($"CustomSegmentLights: housekeeping @ seg. {segmentId}, node {nodeId}: Housekeeping complete. VehicleTypeByLaneIndex={string.Join("; ", VehicleTypeByLaneIndex.Select(x => x.Key + "=" + x.Value).ToArray())} CustomLights={string.Join("; ", CustomLights.Select(x => x.Key.ToString()).ToArray())}"); #endif }
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 = CustomTrafficLightsManager.Instance().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); }
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; } CustomTrafficLightsManager customTrafficLightsManager = CustomTrafficLightsManager.Instance(); TrafficPriorityManager prioMan = TrafficPriorityManager.Instance(); 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 (!prioMan.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]; prioMan.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 = customTrafficLightsManager.GetSegmentLights(NodeId, segmentId); if (liveSegLights == null) { Log.Error($"No live segment lights for seg. {segmentId} @ node {NodeId} found!"); customTrafficLightsManager.AddSegmentLights(NodeId, segmentId); liveSegLights = customTrafficLightsManager.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(); } } } } }
public void UpdateLiveLights(bool noTransition) { try { CustomSegmentLightsManager customTrafficLightsManager = CustomSegmentLightsManager.Instance; bool atEndTransition = !noTransition && (IsInEndTransition() || IsEndTransitionDone()); // = yellow bool atStartTransition = !noTransition && !atEndTransition && IsInStartTransition(); // = red + yellow #if DEBUG if (timedNode == null) { Log.Error($"TimedTrafficLightsStep: timedNode is null!"); return; } #endif if (PreviousStepRefIndex >= timedNode.NumSteps()) { PreviousStepRefIndex = -1; } if (NextStepRefIndex >= timedNode.NumSteps()) { NextStepRefIndex = -1; } TimedTrafficLightsStep previousStep = timedNode.Steps[PreviousStepRefIndex >= 0 ? PreviousStepRefIndex : ((timedNode.CurrentStep + timedNode.Steps.Count - 1) % timedNode.Steps.Count)]; TimedTrafficLightsStep nextStep = timedNode.Steps[NextStepRefIndex >= 0 ? NextStepRefIndex : ((timedNode.CurrentStep + 1) % timedNode.Steps.Count)]; #if DEBUG if (previousStep == null) { Log.Error($"TimedTrafficLightsStep: previousStep is null!"); return; } if (nextStep == null) { Log.Error($"TimedTrafficLightsStep: nextStep is null!"); return; } if (previousStep.segmentLights == null) { Log.Error($"TimedTrafficLightsStep: previousStep.segmentLights is null!"); return; } if (nextStep.segmentLights == null) { Log.Error($"TimedTrafficLightsStep: nextStep.segmentLights is null!"); return; } if (segmentLights == null) { Log.Error($"TimedTrafficLightsStep: segmentLights is null!"); return; } #endif #if DEBUG //Log._Debug($"TimedTrafficLightsStep.SetLights({noTransition}) called for NodeId={timedNode.NodeId}. atStartTransition={atStartTransition} atEndTransition={atEndTransition}"); #endif foreach (KeyValuePair <ushort, CustomSegmentLights> e in segmentLights) { var segmentId = e.Key; var curStepSegmentLights = e.Value; #if DEBUG //Log._Debug($"TimedTrafficLightsStep.SetLights({noTransition}) -> segmentId={segmentId} @ NodeId={timedNode.NodeId}"); #endif if (!previousStep.segmentLights.ContainsKey(segmentId)) { #if DEBUG Log._Debug($"TimedTrafficLightsStep: previousStep does not contain lights for segment {segmentId}!"); #endif continue; } if (!nextStep.segmentLights.ContainsKey(segmentId)) { #if DEBUG Log._Debug($"TimedTrafficLightsStep: nextStep does not contain lights for segment {segmentId}!"); #endif continue; } var prevStepSegmentLights = previousStep.segmentLights[segmentId]; var nextStepSegmentLights = nextStep.segmentLights[segmentId]; //segLightState.makeRedOrGreen(); // TODO temporary fix var liveSegmentLights = customTrafficLightsManager.GetSegmentLights(segmentId, curStepSegmentLights.StartNode, false); if (liveSegmentLights == null) { continue; } 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 = liveSegmentLights.AutoPedestrianLightState = pedLightState; //Log.Warning($"Step @ {timedNode.NodeId}: Segment {segmentId}: Ped.: {liveSegmentLights.PedestrianLightState.ToString()} / {liveSegmentLights.AutoPedestrianLightState.ToString()}"); #if DEBUG if (curStepSegmentLights.VehicleTypes == null) { Log.Error($"TimedTrafficLightsStep: curStepSegmentLights.VehicleTypes is null!"); return; } #endif foreach (ExtVehicleType vehicleType in curStepSegmentLights.VehicleTypes) { #if DEBUG //Log._Debug($"TimedTrafficLightsStep.SetLights({noTransition}) -> segmentId={segmentId} @ NodeId={timedNode.NodeId} for vehicle {vehicleType}"); #endif 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!"); return; } if (prevStepSegmentLight == null) { Log.Error($"TimedTrafficLightsStep: prevStepSegmentLight is null!"); return; } if (nextStepSegmentLight == null) { Log.Error($"TimedTrafficLightsStep: nextStepSegmentLight is null!"); return; } #endif liveSegmentLight.currentMode = curStepSegmentLight.CurrentMode; /*curStepSegmentLight.EnsureModeLights(); * prevStepSegmentLight.EnsureModeLights(); * nextStepSegmentLight.EnsureModeLights();*/ RoadBaseAI.TrafficLightState mainLight = calcLightState(prevStepSegmentLight.LightMain, curStepSegmentLight.LightMain, nextStepSegmentLight.LightMain, atStartTransition, atEndTransition); RoadBaseAI.TrafficLightState leftLight = calcLightState(prevStepSegmentLight.LightLeft, curStepSegmentLight.LightLeft, nextStepSegmentLight.LightLeft, atStartTransition, atEndTransition); RoadBaseAI.TrafficLightState rightLight = calcLightState(prevStepSegmentLight.LightRight, curStepSegmentLight.LightRight, nextStepSegmentLight.LightRight, atStartTransition, atEndTransition); liveSegmentLight.SetStates(mainLight, leftLight, rightLight, false); #if DEBUGTTL Log._Debug($"TimedTrafficLightsStep.SetLights({noTransition}) -> *SETTING* LightLeft={liveSegmentLight.LightLeft} LightMain={liveSegmentLight.LightMain} LightRight={liveSegmentLight.LightRight} for segmentId={segmentId} @ NodeId={timedNode.NodeId} for vehicle {vehicleType}"); #endif //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 for node {timedNode.NodeId}: {e.ToString()}"); //invalid = true; } }
internal void ChangeLightMode(ushort segmentId, ExtVehicleType vehicleType, CustomSegmentLight.Mode mode) { CustomSegmentLight light = segmentLights[segmentId].GetCustomLight(vehicleType); if (light != null) light.CurrentMode = mode; }
private bool RightArrowLightMode(int segmentId, Vector3 screenPos, float lightWidth, float pedestrianWidth, float zoom, float lightHeight, CustomSegmentLight segmentDict, bool hoveredSegment) { SetAlpha(segmentId, 5); var myRect5 = new Rect(screenPos.x - lightWidth / 2 - lightWidth - pedestrianWidth + 5f * zoom, screenPos.y - lightHeight / 2, lightWidth, lightHeight); switch (segmentDict.LightRight) { case RoadBaseAI.TrafficLightState.Green: GUI.DrawTexture(myRect5, TrafficLightToolTextureResources.GreenLightRightTexture2D); break; case RoadBaseAI.TrafficLightState.Red: GUI.DrawTexture(myRect5, TrafficLightToolTextureResources.RedLightRightTexture2D); break; } if (!myRect5.Contains(Event.current.mousePosition)) return hoveredSegment; _hoveredButton[0] = segmentId; _hoveredButton[1] = 5; if (!Input.GetMouseButtonDown(0) || mouseClickProcessed) return true; mouseClickProcessed = true; segmentDict.ChangeLightRight(); return true; }
private bool GetHoveredSegment(Rect myRect1, int segmentId, bool hoveredSegment, CustomSegmentLight segmentDict) { if (!myRect1.Contains(Event.current.mousePosition)) return hoveredSegment; //Log.Message("mouse in myRect1"); _hoveredButton[0] = segmentId; _hoveredButton[1] = -1; if (!Input.GetMouseButtonDown(0) || mouseClickProcessed) return true; mouseClickProcessed = true; segmentDict.ChangeMode(); return true; }
internal void housekeeping(bool mayDelete, RoadBaseAI.TrafficLightState mainState = RoadBaseAI.TrafficLightState.Red, RoadBaseAI.TrafficLightState leftState = RoadBaseAI.TrafficLightState.Red, RoadBaseAI.TrafficLightState rightState = RoadBaseAI.TrafficLightState.Red, RoadBaseAI.TrafficLightState pedState = RoadBaseAI.TrafficLightState.Red) { // we intentionally never delete vehicle types (because we may want to retain traffic light states if a segment is upgraded or replaced) HashSet<ExtVehicleType> setupLights = new HashSet<ExtVehicleType>(); HashSet<ExtVehicleType> allAllowedTypes = VehicleRestrictionsManager.GetAllowedVehicleTypesAsSet(segmentId, nodeId); ExtVehicleType allAllowedMask = VehicleRestrictionsManager.GetAllowedVehicleTypes(segmentId, nodeId); SeparateVehicleTypes = ExtVehicleType.None; #if DEBUGHK Log._Debug($"CustomSegmentLights: housekeeping @ seg. {segmentId}, node {nodeId}, allAllowedTypes={string.Join(", ", allAllowedTypes.Select(x => x.ToString()).ToArray())}"); #endif bool addPedestrianLight = false; uint numLights = 0; foreach (ExtVehicleType allowedTypes in allAllowedTypes) { foreach (ExtVehicleType mask in singleLaneVehicleTypes) { if (setupLights.Contains(mask)) continue; if ((allowedTypes & mask) != ExtVehicleType.None && (allowedTypes & ~(mask | ExtVehicleType.Emergency)) == ExtVehicleType.None) { #if DEBUGHK Log._Debug($"CustomSegmentLights: housekeeping @ seg. {segmentId}, node {nodeId}: adding {mask} light"); #endif if (!CustomLights.ContainsKey(mask)) { CustomLights.Add(mask, new TrafficLight.CustomSegmentLight(this, nodeId, segmentId, mainState, leftState, rightState)); VehicleTypes.AddFirst(mask); } ++numLights; addPedestrianLight = true; autoPedestrianVehicleType = mask; mainSegmentLight = CustomLights[mask]; setupLights.Add(mask); SeparateVehicleTypes |= mask; break; } } } if (allAllowedTypes.Count > numLights) { #if DEBUGHK Log._Debug($"CustomSegmentLights: housekeeping @ seg. {segmentId}, node {nodeId}: adding main vehicle light: {mainVehicleType}"); #endif // traffic lights for cars if (!CustomLights.ContainsKey(mainVehicleType)) { CustomLights.Add(mainVehicleType, new TrafficLight.CustomSegmentLight(this, nodeId, segmentId, mainState, leftState, rightState)); VehicleTypes.AddFirst(mainVehicleType); } autoPedestrianVehicleType = mainVehicleType; mainSegmentLight = CustomLights[mainVehicleType]; addPedestrianLight = allAllowedMask == ExtVehicleType.None || (allAllowedMask & ~ExtVehicleType.RailVehicle) != ExtVehicleType.None; } else { addPedestrianLight = true; } #if DEBUGHK if (addPedestrianLight) { Log._Debug($"CustomSegmentLights: housekeeping @ seg. {segmentId}, node {nodeId}: adding ped. light"); } #endif if (mayDelete) { // delete traffic lights for non-existing configurations HashSet<ExtVehicleType> vehicleTypesToDelete = new HashSet<ExtVehicleType>(); foreach (KeyValuePair<ExtVehicleType, CustomSegmentLight> e in CustomLights) { if (e.Key == mainVehicleType) continue; if (!setupLights.Contains(e.Key)) vehicleTypesToDelete.Add(e.Key); } foreach (ExtVehicleType vehicleType in vehicleTypesToDelete) { #if DEBUGHK Log._Debug($"Deleting traffic light for {vehicleType} at segment {segmentId}, node {nodeId}"); #endif CustomLights.Remove(vehicleType); VehicleTypes.Remove(vehicleType); } } if (CustomLights.ContainsKey(mainVehicleType) && VehicleTypes.First.Value != mainVehicleType) { VehicleTypes.Remove(mainVehicleType); VehicleTypes.AddFirst(mainVehicleType); } if (addPedestrianLight) { #if DEBUGHK Log._Debug($"CustomSegmentLights: housekeeping @ seg. {segmentId}, node {nodeId}: adding pedestrian light"); #endif if (pedestrianLightState == null) pedestrianLightState = pedState; } else { pedestrianLightState = null; } }
/// <summary> /// Calculates the current metrics for flowing and waiting vehicles /// </summary> /// <param name="wait"></param> /// <param name="flow"></param> /// <returns>true if the values could be calculated, false otherwise</returns> public bool calcWaitFlow(out float wait, out float flow) { #if TRACE Singleton <CodeProfiler> .instance.Start("TimedTrafficLightsStep.calcWaitFlow"); #endif #if DEBUGMETRIC bool debug = timedNode.NodeId == 3201; #else bool debug = false; #endif #if DEBUGMETRIC if (debug) { Log.Warning($"TimedTrafficLightsStep.calcWaitFlow: ***START*** @ node {timedNode.NodeId}"); } #endif uint numFlows = 0; uint numWaits = 0; uint curMeanFlow = 0; uint curMeanWait = 0; // we are the master node. calculate traffic data foreach (ushort timedNodeId in timedNode.NodeGroup) { TrafficLightSimulation sim = TrafficLightSimulation.GetNodeSimulation(timedNodeId); if (sim == null || !sim.IsTimedLight()) { continue; } TimedTrafficLights slaveTimedNode = sim.TimedLight; if (slaveTimedNode.NumSteps() <= timedNode.CurrentStep) { for (int i = 0; i < slaveTimedNode.NumSteps(); ++i) { slaveTimedNode.GetStep(i).invalid = true; } continue; } TimedTrafficLightsStep slaveStep = slaveTimedNode.Steps[timedNode.CurrentStep]; //List<int> segmentIdsToDelete = new List<int>(); // minimum time reached. check traffic! foreach (KeyValuePair <ushort, CustomSegmentLights> e in slaveStep.segmentLights) { var fromSegmentId = e.Key; var segLights = e.Value; // one of the traffic lights at this segment is green: count minimum traffic flowing through SegmentEnd fromSeg = TrafficPriority.GetPrioritySegment(timedNodeId, fromSegmentId); if (fromSeg == null) { #if DEBUGMETRIC if (debug) { Log.Warning($"TimedTrafficLightsStep.calcWaitFlow: No priority segment @ seg. {fromSegmentId} found!"); } #endif //Log.Warning("stepDone(): prioSeg is null"); //segmentIdsToDelete.Add(fromSegmentId); continue; // skip invalid segment } //bool startPhase = getCurrentFrame() <= startFrame + minTime + 2; // during start phase all vehicles on "green" segments are counted as flowing ExtVehicleType validVehicleTypes = VehicleRestrictionsManager.GetAllowedVehicleTypes(fromSegmentId, timedNode.NodeId); foreach (KeyValuePair <byte, ExtVehicleType> e2 in segLights.VehicleTypeByLaneIndex) { byte laneIndex = e2.Key; ExtVehicleType vehicleType = e2.Value; if (vehicleType != ExtVehicleType.None && (validVehicleTypes & vehicleType) == ExtVehicleType.None) { continue; } CustomSegmentLight segLight = segLights.GetCustomLight(laneIndex); if (segLight == null) { Log.Warning($"Timed traffic light step: Failed to get custom light for vehicleType {vehicleType} @ seg. {fromSegmentId}, node {timedNode.NodeId}!"); continue; } #if DEBUGMETRIC if (debug) { Log._Debug($"TimedTrafficLightsStep.calcWaitFlow: Checking lane {laneIndex} @ seg. {fromSegmentId}. Vehicle types: {vehicleType}"); } #endif Dictionary <ushort, uint> carsFlowingToSegmentMetric = null; Dictionary <ushort, uint> allCarsToSegmentMetric = null; try { carsFlowingToSegmentMetric = fromSeg.GetVehicleMetricGoingToSegment(false, laneIndex, debug); } catch (Exception ex) { Log.Warning("calcWaitFlow (1): " + ex.ToString()); } try { allCarsToSegmentMetric = fromSeg.GetVehicleMetricGoingToSegment(true, laneIndex, debug); } catch (Exception ex) { Log.Warning("calcWaitFlow (2): " + ex.ToString()); } if (carsFlowingToSegmentMetric == null) { continue; } // build directions from toSegment to fromSegment Dictionary <ushort, Direction> directions = new Dictionary <ushort, Direction>(); foreach (KeyValuePair <ushort, uint> f in allCarsToSegmentMetric) { var toSegmentId = f.Key; SegmentGeometry geometry = SegmentGeometry.Get(fromSegmentId); Direction dir = geometry.GetDirection(toSegmentId, timedNodeId == geometry.StartNodeId()); directions[toSegmentId] = dir; #if DEBUGMETRIC if (debug) { Log._Debug($"TimedTrafficLightsStep.calcWaitFlow: Calculated direction for seg. {fromSegmentId} -> seg. {toSegmentId}: {dir}"); } #endif } // calculate waiting/flowing traffic foreach (KeyValuePair <ushort, uint> f in allCarsToSegmentMetric) { ushort toSegmentId = f.Key; uint totalNormCarLength = f.Value; uint totalFlowingNormCarLength = carsFlowingToSegmentMetric[f.Key]; #if DEBUGMETRIC if (debug) { Log._Debug($"TimedTrafficLightsStep.calcWaitFlow: Total norm. car length of vehicles on lane {laneIndex} going to seg. {toSegmentId}: {totalNormCarLength}"); } #endif bool addToFlow = false; switch (directions[toSegmentId]) { case Direction.Turn: addToFlow = TrafficPriority.IsLeftHandDrive() ? segLight.isRightGreen() : segLight.isLeftGreen(); break; case Direction.Left: addToFlow = segLight.isLeftGreen(); break; case Direction.Right: addToFlow = segLight.isRightGreen(); break; case Direction.Forward: default: addToFlow = segLight.isForwardGreen(); break; } if (addToFlow) { ++numFlows; curMeanFlow += totalFlowingNormCarLength; } else { ++numWaits; curMeanWait += totalNormCarLength; } #if DEBUGMETRIC if (debug) { Log._Debug($"TimedTrafficLightsStep.calcWaitFlow: Vehicles on lane {laneIndex} on seg. {fromSegmentId} going to seg. {toSegmentId} flowing? {addToFlow} curMeanFlow={curMeanFlow}, curMeanWait={curMeanWait}"); } #endif } } } // delete invalid segments from step /*foreach (int segmentId in segmentIdsToDelete) { * slaveStep.segmentLightStates.Remove(segmentId); * }*/ if (slaveStep.segmentLights.Count <= 0) { invalid = true; flow = 0f; wait = 0f; #if TRACE Singleton <CodeProfiler> .instance.Stop("TimedTrafficLightsStep.calcWaitFlow"); #endif return(false); } } #if DEBUGMETRIC if (debug) { Log._Debug($"TimedTrafficLightsStep.calcWaitFlow: ### Calculation completed. numFlows={numFlows}, numWaits={numWaits}, curMeanFlow={curMeanFlow}, curMeanWait={curMeanWait}"); } wait = curMeanWait; flow = curMeanFlow; #else if (numFlows > 0) { curMeanFlow /= numFlows; } if (numWaits > 0) { curMeanWait /= numWaits; } float fCurMeanFlow = curMeanFlow; fCurMeanFlow /= waitFlowBalance; // a value smaller than 1 rewards steady traffic currents wait = (float)curMeanWait; flow = fCurMeanFlow; #endif #if TRACE Singleton <CodeProfiler> .instance.Stop("TimedTrafficLightsStep.calcWaitFlow"); #endif return(true); }
internal void ChangeLightMode(ushort segmentId, ExtVehicleType vehicleType, CustomSegmentLight.Mode mode) { foreach (TimedTrafficLightsStep step in Steps) { step.ChangeLightMode(segmentId, vehicleType, mode); } }
/// <summary> /// Calculates the current metrics for flowing and waiting vehicles /// </summary> /// <param name="wait"></param> /// <param name="flow"></param> /// <returns>true if the values could be calculated, false otherwise</returns> public bool calcWaitFlow(bool onlyMoving, int stepRefIndex, out float wait, out float flow) { uint numFlows = 0; uint numWaits = 0; uint curMeanFlow = 0; uint curMeanWait = 0; // TODO checking agains getCurrentFrame() is only valid if this is the current step if (onlyMoving && getCurrentFrame() <= startFrame + minTime + 1) // during start phase all vehicles on "green" segments are counted as flowing { onlyMoving = false; } TrafficLightSimulationManager tlsMan = TrafficLightSimulationManager.Instance; TrafficPriorityManager prioMan = TrafficPriorityManager.Instance; foreach (ushort timedNodeId in timedNode.NodeGroup) { TrafficLightSimulation sim = tlsMan.GetNodeSimulation(timedNodeId); if (sim == null || !sim.IsTimedLight()) { continue; } TimedTrafficLights slaveTimedNode = sim.TimedLight; TimedTrafficLightsStep slaveStep = slaveTimedNode.Steps[stepRefIndex]; //List<int> segmentIdsToDelete = new List<int>(); // minimum time reached. check traffic! foreach (KeyValuePair <ushort, CustomSegmentLights> e in slaveStep.segmentLights) { var sourceSegmentId = e.Key; var segLights = e.Value; #if DEBUGMETRIC bool debug = sourceSegmentId == 20857 && GlobalConfig.Instance.DebugSwitches[1]; #elif DEBUG bool debug = GlobalConfig.Instance.DebugSwitches[7] && GlobalConfig.Instance.TTLDebugNodeId == timedNodeId; #else bool debug = false; #endif Dictionary <ushort, ArrowDirection> directions = null; if (slaveStep.timedNode.Directions.ContainsKey(sourceSegmentId)) { directions = slaveStep.timedNode.Directions[sourceSegmentId]; } else { #if DEBUG if (debug) { Log._Debug($"calcWaitFlow: No arrow directions defined for segment {sourceSegmentId} @ {timedNodeId}"); } #endif continue; } // one of the traffic lights at this segment is green: count minimum traffic flowing through SegmentEnd sourceSegmentEnd = prioMan.GetPrioritySegment(timedNodeId, sourceSegmentId); if (sourceSegmentEnd == null) { Log.Warning($"TimedTrafficLightsStep.calcWaitFlow: No priority segment @ seg. {sourceSegmentId} found!"); continue; // skip invalid segment } ExtVehicleType validVehicleTypes = VehicleRestrictionsManager.Instance.GetAllowedVehicleTypes(sourceSegmentId, timedNode.NodeId); foreach (KeyValuePair <byte, ExtVehicleType> e2 in segLights.VehicleTypeByLaneIndex) { byte laneIndex = e2.Key; ExtVehicleType vehicleType = e2.Value; if (vehicleType != ExtVehicleType.None && (validVehicleTypes & vehicleType) == ExtVehicleType.None) { continue; } CustomSegmentLight segLight = segLights.GetCustomLight(laneIndex); if (segLight == null) { Log.Warning($"Timed traffic light step: Failed to get custom light for vehicleType {vehicleType} @ seg. {sourceSegmentId}, node {timedNode.NodeId}!"); continue; } #if DEBUG if (debug) { Log._Debug($"TimedTrafficLightsStep.calcWaitFlow: Checking lane {laneIndex} @ seg. {sourceSegmentId}. Vehicle types: {vehicleType}"); } #endif Dictionary <ushort, uint> carsFlowingToSegmentMetric = null; Dictionary <ushort, uint> allCarsToSegmentMetric = null; bool evalFlowingVehicles = segLight.IsAnyGreen(); // flowing vehicle need only to be evaluated if a light is green if (evalFlowingVehicles && onlyMoving) { carsFlowingToSegmentMetric = sourceSegmentEnd.GetVehicleMetricGoingToSegment(false, laneIndex, debug); } allCarsToSegmentMetric = sourceSegmentEnd.GetVehicleMetricGoingToSegment(true, laneIndex, debug); // calculate waiting/flowing traffic foreach (KeyValuePair <ushort, uint> f in allCarsToSegmentMetric) { ushort targetSegmentId = f.Key; uint totalNumCars = f.Value; if (!directions.ContainsKey(targetSegmentId)) { Log._Debug($"TimedTrafficLightsStep.calcWaitFlow: Direction undefined for target segment {targetSegmentId} @ {timedNodeId}"); continue; } if (evalFlowingVehicles) { uint totalNumFlowingCars = onlyMoving ? carsFlowingToSegmentMetric[f.Key] : totalNumCars; #if DEBUG if (debug) { Log._Debug($"TimedTrafficLightsStep.calcWaitFlow: Total num of flowing cars on seg. {sourceSegmentId}, lane {laneIndex} going to seg. {targetSegmentId}: {totalNumFlowingCars}"); } #endif bool addToFlow = false; switch (directions[targetSegmentId]) { case ArrowDirection.Turn: addToFlow = TrafficPriorityManager.IsLeftHandDrive() ? segLight.IsRightGreen() : segLight.IsLeftGreen(); break; case ArrowDirection.Left: addToFlow = segLight.IsLeftGreen(); break; case ArrowDirection.Right: addToFlow = segLight.IsRightGreen(); break; case ArrowDirection.Forward: default: addToFlow = segLight.IsMainGreen(); break; } if (addToFlow) { curMeanFlow += totalNumFlowingCars; ++numFlows; } else { curMeanWait += totalNumCars; ++numWaits; } } else { curMeanWait += totalNumCars; ++numWaits; } #if DEBUG if (debug) { Log._Debug($"TimedTrafficLightsStep.calcWaitFlow: Vehicles on lane {laneIndex} on seg. {sourceSegmentId} going to seg. {targetSegmentId} curMeanFlow={curMeanFlow}, curMeanWait={curMeanWait}, numFlows={numFlows}, numWaits={numWaits}"); } #endif } } } } /*if (numFlows > 0) * curMeanFlow /= numFlows; * if (numWaits > 0) * curMeanWait /= numWaits;*/ float fCurMeanFlow = numFlows > 0 ? (float)curMeanFlow / (float)numFlows : 0; float fCurMeanWait = numWaits > 0 ? (float)curMeanWait / (float)numWaits : 0; fCurMeanFlow /= waitFlowBalance; // a value smaller than 1 rewards steady traffic currents wait = (float)fCurMeanWait; flow = fCurMeanFlow; return(true); }
private bool LeftForwardRManualSegmentLightMode(bool hasLeftSegment, int segmentId, Vector3 screenPos, float lightWidth, float pedestrianWidth, float zoom, float lightHeight, CustomSegmentLight segmentDict, bool hoveredSegment, bool hasForwardSegment, bool hasRightSegment) { if (hasLeftSegment) { // left arrow light SetAlpha(segmentId, 3); var myRect4 = new Rect(screenPos.x - lightWidth / 2 - lightWidth * 2 - pedestrianWidth + 5f * zoom, screenPos.y - lightHeight / 2, lightWidth, lightHeight); switch (segmentDict.LightLeft) { case RoadBaseAI.TrafficLightState.Green: GUI.DrawTexture(myRect4, TrafficLightToolTextureResources.GreenLightLeftTexture2D); break; case RoadBaseAI.TrafficLightState.Red: GUI.DrawTexture(myRect4, TrafficLightToolTextureResources.RedLightLeftTexture2D); break; } if (myRect4.Contains(Event.current.mousePosition)) { _hoveredButton[0] = segmentId; _hoveredButton[1] = 3; hoveredSegment = true; if (checkClicked()) { segmentDict.ChangeLightLeft(); } } } // forward-right arrow light SetAlpha(segmentId, 4); var myRect5 = new Rect(screenPos.x - lightWidth / 2 - lightWidth - pedestrianWidth + 5f * zoom, screenPos.y - lightHeight / 2, lightWidth, lightHeight); if (hasForwardSegment && hasRightSegment) { switch (segmentDict.LightMain) { case RoadBaseAI.TrafficLightState.Green: GUI.DrawTexture(myRect5, TrafficLightToolTextureResources.GreenLightForwardRightTexture2D); break; case RoadBaseAI.TrafficLightState.Red: GUI.DrawTexture(myRect5, TrafficLightToolTextureResources.RedLightForwardRightTexture2D); break; } } else if (!hasRightSegment) { switch (segmentDict.LightMain) { case RoadBaseAI.TrafficLightState.Green: GUI.DrawTexture(myRect5, TrafficLightToolTextureResources.GreenLightStraightTexture2D); break; case RoadBaseAI.TrafficLightState.Red: GUI.DrawTexture(myRect5, TrafficLightToolTextureResources.RedLightStraightTexture2D); break; } } else { switch (segmentDict.LightMain) { case RoadBaseAI.TrafficLightState.Green: GUI.DrawTexture(myRect5, TrafficLightToolTextureResources.GreenLightRightTexture2D); break; case RoadBaseAI.TrafficLightState.Red: GUI.DrawTexture(myRect5, TrafficLightToolTextureResources.RedLightRightTexture2D); break; } } if (!myRect5.Contains(Event.current.mousePosition)) return hoveredSegment; _hoveredButton[0] = segmentId; _hoveredButton[1] = 4; if (!Input.GetMouseButtonDown(0) || mouseClickProcessed) return true; mouseClickProcessed = true; segmentDict.ChangeLightMain(); return true; }
/*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(); } } } } }