private void ParseEvents(OPLParser oplParser, IEnumerable<SignalEvent> signalEvents, BlockingBackConfig config) { int vehicleCount = 0; int oldCount = 0; uint lastVehicleEntering = 0; uint lastVehicleExit = 0; uint lastBlockedBegin = 0; foreach (string signalName in config.BlockedSignals) { _blockingBackBlockedRanges.Add(signalName, new TimePeriodCollection()); } foreach (SignalEvent signalEvent in signalEvents) { oldCount = vehicleCount; uint curTime = signalEvent.TimeAsUnixTime; string eventElementName; if (signalEvent.EventType == SignalEvent.Type.TransitVehicleDetectedInLogic) { eventElementName = signalEvent.ElementName + " " + signalEvent.ExtraInfo; } else { eventElementName = signalEvent.ElementName; } if (config.StrikeIn.Contains(eventElementName)) { // A vehicle has entered the monitored section. vehicleCount += 1; lastVehicleEntering = curTime; } else if (config.StrikeOut.Contains(eventElementName)) { // A vehicle has left the monitored section. if (vehicleCount > 0) { vehicleCount -= 1; } lastVehicleExit = curTime; } if (config.TimeOut != 0 && lastVehicleExit > 0 && curTime - lastVehicleExit > config.TimeOut) { if (vehicleCount > 0) { vehicleCount -= 1; lastVehicleExit = curTime; } } // Check whether we've crossed the threshold for blocking/unblocking the signal groups. if (oldCount < config.MaxVehicles && vehicleCount >= config.MaxVehicles) { lastBlockedBegin = curTime; foreach (string signalName in config.BlockedSignals) { _blockingBackEvents.Add(new SignalEvent(SignalEvent.Type.SignalGroupBlocked, curTime, oplParser.GetSignalElementUidByName(signalName), signalName, signalEvent.ElementName)); } } else if (oldCount >= config.MaxVehicles && vehicleCount < config.MaxVehicles) { foreach (string signalName in config.BlockedSignals) { _blockingBackBlockedRanges[signalName].Add( new TimeRange(Utils.UnixTimeToDateTime(lastBlockedBegin), Utils.UnixTimeToDateTime(curTime), true)); _blockingBackEvents.Add(new SignalEvent(SignalEvent.Type.SignalGroupUnblocked, curTime, oplParser.GetSignalElementUidByName(signalName), signalName, signalEvent.ElementName)); } } } }
private void AddIntergreenEvents(OPLParser oplParser, IEnumerable<SignalEvent> signalEvents) { foreach (SignalEvent signalEvent in signalEvents) { var curName = signalEvent.ElementName; // If a signal group changes to red, all conflicting signal groups become unblocked // after the intergreen time has elapsed. // Note: Strictly speaking the termination of the green phase is the interesting point, // however we currently assume the usual case of a transit vehicle actively replacing // it's own signal to red, in which case there is no yellow phase. if (signalEvent.EventType == SignalEvent.Type.SignalGroupChangeToRed) { foreach (string conflictingElement in _intergreenTimes[curName].Keys) { _intergreenEvents.Add(new SignalEvent(SignalEvent.Type.SignalGroupUnblocked, (uint)(signalEvent.TimeAsUnixTime + _intergreenTimes[curName][conflictingElement]), oplParser.GetSignalElementUidByName(conflictingElement), conflictingElement, curName)); } } // If a signal group changes to green, we need to look back in time and determine the // latest point at which a conflicting signal group had to switch away from green. else if (signalEvent.EventType == SignalEvent.Type.SignalGroupChangeToGreen) { foreach (string conflictingElement in _intergreenTimes.Keys) { if (_intergreenTimes[conflictingElement].ContainsKey(curName)) { _intergreenEvents.Add(new SignalEvent(SignalEvent.Type.SignalGroupBlocked, (uint)(signalEvent.TimeAsUnixTime - _intergreenTimes[conflictingElement][curName]), oplParser.GetSignalElementUidByName(conflictingElement), conflictingElement, curName)); } } } } }