public void Start() { /*if (!housekeeping()) * return;*/ for (int s = 0; s < 8; ++s) { ushort segmentId = Singleton <NetManager> .instance.m_nodes.m_buffer[NodeId].GetSegment(s); if (segmentId == 0) { continue; } bool needsAlwaysGreenPedestrian = true; foreach (TimedTrafficLightsStep step in Steps) { if (!step.segmentLights.ContainsKey(segmentId)) { continue; } if (step.segmentLights[segmentId].PedestrianLightState == RoadBaseAI.TrafficLightState.Green) { needsAlwaysGreenPedestrian = false; break; } } CustomTrafficLights.GetOrLiveSegmentLights(NodeId, segmentId).InvalidPedestrianLight = needsAlwaysGreenPedestrian; } CurrentStep = 0; Steps[0].Start(); Steps[0].SetLights(); started = true; }
/// <summary> /// Adds a new segment to this step. After adding all steps the method `rebuildSegmentIds` must be called. /// </summary> /// <param name="segmentId"></param> internal void addSegment(ushort segmentId, bool makeRed) { segmentLights.Add(segmentId, (CustomSegmentLights)CustomTrafficLights.GetOrLiveSegmentLights(timedNode.NodeId, segmentId).Clone()); if (makeRed) { segmentLights[segmentId].MakeRed(); } else { segmentLights[segmentId].MakeRedOrGreen(); } }
/// <summary> /// Updates timed segment lights according to "real-world" traffic light states /// </summary> public void UpdateLights() { foreach (KeyValuePair <ushort, CustomSegmentLights> e in segmentLights) { var segmentId = e.Key; var segLights = e.Value; //if (segment == 0) continue; var liveSegLights = CustomTrafficLights.GetSegmentLights(timedNode.NodeId, segmentId); if (liveSegLights == null) { continue; } segLights.SetLights(liveSegLights); } }
/// <summary> /// Updates timed segment lights according to "real-world" traffic light states /// </summary> public void UpdateLights() { #if TRACE Singleton <CodeProfiler> .instance.Start("TimedTrafficLightsStep.UpdateLights"); #endif foreach (KeyValuePair <ushort, CustomSegmentLights> e in segmentLights) { var segmentId = e.Key; var segLights = e.Value; //if (segment == 0) continue; var liveSegLights = CustomTrafficLights.GetSegmentLights(timedNode.NodeId, segmentId); if (liveSegLights == null) { continue; } segLights.SetLights(liveSegLights); } #if TRACE Singleton <CodeProfiler> .instance.Stop("TimedTrafficLightsStep.UpdateLights"); #endif }
public TimedTrafficLights(ushort nodeId, IEnumerable <ushort> nodeGroup) { this.NodeId = nodeId; NodeGroup = new List <ushort>(nodeGroup); masterNodeId = NodeGroup[0]; // setup priority segments & live traffic lights foreach (ushort slaveNodeId in nodeGroup) { for (int s = 0; s < 8; ++s) { ushort segmentId = Singleton <NetManager> .instance.m_nodes.m_buffer[slaveNodeId].GetSegment(s); if (segmentId <= 0) { continue; } CustomRoadAI.GetSegmentGeometry(segmentId).Recalculate(true, true); TrafficPriority.AddPrioritySegment(slaveNodeId, segmentId, SegmentEnd.PriorityType.None); CustomTrafficLights.AddLiveSegmentLights(slaveNodeId, segmentId); } } started = false; }
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 }
/*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(); } } } } }
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 = CustomTrafficLights.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 bool housekeeping(bool housekeepCustomLights) { bool mayStart = true; List <ushort> nodeIdsToDelete = new List <ushort>(); int i = 0; foreach (ushort otherNodeId in NodeGroup) { if ((Singleton <NetManager> .instance.m_nodes.m_buffer[otherNodeId].m_flags & NetNode.Flags.Created) == NetNode.Flags.None) { Log.Warning($"Timed housekeeping: Remove node {otherNodeId}"); nodeIdsToDelete.Add(otherNodeId); if (otherNodeId == NodeId) { Log.Warning($"Timed housekeeping: Other is this. mayStart = false"); mayStart = false; } } ++i; } foreach (ushort nodeIdToDelete in nodeIdsToDelete) { NodeGroup.Remove(nodeIdToDelete); TrafficLightSimulation.RemoveNodeFromSimulation(nodeIdToDelete, false); } // check that live lights exist (TODO refactor?) foreach (ushort timedNodeId in NodeGroup) { for (int s = 0; s < 8; s++) { var segmentId = Singleton <NetManager> .instance.m_nodes.m_buffer[timedNodeId].GetSegment(s); if (segmentId == 0) { continue; } CustomTrafficLights.AddLiveSegmentLights(timedNodeId, segmentId); } } if (NodeGroup.Count <= 0) { Log.Warning($"Timed housekeeping: No lights left. mayStart = false"); mayStart = false; return(mayStart); } //Log.Warning($"Timed housekeeping: Setting master node to {NodeGroup[0]}"); masterNodeId = NodeGroup[0]; if (housekeepCustomLights) { foreach (TimedTrafficLightsStep step in Steps) { foreach (KeyValuePair <ushort, CustomSegmentLights> e in step.segmentLights) { e.Value.housekeeping(true); } } } return(mayStart); }
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; } 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 (!TrafficPriority.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]; 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) { 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 = CustomTrafficLights.GetSegmentLights(NodeId, segmentId); if (liveSegLights == null) { Log.Error($"No live segment lights for seg. {segmentId} @ node {NodeId} found!"); CustomTrafficLights.AddSegmentLights(NodeId, segmentId); liveSegLights = CustomTrafficLights.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(); } } } } }